我有一个现有项目,其中包含一个使用语义变量的 scss 文件:
$background-color: white;
body {
background-color: $background-color;
}
Run Code Online (Sandbox Code Playgroud)
当我向正文添加主题类时,我想将背景更改为黑色:
<body class="theme-dark">...</body>
Run Code Online (Sandbox Code Playgroud)
如果我删除课程(或切换到主题灯),则返回白色。
我还没有找到任何轻量级的方法来在 scss 中执行此操作(为每个主题参数化一个类似乎是一种非常难以维护的方法)。
我找到了一个混合 scss/css-自定义属性解决方案:
原来的:
.theme-light {
--background-color: white;
}
Run Code Online (Sandbox Code Playgroud)
更新(基于阿马尔的回答):
:root {
--background-color: white;
}
.theme-dark {
--background-color: black;
}
$background-color: var(--background-color);
body {
background-color: $background-color;
}
Run Code Online (Sandbox Code Playgroud)
将 scss 变量定义为具有 css 变量扩展作为值,即(从上面):
$background-color: var(--background-color);
Run Code Online (Sandbox Code Playgroud)
生成以下 css:
:root { --background-color: white; }
.theme-dark { --background-color: black; }
body { background-color: var(--background-color); }
Run Code Online (Sandbox Code Playgroud)
这似乎就是我们想要的......?
我喜欢它,因为它只需要更改$background-color(不是非常大的 scss 文件中的每个用法)的定义,但我不确定这是否是一个合理的解决方案?我对 scss 还很陌生,所以也许我错过了一些功能..?
Ama*_*yla 13
使用 SCSS 可以做到这一点,但您必须向所有想要设置主题的元素添加样式。这是因为 SCSS 是在构建时编译的,您无法使用类切换变量。一个例子是:
$background-color-white: white;
$background-color-black: black;
body {
background-color: $background-color-white;
}
.something-else {
background-color: $background-color-white;
}
// Dark theme
body.theme-dark {
background-color: $background-color-black;
.something-else {
background-color: $background-color-black;
}
}
Run Code Online (Sandbox Code Playgroud)
目前最好的方法是使用 CSS 变量。您可以像这样定义默认变量:
:root {
--background-color: white;
--text-color: black;
}
.theme-dark {
--background-color: black;
--text-color: white;
}
Run Code Online (Sandbox Code Playgroud)
然后,您可以在元素中使用这些变量,如下所示:
body {
background-color: var(--background-color);
color: var(--text-color);
}
Run Code Online (Sandbox Code Playgroud)
如果body元素具有theme-dark类,它将使用为该类定义的变量。否则,它将使用默认的根变量。
我会推荐一种类似于这篇 Medium 文章中提到的方法。通过这种方法,您可以指定哪些类需要主题化,而无需特别提及主题名称,因此可以一次应用多个主题。
首先,您设置一个包含主题的 SASS 地图。键可以是任何对您有意义的键,只需确保每个主题对同一事物使用相同的名称即可。
$themes: (
light: (
backgroundColor: #fff,
textColor: #408bbd,
buttonTextColor: #408bbd,
buttonTextTransform: none,
buttonTextHoverColor: #61b0e7,
buttonColor: #fff,
buttonBorder: 2px solid #fff,
),
dark: (
backgroundColor: #222,
textColor: #ddd,
buttonTextColor: #aaa,
buttonTextTransform: uppercase,
buttonTextHoverColor: #ddd,
buttonColor: #333,
buttonBorder: 1px solid #aaa,
),
);
Run Code Online (Sandbox Code Playgroud)
然后使用mixin和function配对添加主题支持。
body {
background-color: white;
@include themify {
background-color: theme( 'backgroundColor' );
}
}
.button {
background-color: lightgray;
color: black;
@include themify {
background-color: theme( 'buttonBackgrounColor' );
color: theme( 'buttonTextColor' );
}
&:focus,
&:hover {
background-color: gray;
@include themify {
background-color: theme( 'buttonBackgroundHoverColor' );
color: theme( 'buttonTextHoverColor' );
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果您要添加大量主题或主题将涉及很多内容,您可能需要稍微不同地设置 SCSS 文件,以便所有主题不会使您的主 CSS 文件变得臃肿(例如上面的例子就可以了)。实现此目的的一种方法可能是创建一个themes.scss文件并复制需要主题化的任何选择器路径,并使用第二个仅输出该themes.scss文件的构建脚本。
混音
@mixin themify( $themes: $themes ) {
@each $theme, $map in $themes {
.theme-#{$theme} & {
$theme-map: () !global;
@each $key, $submap in $map {
$value: map-get(map-get($themes, $theme), '#{$key}');
$theme-map: map-merge($theme-map, ($key: $value)) !global;
}
@content;
$theme-map: null !global;
}
}
}
Run Code Online (Sandbox Code Playgroud)
功能
@function themed( $key ) {
@return map-get( $theme-map, $key );
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
21259 次 |
| 最近记录: |