Libon

CSS 属性选择器

这一次彻底学会 CSS 属性选择器的使用

其实之前一直都记不太清 CSS 里的属性选择器的匹配规则,然后这次趁着给博客中的部分外链链接加上了 external 图标的机会,正好理清一下所有属性选择器的匹配方式,防止下一次在需要使用的时候又要翻文档去找。

[] 属性匹配

在 CSS 里可以使用 [] 来对包含某个属性的元素进行匹配,语法为 [attribute],以下示例是点开 <details /> 元素时背景颜色将会变为红色

<details open>
  <summary>matching</summary>
</details>
<details>
  <summary>do not matching</summary>
</details>

<style>
details[open] {
  background: #f00
}
</style>

^ 前缀匹配

在 CSS 里可以使用 脱字符(^) 来根据元素属性值以什么什么开头作为匹配规则来选择元素,这被称作为:starts with 属性选择器,语法为:[attribute^=value],其中这里面的 ^ 和正则里的 ^ 作用是一样的,都是用于匹配以xxx作为开头。

<p title="matching">matching</p>
<p title="do-not-matching">do not matching</p>

<style>
[title^="matching"] {
  background: #f00
}
</style>

当然,属性选择器也是可以组合的(下面其他的选择器就不再重复举例了),比如说我想要匹配 target="_blank"<a /> 标签那我就可以这么做:

<a href="https://baidu.com">baidu.com</a>
<a href="https://google.com" target="_blank">google.com</a>

<style>
a[href^="https"][target="_blank"] {
  background-color: #f00
}
</style>

$ 后缀匹配

后缀匹配器是以 美元符号($) 来进行表示的,这被称之为:ends with 属性选择器,语法是 [attribute$=value],这里面的 $ 也和 正则里的 $ 作用一致,用于匹配以什么作为结尾的字符串。我们可以用这个选择器来对 a 标签的 href 属性中是否包含 .pdf 来判断是否是一个资源路径,你还可以用这种方式来对 a 标签添加一个对应资源类型的图标。

<a href="http://example.com/test.pdf">test.pdf</a>
<a href="http://example.com/test.doc">test.doc</a>

<style>
[href$=".pdf"] {
  background-color: #f00
}
</style>

* 子串匹配

子串匹配则是使用 星号(*) 作为匹配符,语法为 [arrtibute*=value]。规则是只要设置的属性中有包含 value 这一子串的时候则匹配成功:

<a href="http://google.com">google</a>
<a href="http://facebook.com">facebook</a>

<style>
[href*="com"] {
  color: #f00
}
[href*="google"] {
  background-color: #f00;
  color: #fff
}
</style>

~ 包含匹配

包含匹配是以 波浪号(~) 作为匹配符的选择器。语法为 [attribute*=value]。它的匹配规则是只要属性值可能有很多,但至少有一个包含了 “value” 的就算匹配成功(相当于是将 value 作为了一个分词符,必须完整包含 value 这个分词符)

<ul>
  <li>Item 1</li>
  <li class="a">Item 2</li>
  <li class="a b">Item 3</li>
  <li class="ab">Item 4</li>
</ul>

<style>
li[class~="a"] {
  color: red;
}
</style>

| 开头匹配

这个选择器也是比较少见的一个,以至于我甚至都没查到它的官方用名到底叫什么。同时它的匹配规则也有一点特殊,它和 ^= 很像,但又有着特殊规则:

<p lang="en">en</p>
<p lang="en-US">en-US</p>
<p lang="en-source">en-source</p>

<style>
[lang|="en"] {
  background-color: #f00
}

[lang^="en"] {
  color: #ff0
}
</style>

是的,它俩都能匹配上,但是 W3Schools 上给的解释是

Represents an element with the att attribute, its value either being exactly “val” or beginning with “val” immediately followed by ”-” (U+002D). This is primarily intended to allow language subcode matches (e.g., the hreflang attribute on the a element in HTML) as described in BCP 47 ([BCP47]) or its successor. For lang (or xml:lang) language subcode matching, please see the :lang() pseudo-class.

从描述中我们可以理解成当 value 可能是 en en-US en-source 这种在分词符后面会接上 - 分隔符的字符串的时候就比较适用于这个选择器(比如说 html 元素上的 lang 属性的值就有可能是 zh zh-CN 等)。(我个人觉得 ^= 就够用辣~)

精准匹配

这个就很明显了,元素中必须完整包含完整的 value,这个选择器是没有匹配符的,这里使用上面的实例:

<p title="matching">matching</p>
<p title="do-not-matching">do not matching</p>

<style>
[title="matching"] {
  background: #f00
}
</style>

修饰符

其实到了这里很多教程就都已经结束了,但是他们都漏掉了一个比较重要的点,就是 value 值也是可能包含大小写的,而这些选择器默认情况下对大小写敏感的。

等一下,默认情况下?还有特殊情况?

是的,这种情况是可以被打破的,在以上这些属性选择器里,不仅仅是语法和正则有点相似,还有一个很容易被人忽视的东西,那就是和正则第二个参数一样的 “修饰符”。

忽略大小写

在属性选择的 [] 内以空格分隔,再加上参数 i 就可以在匹配的时候忽略大小写了:

<p title="MATCHING">matching</p>
<p title="matching">do not matching</p>

<style>
[title*="MATCHING" i] {
  background: #f00
}
</style>

上面的例子是,只要 title 属性包含了 matching 值即可命中,而不管它是否是大小写。

强制检查大小写

s 修饰符是用于在对大小写不敏感的上下文中强行要求匹配的时候检查大小写,只不过只有火狐在 2019-03-19 年发布的 v66 及以后的版本支持,其他的(Chrome、Edge、Opera、Safari)全都不支持。。。。在这种情况下的特性那基本上约等于没有,所以这里也不再展开了,知道有这么一回事就好了。

以上。

cd ../