33个好用的css选择器

前言

CSS 选择器是 CSS 世界中非常重要的一环。

在 CSS 2 之后,所有的 CSS 属性都是按模块去维护的。

CSS 选择器也是如此,然而如今也已经发布了第四版 —— CSS Selectors Level 4 ,这一版最早的草案发布于2011年09月29日,最后更新是2018年11月21日。

下面让我们一起来看看 Level 4 新推出的一些选择器。

正文

下面我们按照类型来划分

逻辑组合(Logical Combinations)

在这个分类下,我们有以下四个选择器:

:not()

其实 :not() 不算是新标签,不过在 Level 4 里,增加了多选的功能,代码如下:

/* 除了.left, .right, .top之外所以的div的盒子模型都会变成flex*/div:not(.left, .right, .top) {  display: flex;}/* 等价于 */div:not(.left), div:not(.right), div:not(.top) {  display: flex;}

兼容性如下:

image

额。。。还不能用

:is()

:is() 伪类将选择器列表作为参数,并选择该列表中任意一个选择器可以选择的元素。这对于以更紧凑的形式编写大型选择器非常有用。

看个栗子:

/* 选择header, main, footer里的任意一个悬浮状态的段落(p标签) */:is(header, main, footer) p:hover {  color: red;  cursor: pointer;}/* 等价于 */header p:hover,main p:hover,footer p:hover {  color: red;  cursor: pointer;}

兼容如下:

image

:where()

:where() 伪类接受选择器列表作为它的参数,将会选择所有能被该选择器列表中任何一条规则选中的元素。

其实就是跟 :is() ,唯一不同的就是 :where() 的优先级总是为 0 ,但是 :is() 的优先级是由它的选择器列表中优先级最高的选择器决定的。

代码如下:

<style>    :is(section.is-styling, aside.is-styling, footer.is-styling) a {        color: red;    }    :where(section.where-styling, aside.where-styling, footer.where-styling) a {        color: orange;    }    footer a {        color: blue;    }</style><article>    <h2>:is()-styled links</h2>    <section class="is-styling">        <p>Here is my main content. This <a href="https://mozilla.org">contains a link</a>.    </section>    <aside class="is-styling">        <p>Here is my aside content. This <a href="https://developer.mozilla.org">also contains a link</a>.    </aside>    <footer class="is-styling">        <p>This is my footer, also containing <a href="https://github.com/mdn">a link</a>.    </footer></article><article>    <h2>:where()-styled links</h2>    <section class="where-styling">        <p>Here is my main content. This <a href="https://mozilla.org">contains a link</a>.    </section>    <aside class="where-styling">        <p>Here is my aside content. This <a href="https://developer.mozilla.org">also contains a link</a>.    </aside>    <footer class="where-styling">        <p>This is my footer, also containing <a href="https://github.com/mdn">a link</a>.    </footer></article>

:is():where() 对比效果图如下:

image

兼容性如下:

image

:has()

:has() 伪类代表一个元素,其给定的选择器参数(相对于该元素的 :scope)至少匹配一个元素。

:has() 接受一个选择器组作为参数。在当前规范中 :has() 并未列为实时选择器配置的一部分,意味着其不能用于样式表中。

语法如下:

// 下面的选择器只会匹配直接包含 <img> 子元素的 <a> 元素a:has(> img)// 下面的选择器只会匹配其后紧跟着 <p> 元素的 <h1> 元素:h1:has(+ p)

兼容性如下:

image

嗯,全红。。。

语言伪类(Linguistic Pseudo-classes)

:dir()

:dir()伪类匹配特定文字书写方向的元素。在HTML中, 文字方向由dir属性决定。其他的文档类型可能有其他定义文字方向的方法。

