Css 如何在SCS中实现可切换主题?
我有一个使用语义变量的scss文件的现有项目:Css 如何在SCS中实现可切换主题?,css,sass,Css,Sass,我有一个使用语义变量的scss文件的现有项目: $background-color: white; body { background-color: $background-color; } 我想在向主体添加主题类时将背景更改为黑色: <body class="theme-dark">...</body> 更新(基于Amar的回答): .theme-light { --background-color: white; } :ro
$background-color: white;
body {
background-color: $background-color;
}
我想在向主体添加主题类时将背景更改为黑色:
<body class="theme-dark">...</body>
更新(基于Amar的回答):
.theme-light {
--background-color: white;
}
:root {
--background-color: white;
}
.theme-dark {
--background-color: black;
}
$background-color: var(--background-color);
body {
background-color: $background-color;
}
将scss变量定义为具有css变量扩展作为值,即(从上面开始):
生成以下css:
:root { --background-color: white; }
.theme-dark { --background-color: black; }
body { background-color: var(--background-color); }
这似乎是我们想要的
我喜欢它,因为它只需要更改
$background color
的定义(不是在非常大的scss文件中的所有用法),但我不确定这是否是一个合理的解决方案?我对scss还很陌生,所以可能我错过了一些功能。使用scss可以做到这一点,但您必须将样式添加到所有要设置主题的元素中。这是因为SCS是在构建时编译的,不能用类切换变量。例如:
$background-color-white: white;
$background-color-black: white;
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;
}
}
目前最好的方法是使用CSS变量。您可以这样定义默认变量:
:root {
--background-color: white;
--text-color: black;
}
.theme-dark {
--background-color: black;
--text-color: white;
}
body {
background-color: var(--background-color);
color: var(--text-color);
}
然后,在元素中使用这些变量,如下所示:
:root {
--background-color: white;
--text-color: black;
}
.theme-dark {
--background-color: black;
--text-color: white;
}
body {
background-color: var(--background-color);
color: var(--text-color);
}
如果body
元素具有主题类,它将使用为该类定义的变量。否则,它将使用默认的根变量。所有信用都归Dmitry Borody所有
我会推荐一种类似于中提到的方法。使用这种方法,您可以指定需要设置主题的类,而无需特别提及主题名称,这样就可以同时应用多个主题
首先,设置包含主题的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,
),
);
然后使用mixin
和函数
对添加主题支持
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' );
}
}
}
如果你要添加很多主题,或者一个主题会涉及很多东西,你可能希望设置你的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;
}
}
}
@function themed( $key ) {
@return map-get( $theme-map, $key );
}
功能
@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;
}
}
}
@function themed( $key ) {
@return map-get( $theme-map, $key );
}
您是否建议不要定义和使用$background color
scss变量?@比约恩我刚刚更新了我的答案,以展示如何使用scss实现这一点。对于主题化,我建议您使用SCSS变量,因为您可以随时切换这些变量,而不必为主题自定义的所有元素设置样式。@Bjorn取决于,CSS变量可能不适合您。@hungerstar谢天谢地,这不是问题(是的,我知道我很幸运;-)@AmarSyla我刚刚更新了这个问题,详细介绍了如何将css变量作为scss变量的值编译到您答案中的最后一个代码块中。我在第一条评论中的问题是,您是否建议不要以这种方式混合css变量和scss变量?这当然令人印象深刻:-)我不确定我会称之为轻量级,而且它需要更改现有(非常大)scss文件中的几乎每一条规则…为什么您必须更改规则(假设你指的是CSS选择器)?你只需添加@include themify{}
其中需要添加主题样式,并将主题
函数与属性值一起使用。由@AmarSyla提供的SCSS解决方案将需要相同的工作量,CSS变量解决方案将是最精简的,但我可以看出人们可能不希望所有--background color
的实例都切换。在这种情况下,y你将处理更多的变量,并拥有与SCSS解决方案类似的开销。如果一个小函数和一个小混入不是轻量级的,那么我不知道该告诉你什么。这将起作用,直到你决定说darken($background color,10%);
@YuryTarabanko啊..我知道一定有这样的事情:-/