编写更好的 CSS 代码 (Part Ⅱ)

在早期的 Web 开发中,页面的布局和定位通常要用表格和各种 hack 技术来实现。与那时相比,CSS 已经得到了长足的发展。如今,开发人员可以很轻松地编写出适用于所有主流浏览器的 CSS 代码,在实现复杂布局时也不会像以前那样绞尽脑汁。这不仅使响应式布局变得更容易,还可以通过删除冗余的代码来发布体积更小的样式。在本文中,我们将使用现代技术来降低代码的复杂程度,通过一些较新的技术来编写出更好的 CSS 代码。

使用 :where 设置全局默认样式

与 :is 的用法一样(具体可见上一篇文章,编写更好的 CSS 代码 (Part I)),:where 也是接收选择器列表作为它的参数。

.nav-link:where(:focus, :hover, [aria-current="page"]) {}

:where 和 :is 的不同之处在于,:is 中选择器的优先级与列表中最高的优先级保持一致;而 :where 中选择器的优先级被设置为最低,权重值为 0。选择器优先级的权重值,如下所示:

  • 内联样式:1000
  • ID 选择器:100
  • 类选择器、属性选择器等:10
  • 元素选择器、伪元素选择器等:1
  • 通配符、相邻选择器等:0

换句话说,:is 提高了列表参数中每个选择器优先级;:where 降低了列表参数中每个选择器优先级。下面两段代码中选择器的优先级是相同的。

// 10 + 0
.nav-link:where(:focus, :hover, [aria-current="page"]) {}
// 10
.nav-link {}

无论它的参数是多么复杂的选择器,它的优先级都是 0;比如在下面的代码中,选择器的优先级也是 0:

where(#id:not(.very.high.specificity).more.classes) {}

由于优先级低,:where 声明的样式很容易被覆盖了,因此 :where 特别适合全局的样式重置(CSS Reset)的场景。Elad Schechter 在他实现的现代 CSS 样式重置中,使用 :where 来为一些元素设置默认的样式。下面是他的部分代码实现:

:where(ul, ol) {
  list-style: none;
}

:where(img) {
  max-width: 100%;
  height: auto;
}

/* etc */

在这份样式表中,选择器的优先级比较低,它们的样式很容易被其他选择器覆盖。当我们在重写样式时,不需要特意地提高选择器的优先级。

在 CSS 的实践中,重置样式通常会放在最前面,并且在开发中很少使用元素选择器来声明样式,例如使用 BEM 技术。于是 :where 可以在一定程度上保证,定义的样式永远不会在优先级上遇到任何冲突。

另外,Adam Argyle 在他的文章 :is 和 :where 中提到,在一些公共库中,:where 优先级比较低这个特点,是非常有用的。因为,当用户需要自定义样式时,可以很方便地将公共库中的样式覆盖掉。

发表评论

后才能评论