:dir() 并不等于使用 [dir=…] 属性选择器。后者匹配 dir 的值且不会匹配到未定义此属性的元素,即使该元素继承了父元素的属性;类似的, [dir=rtl][dir=ltr]不会匹配到dir属性的值为auto的元素。而 :dir()会匹配经过客户端计算后的属性, 不管是继承的dir值还是dir值为auto的。

例子如下:

<style>    :dir(ltr) {        background-color: yellow;    }    :dir(rtl) {        background-color: powderblue;    }</style><div dir="rtl">      <span>test1</span>      <div dir="ltr">test2        <div dir="auto">עִבְרִית</div>      </div></div>

效果如下:

image

兼容性如下:

image

又是一片红。。

:lang()

:lang() 伪类基于元素语言来匹配页面元素。

例子如下:

/* 下例表示选择文本语言带有-TN的div元素 (ar-TN, fr-TN). */div:lang(*-TN) {    background-color: green}

浏览器支持状态:没有一个支持的。

位置伪类(Location Pseudo-classes)

:any-link

:any-link 伪类 选择器代表一个有链接锚点的元素,而不管它是否被访问过,也就是说,它会匹配每一个有 href 属性的 <a><area><link>元素。因此,它会匹配到所有的 :link:visited

例子如下:

<style>    a:any-link {        border: 1px solid blue;        color: orange;    }    /* WebKit 内核浏览器 */    a:-webkit-any-link {        border: 1px solid blue;        color: orange;    }</style><a href="https://example.com">External link</a><br><a href="#">Internal target link</a><br><a>Placeholder link (won't get styled)</a>

效果如下:

image

兼容性如下:

image

:local-link

:local-link伪类可以单独格式化本地链接(原文是local links)(内部链接)。

例子如下:

a:local-link {   text-decoration: none;}

效果 & 兼容性

没有一个浏览器是支持的,看不到效果

:target-within

:target-within伪类适用于:target所匹配的元素,以及它DOM节点内所有匹配的元素。

例子如下:

div:target-within {   border: 2px solid black;}

效果 & 兼容性

没有一个浏览器是支持的,看不到效果

:scope

:scope伪类表示作为选择器要匹配的作用域的元素。不过目前它等效于 :root

因为尚未有浏览器支持CSS的局部作用域。

例子如下:

:scope {   background-color: lime;}

兼容性如下:

image

浏览器算法不支持,兼容有跟没没区别~

用户行为伪类(User Action Pseudo-classes)

:focus-visible

当元素匹配 :focus 伪类并且客户端(UA)的启发式引擎决定焦点应当可见(在这种情况下很多浏览器默认显示“焦点框”。)时,:focus-visible 伪类将生效。

这个选择器可以有效地根据用户的输入方式(鼠标 vs 键盘)展示不同形式的焦点。

例子如下:

<style>    input, button {        margin: 10px;    }    .focus-only:focus {        outline: 2px solid black;      }    .focus-visible-only:focus-visible {        outline: 4px dashed darkorange;    }</style><input value="Default styles"><br><button>Default styles</button><br><input class="focus-only" value=":focus only"><br><button class="focus-only">:focus only</button><br><input class="focus-visible-only" value=":focus-visible only"><br><button class="focus-visible-only">:focus-visible only</button>

效果如下:

image

兼容性如下:

目前只有Chrome 67+ 兼容...

:focus-within

:focus-within伪类适用于:focus所匹配的元素,以及它DOM节点内所有匹配的元素。

例子如下:

<style>    form {        border: 1px solid;        color: gray;        padding: 4px;    }    form:focus-within {        background: #ff8;        color: black;    }    input {        margin: 4px;    }</style>

效果如下:

image

时间尺寸伪类(Time-dimensional Pseudo-classes)

:current && :past && :future

这个伪类选择器会选择HTML5<video>的语言渲染以及播放过程中的时间维度相对元素。所有相关的选择器都像:matches()。这几个伪类选择器的区别在于:past会选择:current所选的元素之前的所有节点。所以,:future就是指之后的所有节点了。

例子如下:

/* Current */:current(p, span) {   background-color: yellow;}/* Past */:past,/* Future */:future {   display: none;}

兼容性如下:

目前没有任何浏览器支持

输入伪类(The Input Pseudo-classes)

:read-only:read-write

:read-only伪类选择器表示当前元素是用户不可修改的。

:read-write伪类选择器表示当前元素是用户可修改的。这个伪类选择器可以使用在一个可输入的元素或 contenteditable 元素(HTML5 属性)。

例子如下:

<style>    :read-only {      font-size: 20px;      color: green;    }    :read-write {      border: 1px solid orange;      font-size: 18px;    }</style><input type="text" placeholder='text here'><input type="tel" placeholder='number here'><select>      <option>1</option>      <option>2</option></select>

效果如下:

image

兼容性如下:

image

:placeholder-shown

:placeholder-shown 伪类 在 <input><textarea> 元素显示 placeholder text 时生效。

例子如下:

<style>    input {        border: 2px solid black;        padding: 3px;    }    input:placeholder-shown {        border-color: silver;    }</style><input placeholder="Type something here!">

效果如下:

image

兼容性如下:

image

:default

:default 伪类选择器 表示一组相关元素中的默认表单元素。

该选择器可以在 <button>, <input type="checkbox">, <input type="radio">, 以及 <option> 上使用。

例子如下:

<style>    input:default {       box-shadow: 0 0 2px 1px coral;    }    input:default + label {       color: coral;    }</style><input type="radio" name="season" id="spring"><label for="spring">Spring</label><input type="radio" name="season" id="summer" checked><label for="summer">Summer</label><input type="radio" name="season" id="fall"><label for="fall">Fall</label><input type="radio" name="season" id="winter"><label for="winter">Winter</label>

效果如下:

image

兼容性如下:

image

:indeterminate

:indeterminate 伪类选择器表示状态不确定的表单元素。

它支持:

  • <input type="checkbox"> 元素,其 indeterminate 属性被JavaScript设置为 true
  • <input type="radio"> 元素, 表单中拥有相同 name值的所有单选按钮都未被选中时。
  • 处于不确定状态的 <progress> 元素

例子如下:

<style>    input, span {        background: red;    }    :indeterminate, :indeterminate + label {        background: lime;    }    progress {       margin: 4px;    }    progress:indeterminate {          opacity: 0.5;          background-color: lightgray;          box-shadow: 0 0 2px 1px red;    }</style><div>    <input type="checkbox" id="checkbox">    <label for="checkbox">Background should be green</label></div><br /><div>    <input type="radio" id="radio">    <label for="radio">Background should be green</label></div><br /><progress></progress><script>    'use strict'    const inputs = document.querySelectorAll('input')    inputs.forEach(input => {        input.indeterminate = true    })</script>

效果如下:

image

兼容性如下:

image

:valid:invalid

判断有效性的伪类选择器(:valid:invalid)匹配有效或无效,<input><form>元素。

:valid伪类选择器表示值通过验证的<input>,这告诉用户他们的输入是有效的。

:invalid伪类选择器表示值不通过通过验证的<input>,这告诉用户他们的输入是无效的。

例子如下:

<style>    input:valid {        outline: 1px solid green;    }    input:invalid {        outline: 1px solid red;    }</style>输入文字:<input type="text" pattern="[\w]+" required /><br />输入电话号码:<input type="tel" pattern="[0-9]+" required />

效果如下:

image

兼容性如下:

image

:in-range:out-of-range

如果一个时间或数字<input>具有maxmin属性,那么:in-range会匹配到输入值在指定范围内的<input>:out-of-input则匹配输入值不在指定范围的<input>。如果没有规定范围,则都不匹配。

例子如下:

<style>    li {        list-style: none;        margin-bottom: 1em;    }    input {        border: 1px solid black;    }    input:in-range {        background-color: rgba(0, 255, 0, 0.25);    }    input:out-of-range {        background-color: rgba(255, 0, 0, 0.25);        border: 2px solid red;    }    input:in-range + label::after {        content: 'okay.';    }    input:out-of-range + label::after {        content: 'out of range!';    }</style><form action="" id="form1">    <ul>Values between 1 and 10 are valid.        <li>            <input id="value1" name="value1" type="number" placeholder="1 to 10" min="1" max="10" value="12">            <label for="value1">Your value is </label>        </li>    </ul></form>

效果如下:

image

兼容性如下:

image

:required:optional

伪类选择器:required:optional匹配了<input><select>, 或 <textarea>元素。

:required表示“必填”

:optional表示“可选”

例子如下:

<style>    input:required {        border: 1px solid orange;    }    input:optional {        border: 1px solid green;    }</style>必填的:<input type="text" required><br />可选的:<input type="text">

效果如下:

image

兼容性如下:

image

:required 的兼容性在上面有。

:blank

:blank 伪类选择器 用于匹配如下节点:

  1. 没有子节点;
  2. 仅有空的文本节点;
  3. 仅有空白符的文本节点。

有点类似于:empty,但是比:empty宽松,目前还是没有任何一款浏览器支持。

:user-invalid

:user-invalid伪类选择器匹配输入错误的元素。不过跟其它的输入伪类不同的是,它仅匹配用户输入时的错误,而不是静默状态下的错误,这样就会比较人性化,可惜,目前还是没有任何一款浏览器支持。

树型伪类(Tree-Structural pseudo-classes)

:nth-child:nth-last-child

:nth-child:nth-last-child并不是 Level 4 才推出的伪类选择器,但是在 Level 4 里 新增了在元素组里匹配的功能。

语法如下::nth-child/nth-last-child(An + B [of S] ?)

例子如下:

:nth-child(-n+3 of li.important)

上面的例子通过传递选择器参数,选择与之匹配的第n个元素,这里表示li.important中前三个子元素。

它跟以下规则不同:

li.important:nth-child(-n+3)

这里表示的时候如意前三个子元素刚才是li.important时才能被选择得到。

兼容性如下:

image

(鱼头注:牛皮,Safari居然弯道超车了,不过别的浏览器不支持,也没啥用...)

网格选择器(Grid-Structural Selectors)

||

|| 组合器选择属于某个表格行的节点。

例子如下:

<style>    col.selected || td {          background: gray;          color: white;          font-weight: bold;    }</style><table border="1">      <colgroup>            <col span="2"/>            <col class="selected"/>      </colgroup>      <tbody>            <tr>                  <td>A                  <td>B                  <td>C            </tr>            <tr>                  <td colspan="2">D</td>                  <td>E</td>            </tr>            <tr>                  <td>F</td>                  <td colspan="2">G</td>            </tr>      </tbody></table>

上面的例子可以使C,E 与 G单元格变灰。

很可惜,目前还是没有任何浏览器给予支持。

:nth-col():nth-last-col()

伪类选择器:nth-col():nth-last-col()表示选择正向或反向的表格行的节点。

语法和:nth-child:nth-last-child类似,只不过它是选择表格内的元素。

目前还是没有任何浏览器支持。

最后

总结

以上便是CSS选择器 Level 4 里新出的所有选择器,其实都是非常有用的,虽然有些选择器的浏览器支持度并不乐观的。

希望各大浏览器厂商可以赶快增加对它们的支持吧。

参考资料

  1. can i use
  2. MDN
  3. Selectors Level 4 W3C Working Draft

来源:公众号-鱼头的Web海洋
作者:陈大鱼头
github:KRISACHAN

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,192评论 6 511
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,858评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,517评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,148评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,162评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,905评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,537评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,439评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,956评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,083评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,218评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,899评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,565评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,093评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,201评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,539评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,215评论 2 358