掌握CSS级联:告别混乱,拥抱掌控!本文将探讨如何利用新的CSS特性来掌控级联,从而编写更简洁高效的CSS代码。以往,来自不同来源的样式常常导致级联难以管理,最终产生冗余代码。即使使用ITCSS和BEM等方法,我们仍然会面临级联带来的挑战,例如需要精确控制@import
语句的位置或不得不求助于!important
。幸运的是,一些新的工具已经问世,让我们能够有效地控制级联。

驾驭:where
伪选择器
:where
伪选择器允许我们消除选择器的特殊性,使其优先级仅高于用户代理默认样式,而与CSS加载顺序无关。这意味着选择器的特殊性实际上为零,这对于通用组件非常有用。
例如,使用:where
定义通用的表格样式:
:where(table) {
background-color: tan;
}
登录后复制
即使在此之前定义了其他表格样式:
table {
background-color: hotpink;
}
:where(table) {
background-color: tan;
}
登录后复制
表格背景色仍然为tan
,因为:where
消除了选择器的特殊性。这使得:where
非常适合CSS重置。
:where
的兄弟选择器:is
则具有相反的效果:
:is()
伪类的特殊性由其最特殊参数的特殊性决定。因此,使用:is()
编写的选择器并不一定具有与不使用:is()
编写的等效选择器相同的特殊性。——选择器级别4规范
继续之前的例子:
:is(table) {
--tbl-bgc: orange;
}
table {
--tbl-bgc: tan;
}
:where(table) {
--tbl-bgc: hotpink;
background-color: var(--tbl-bgc);
}
登录后复制
表格背景色将为tan
,因为:is
的特殊性与table
相同,而table
位于之后。但是,如果我们将其更改为:
:is(table, .c-tbl) {
--tbl-bgc: orange;
}
登录后复制
背景色将为orange
,因为:is
的权重与其最特殊的选择器.c-tbl
相同。
示例:可配置的表格组件
让我们构建一个表格组件,HTML如下:
接下来,我们将.c-tbl
包裹在:where
选择器中,并添加圆角:
:where(.c-tbl) {
border-collapse: separate;
border-spacing: 0;
table-layout: auto;
width: 99.9%;
}
登录后复制
表格单元格使用不同的样式:
:where(.c-tbl thead th) {
/* ... */
}
:where(.c-tbl tbody td) {
/* ... */
}
登录后复制
由于圆角和border-collapse: separate
,我们需要添加额外的样式:
:where(.c-tbl tr td:first-of-type) {
/* ... */
}
/* ... */
登录后复制
现在,我们可以通过在通用样式之前或之后注入其他样式来创建表格组件的变体(得益于:where
的特殊性消除功能):
.c-tbl--purple th {
background-color: hsl(330, 50%, 40%)
}
/* ... */
登录后复制
CSS自定义属性
我们将使用data-component
属性来定义组件:
通用样式将应用于所有组件实例,特定组件实例的样式将包含在常规类中,并使用通用组件的自定义属性。
:where([data-component="table"]) {
/* ... */
}
.c-tbl--purple {
/* ... */
}
登录后复制
在通用组件中,每个CSS属性都指向一个自定义属性。需要作用于子元素的属性(如border-color
)在通用组件的根部指定:
:where([data-component="table"]) {
--tbl-hue: 200;
/* ... */
}
:where([data-component="table"] td) {
border-color: var(--tbl-bdc);
}
登录后复制
其他属性可以设置静态值或使用自定义属性进行配置。如果使用自定义属性,请记住定义一个默认值,以便在缺少变体类时使用。
:where([data-component="table"]) {
background-color: var(--tbl-bgc, transparent);
/* ... */
}
登录后复制
我们可以使用自定义属性来控制列对齐和宽度:
:where([data-component="table"] tr > *:nth-of-type(1)) {
text-align: var(--ca1, initial);
/* ... */
}
登录后复制
现在,让我们创建特定组件样式,使用常规类.c-tbl
:
.c-tbl {
--tbl-hue: 330;
}
登录后复制
我们只需要更新属性,而无需编写全新的CSS!更改一个属性即可更新表格的颜色。
我们可以编写更复杂的样式,例如斑马条纹:
.c-tbl tr:nth-child(even) td {
--tbl-td-bgc: hsl(var(--tbl-hue), var(--tbl-sat), 95%);
}
登录后复制
使用另一个data-attribute
添加参数
我们可以添加另一个data-param
属性来添加更多参数:
然后,在CSS中,我们可以使用属性选择器来匹配参数列表中的整个单词。例如,斑马条纹行:
[data-component="table"][data-param~="zebrarow"] tr:nth-child(even) td {
--tbl-td-bgc: var(--tbl-zebra-bgc);
}
登录后复制
或者斑马条纹列:
[data-component="table"][data-param~="zebracol"] td:nth-of-type(odd) {
--tbl-td-bgc: var(--tbl-zebra-bgc);
}
登录后复制
级联层
最后一个控制级联的工具是“级联层”。目前,它是一个实验性功能,可以在Safari或Chrome中启用#enable-cascade-layers
标志来访问。
级联层允许我们以特定顺序注入样式表。一个简化的结构如下:
@layer generic, components;
登录后复制
这决定了层的顺序。首先是通用样式,然后是组件特定样式。
即使组件样式写在通用样式之前,组件样式层仍然优先:
@layer components {
body {
background-color: lightseagreen;
}
}
@layer generic {
body {
background-color: tomato;
}
}
登录后复制
总结
:where
和:is
伪选择器允许我们控制特殊性;CSS自定义属性允许我们覆盖样式而无需编写新的类;data-attribute
可以增加灵活性;级联层允许我们指定样式的加载顺序。 CSS级联不再是敌人,而是我们可以掌控的工具。
图片来自Stephen Leonardi在Unsplash
以上是不要与级联战斗,控制它!的详细内容。更多信息请关注PHP中文网其他相关文章!