CSS 个变量,适用于旧版浏览器
CSS variables with fallback for older browsers
TL;DR:如何使用 SCSS 让 CSS 变量具有旧浏览器的回退。
我正在尝试理解这个 article。在我看来,您必须已经是高级 SASS 用户才能理解它,但我不是。更糟糕的是,这是我找到的唯一一篇关于该主题的文章。
这是我要实现的目标:
我的 scss 应该是这样的:
body {
@include v(background-color, primary)
}
那么处理后的CSS应该是
body{
background: yellow; /* Yellow being defined above as the primary color */
background: var(--color-primary);
}
通过稍微尝试一下,我已经可以得到 CSS 变量的值,如下所示:
$colors: (
primary: yellow,
);
:root {
@each $name, $color in $colors {
--color-#{$name}: $color;
}
}
@mixin background-color($color_) {
background: var(--color-#{$color_});
}
使用方法:
body{
@include background-color(primary);
}
这将导致:
body {
background: var(--color-primary);
/* But the fallback is missing :(, I tried things with the map-get but it's really eluding me... */
}
我假设您知道它没有显示回退的原因。但既然是答案我就解释一下原因
当前mixin块只有一个背景属性,这使得sass编译器只生成一个属性。我认为 sass 无法识别浏览器是否支持 'var'。因此,我们必须明确指定是否需要回退。
既然你已经有了地图,你所需要的就是通过提供密钥来获取值 'primary'
@mixin background-color($color_) {
background: var(--color-#{$color_});
background: map-get($colors, primary);
}
这将始终向正文添加背景:黄色 class。或者,如果您想根据条件控制回退的添加。你可以这样做
@mixin background-color($color_, $showFall) {
background: var(--color-#{$color_});
@if $showFall {
background: map-get($colors, primary);
}
}
然后这样调用
body{
@include background-color(primary, true);
}
相同的代码笔
https://codepen.io/srajagop/pen/xdovON
注意:我在假设您只希望背景颜色起作用而不是 post 中提到的所有其他属性的情况下编写答案。为此你需要创建一个合适的数据结构
更新: Postcss Custom properties 可以回退并且比下面的代码更容易
第 1 步:声明 scss 个变量
所以首先我们要将一些变量放在 $map
中,我将使用颜色变量:
$colors: (
primary: #FFBB00,
secondary: #0969A2
);
第 2 步:自动化 css 4 变量生成
// ripped CSS4 vars out of color map
:root {
// each item in color map
@each $key, $value in $colors {
--colors-#{$key}: $value;
}
}
root 中发生的事情是:对于颜色 map 中的每个键和值,我们打印以下内容:
--colors-#{$key}: $value;
对应于 css 变量声明。我相信 #{}
键周围的奇怪位是值周围没有空格。
因此结果是:
--colors-primary: #FFBB00,
--colors-secondary: #0969A2
注意前缀(--colors-
)与上面的scss色图同名。为什么会在最后一步变得清楚。
第 3 步:大量地图!
$props: (
background-color: $colors
);
$map-maps: (
background-color: colors
);
这里我们添加映射 $props
,它将 css 属性 映射到包含值的映射。 background-color
会保留颜色,所以正确的贴图是 $colors
.
map-maps
是 props 的副本,其中我们使用所述地图的名称而不是地图。 (这与步骤 2 中的注释有关)。
第 4 步:开始吧!
@mixin v($prop, $var) {
// get the map from map name
$map: map-get($props, $prop);
// fallback value, grab the variable's value from the map
$var-fall: map-get($map, $var);
// our css4 variable output
$var-output: var(--#{$map}-#{$var});
#{$prop}: $var-fall;
// css4 variable output
#{$prop}: $var-output;
}
body{
@include v(background-color, primary);
}
我把文章中的代码简化了很多,它仍然有效,至少对于这个例子,文章中的代码考虑到了更多。
无论如何,事情是这样的。
首先,我们调用mixin:
@include v(background-color, primary);
然后进入后,
$map: map-get($props, $prop); // map-get($props, background-color)
我们有一个名为 $map
的变量,我们将 $props
映射内部的值分配给键 background-color
处的值,而键 $colors
恰好是 $colors
映射.这有点迷宫,但一旦你解决了它就没那么复杂了。
然后备用:
$var-fall: map-get($map, $var);
这只是在 $var
键(恰好是主键)处获取我们刚刚获得的映射(即 $colors
)的值。因此结果是 #FFBB00
.
对于 css 变量
$map-name: map-get($map-maps, $prop);
$var-output: var(--#{$map-name}-#{$var});
我们重新创建我们在 @each
循环中生成 var 的操作
整个代码为:
$colors: (
primary: #FFBB00,
secondary: #0969A2
);
// ripped CSS4 vars out of color map
:root {
// each item in color map
@each $name, $color in $colors {
--colors-#{$name}: $color;
}
}
$props: (
background-color: $colors,
color: $colors
);
$map-maps: (
background-color: colors
);
@mixin v($prop, $var) {
// get the map from map name
$map: map-get($props, $prop);
// fallback value, grab the variable's value from the map
$var-fall: map-get($map, $var);
// our css4 variable output
$map-name: map-get($map-maps, $prop);
$var-output: var(--#{$map-name}-#{$var});
#{$prop}: $var-fall;
// css4 variable output
#{$prop}: $var-output;
}
body{
@include v(background-color, primary);
}
现在这是对文章中所做内容的简化。您应该检查它以使代码更健壮。
如果您正在使用 Sass,您可以通过 Sass 混入自动回退。创建一个 CSS 变量名称及其值的映射,然后您可以在输出后备样式和首选样式的混合中查找这些值
$vars: (
primary: yellow,
);
:root {
--primary: map-get($vars, primary);
}
@mixin var($property, $varName) {
#{$property}: map-get($vars, $varName);
#{$property}: var(--#{$varName});
}
上面的mixin是这样使用的:
body {
@include var(background-color, primary);
}
并输出以下 CSS:
:root {
--primary: yellow;
}
body {
background-color: yellow;
background-color: var(--primary);
}
Et voilà :)
TL;DR:如何使用 SCSS 让 CSS 变量具有旧浏览器的回退。
我正在尝试理解这个 article。在我看来,您必须已经是高级 SASS 用户才能理解它,但我不是。更糟糕的是,这是我找到的唯一一篇关于该主题的文章。
这是我要实现的目标:
我的 scss 应该是这样的:
body {
@include v(background-color, primary)
}
那么处理后的CSS应该是
body{
background: yellow; /* Yellow being defined above as the primary color */
background: var(--color-primary);
}
通过稍微尝试一下,我已经可以得到 CSS 变量的值,如下所示:
$colors: (
primary: yellow,
);
:root {
@each $name, $color in $colors {
--color-#{$name}: $color;
}
}
@mixin background-color($color_) {
background: var(--color-#{$color_});
}
使用方法:
body{
@include background-color(primary);
}
这将导致:
body {
background: var(--color-primary);
/* But the fallback is missing :(, I tried things with the map-get but it's really eluding me... */
}
我假设您知道它没有显示回退的原因。但既然是答案我就解释一下原因
当前mixin块只有一个背景属性,这使得sass编译器只生成一个属性。我认为 sass 无法识别浏览器是否支持 'var'。因此,我们必须明确指定是否需要回退。
既然你已经有了地图,你所需要的就是通过提供密钥来获取值 'primary'
@mixin background-color($color_) {
background: var(--color-#{$color_});
background: map-get($colors, primary);
}
这将始终向正文添加背景:黄色 class。或者,如果您想根据条件控制回退的添加。你可以这样做
@mixin background-color($color_, $showFall) {
background: var(--color-#{$color_});
@if $showFall {
background: map-get($colors, primary);
}
}
然后这样调用
body{
@include background-color(primary, true);
}
相同的代码笔 https://codepen.io/srajagop/pen/xdovON
注意:我在假设您只希望背景颜色起作用而不是 post 中提到的所有其他属性的情况下编写答案。为此你需要创建一个合适的数据结构
更新: Postcss Custom properties 可以回退并且比下面的代码更容易
第 1 步:声明 scss 个变量
所以首先我们要将一些变量放在 $map
中,我将使用颜色变量:
$colors: (
primary: #FFBB00,
secondary: #0969A2
);
第 2 步:自动化 css 4 变量生成
// ripped CSS4 vars out of color map
:root {
// each item in color map
@each $key, $value in $colors {
--colors-#{$key}: $value;
}
}
root 中发生的事情是:对于颜色 map 中的每个键和值,我们打印以下内容:
--colors-#{$key}: $value;
对应于 css 变量声明。我相信 #{}
键周围的奇怪位是值周围没有空格。
因此结果是:
--colors-primary: #FFBB00,
--colors-secondary: #0969A2
注意前缀(--colors-
)与上面的scss色图同名。为什么会在最后一步变得清楚。
第 3 步:大量地图!
$props: (
background-color: $colors
);
$map-maps: (
background-color: colors
);
这里我们添加映射 $props
,它将 css 属性 映射到包含值的映射。 background-color
会保留颜色,所以正确的贴图是 $colors
.
map-maps
是 props 的副本,其中我们使用所述地图的名称而不是地图。 (这与步骤 2 中的注释有关)。
第 4 步:开始吧!
@mixin v($prop, $var) {
// get the map from map name
$map: map-get($props, $prop);
// fallback value, grab the variable's value from the map
$var-fall: map-get($map, $var);
// our css4 variable output
$var-output: var(--#{$map}-#{$var});
#{$prop}: $var-fall;
// css4 variable output
#{$prop}: $var-output;
}
body{
@include v(background-color, primary);
}
我把文章中的代码简化了很多,它仍然有效,至少对于这个例子,文章中的代码考虑到了更多。
无论如何,事情是这样的。
首先,我们调用mixin:
@include v(background-color, primary);
然后进入后,
$map: map-get($props, $prop); // map-get($props, background-color)
我们有一个名为 $map
的变量,我们将 $props
映射内部的值分配给键 background-color
处的值,而键 $colors
恰好是 $colors
映射.这有点迷宫,但一旦你解决了它就没那么复杂了。
然后备用:
$var-fall: map-get($map, $var);
这只是在 $var
键(恰好是主键)处获取我们刚刚获得的映射(即 $colors
)的值。因此结果是 #FFBB00
.
对于 css 变量
$map-name: map-get($map-maps, $prop);
$var-output: var(--#{$map-name}-#{$var});
我们重新创建我们在 @each
循环中生成 var 的操作
整个代码为:
$colors: (
primary: #FFBB00,
secondary: #0969A2
);
// ripped CSS4 vars out of color map
:root {
// each item in color map
@each $name, $color in $colors {
--colors-#{$name}: $color;
}
}
$props: (
background-color: $colors,
color: $colors
);
$map-maps: (
background-color: colors
);
@mixin v($prop, $var) {
// get the map from map name
$map: map-get($props, $prop);
// fallback value, grab the variable's value from the map
$var-fall: map-get($map, $var);
// our css4 variable output
$map-name: map-get($map-maps, $prop);
$var-output: var(--#{$map-name}-#{$var});
#{$prop}: $var-fall;
// css4 variable output
#{$prop}: $var-output;
}
body{
@include v(background-color, primary);
}
现在这是对文章中所做内容的简化。您应该检查它以使代码更健壮。
如果您正在使用 Sass,您可以通过 Sass 混入自动回退。创建一个 CSS 变量名称及其值的映射,然后您可以在输出后备样式和首选样式的混合中查找这些值
$vars: (
primary: yellow,
);
:root {
--primary: map-get($vars, primary);
}
@mixin var($property, $varName) {
#{$property}: map-get($vars, $varName);
#{$property}: var(--#{$varName});
}
上面的mixin是这样使用的:
body {
@include var(background-color, primary);
}
并输出以下 CSS:
:root {
--primary: yellow;
}
body {
background-color: yellow;
background-color: var(--primary);
}
Et voilà :)