最近,我一直在研究CSS变量 (或自定义属性),并认为在开发一种将它们集成到工作流中的实用策略时,我会分享一些技巧。
变量类型
在使用CSS变量时,经常会发现将其视为两种不同类型会有所帮助:
主要变量
这些是您可能希望在CSS中更新的变量-例如在不同的选择器中,在媒体查询中,在使用:hover
或:focus
进行定位或使用JavaScript进行更改时。 它们通常包含一个值:
:root {
--wrapper: 900px;
--gutter: 10px;
}
次要变量
这些是从其他变量计算得出的变量。 例如,在此关于长宽比网格单元的演示中,-- --rowHeight
变量是根据几个主要变量计算得出的。 它应用于属性,但从不手动更新-仅在更新主变量后才重新计算。
像在本示例中一样,给次级变量加上前缀可能很有用,这样您和其他使用您的代码的人都知道不应手动更改它们:
:root {
--wrapper: 900px;
--gutter: 10px;
/*
the s- prefix denotes a secondary variable
*/
--s-rh: calc((var(--wrapper) - (3 * var(--gutter))) / 4);
}
当然,唯一的例外是您是否需要更改该值的计算方式-但从理论上讲,一旦设置,它应该是永久的。 除非必要,否则这可能有助于阻止不熟悉该代码的开发人员修改该代码。
范围界定
在我的许多演示中,我在:root
声明了变量,该变量表示<html>
元素:
:root {
---bgColor: red;
}
但是,这不是严格必要的,而且实际上也不是很好的做法。 避免在Javascript中设置全局变量的许多原因也适用于CSS。 然后,如果您想在不同的组件中使用称为--bgColor
background-color
变量,则可能会遇到范围界定方面的各种问题。 最好在选择器中声明变量,例如,如果您在组件中工作:
.my-component {
---bgColor: red;
}
.some-other-component {
---bgColor: blue;
}
在上面的代码段中,-- --bgColor
的作用域是每个组件,因此您可以使用具有相同名称的变量,而不必担心它会影响该组件之外的任何内容。
设置默认值
使用CSS变量,您可以设置后备值 (或多个值)。 这意味着在某些情况下,您只需要在需要更改的位置声明变量即可。 在此演示中,仅在断点之后声明该框的变量--bgColor
,直到断点采用默认值为止:
在第二个示例中,您可以看到h1
和p
选择器的color
属性具有不同的默认值,但是当它们悬停时,它们都采用变量:
将CSS变量与预处理器变量一起使用
CSS变量的缺点之一是它们在媒体查询或选择器名称中不起作用–例如:nth-child(var(--n))
不起作用。 因此,您可能还是会在某种程度上使用预处理器变量。
除非您完全了解它们的不同特征,否则我不建议将二者混用。 Sass变量在代码到达浏览器之前就已编译,而CSS变量只有在到达浏览器后才具有计算值。 这意味着在下面的示例中, .box1
的width值(使用Sass变量)将起作用,但是.box2
会引发错误,因为--halfWidth
的值作为字符串传递给浏览器:
$width: 600px;
$halfWidth: $width / 2;
:root {
--halfWidth: $width / 2;
}
.box1 {
width: $halfWidth;
}
.box2 {
width: var(--halfWidth); // this isn’t valid
}
但是,可以像前面的示例一样使用calc()
。 在演示中查看结果:
如果您在Chrome中检查元素,然后转到“计算样式”标签,则可以看到未计算.box2
的宽度值。 在Mud,我们使用了许多Sass函数,例如,根据像素计算Rems以进行大小调整。 当我尝试将Sass函数传递给CSS变量(例如--width: rem(600px)
时,我发现这是一个问题。 有一些PostCSS插件可以将像素转换为rems并达到所需的结果,但是在确信将它们推荐与CSS变量一起使用之前,我需要对它们进行更多的试验。
尽管如此,在某些情况下,如前所述,在与CSS变量相同的代码块中使用预处理器变量是有意义的,例如在媒体查询中。
在此演示中,我将Sass变量用于CSS变量中的后备值以及媒体查询,以提供方便的可视断点帮助器: