精读《使用 CSS 属性选择器》

1 引言

虽然现在 Css Module 与 Css-in-js 更流行,但使用它们会导致过分依赖 滥用 class 做唯一定位,违背了 Css 选择器的初衷。

本期精读的文章是:attribute-selectors-splicing-html-dna-css,带你重新理解强大的 Css 选择器。

2 概要

Css Module 与 Css-in-js 大部分场景使用 className 作为选择器,那么本文以选择器为重点,看看选择器有哪些实用的用法。

属性选择器

如果你想选择包含 title 属性的 div

div[title]

选择包含 title 属性的子元素,只需要加个空格:

div [title]

选择 title 内容是 dna 的元素:

div[title="dna"]

选择 title 属性包含 dna 单词的元素:

注意 dna 需要是单词,也就是用空格分割,比如 “my beautiful dna” 或 “mutating dna is fun!”
div[title~="dna"]

和正则类似,选择 title 属性中,以 dna 结尾的元素:

div[title$="dna"]

dna 开头:

div[title^="dna"]

如果希望选择 dnadna-zh,但不希望匹配 dnaer,可以:

这种场景一般用在国际化,比如 en en-us 就可以用 |="en"
div[title|="dna"]

只要包含 dna 这三个字符就选中:

div[title*="dna"]

真的很像正则,你可以用 i 标识匹配时大小写不敏感:

div[title*="dna" i]

如果你想找到一个 a 标签,拥有 title 属性并且 className 以 genes 结尾,可以这样:

a[title][class$="genes"]

获取标签的值

可以用 attr 标识符拿到当前选择器选中元素的属性,比如当 hover 状态时,在文字尾部显示其 title 属性:

.joke:hover:after {
  content: "Answer:" attr(title);
  display: block;
}

其它用法

本文还介绍了一些实用技巧,比如

根据输入框类型设置样式

input[type="email"] {
  color: papayawhip;
}
input[type="tel"] {
  color: thistle;
}

改变下载标签的 icon

a[download][href$="pdf"]:after {
  content: url(pdf-icon.svg);
}

当然也可以选中一些老代码进行样式重写,比如:

Old, holey genes
div[bgcolor="#000000"] {
  /*override*/
  background-color: #222222 !important;
}

不过这种用法要谨慎,写的越多越难以维护。

结合一些新标签功能

比如 details 标签是 html 原生的手风琴折叠组件:

List of Genes Roddenberry Hackman

我们可以使用属性选择器,定义其打开时的样式:

details[open] {
  background-color: hotpink;
}

为没有 async 标记的 script 标签着色,算是友情提示哪儿有错误:

script[src]:not([async]) {
  display: block;
  width: 100%;
  height: 1em;
  background-color: red;
}
script:after {
  content: attr(src);
}

为 JS 事件着色,比如触发的鼠标事件可以作为选择器:

[OnMouseOver] {
  color: burlywood;
}
[OnMouseOver]:after {
  content: "JS: " attr(OnMouseOver);
}

选中隐藏元素:

[hidden],
[type="hidden"] {
  display: block;
}

还有更多就不一一列举了,感兴趣的读者可以跳转到原文继续阅读。大部分内容其实都写在了 w3school 选择器参考手册,只是结合一篇文章来读,可以理解得更深刻,同时文章里确实有一些新鲜的选择器,比如 JS 事件选择器,HTML5 属性标签选择器等等。

3 精读

这篇文章确实说明了 Css 选择器的强大性,但回到 css module 或者 css-in-js 的工程代码里,我们往往难以做太多的实践,有如下几个原因:

一直在担心的 DOM 结构变动

业务开发中,大量需求涌入,也许过了一周,DOM 结构就已经面目全非了,而且就算是一个普通的圣杯布局,可能老版本用 Table 布局,后面进来一个年轻小伙子直接用 div + flex 重构了,你会担心之前写的 table 选择器在某一天全部失效。

也许今天的 div 选择器,明天因为语义化改造就换成了 article 标签。

最大原因是 一种视觉界面对应的实现方式太多,不仅标签可以各异,css 属性还有 table、block、flex、grid 可选,同时 grid 属性还会导致视觉结构与 DOM 结构不完全对应。

如果你今天用 css 选择器做了一套完全贴合现在 DOM 结构的 css 文件,这个 css 文件也许是后面 dom 结构改动的噩梦。

你敢做全局样式覆盖吗

我们排除标签,仅对属性做全局覆盖,的确可以部分绕开 DOM 结构的限制,但是这样的全局样式覆盖,不同的人有不同看法。

小明的团队非常懂得 css 运用,他们每天都会花一个小时讨论项目的 css 架构,并对通用需求样式做了抽象,并且每个人都很认可这个方案,在他们的团队,一个非常酷炫的按钮与动画效果,通过

你可能感兴趣的:(javascript)