CSS选择器及其优先级

为了方便记忆,我将 css 选择器分为6大类:基本选择器、属性选择器、关系选择器、伪元素选择器、伪类选择器。其实对于选择器的种类我们不必死记硬背,用多了自然就会记住了。本文记录了大部分常用的选择器,更加直观详细的选择器表格可查看:CSS 选择器 | 菜鸟教程 或者 w3school-CSS 选择器参考手册

基本选择器

通配符选择器(*)

通配符选择器(*) 用于选择所有的元素。示例代码如下:

css 复制代码
/* 将所有元素的 padding 和 margin 都设置为 0 */
* {
    padding: 0;
    margin: 0;
}

ID选择器(#id)

ID选择器# 开头,后面紧接着元素的 id。下面示例代码用于设置 id 为 app 的元素的样式:

css 复制代码
#app {
    color: black;
    font-size: 14px;
}

类名选择器(.class)

类名选择器 又叫做 class选择器 ,以 . 开头,后面紧接着元素的 class。下面示例代码用于设置 class 为 content 的元素的样式:

css 复制代码
.content {
    min-width: 100px;
    min-height: 100px;
    border-radius: 4px;
    background-color: #fff;
}

标签选择器/元素选择器(div)

标签选择器 又叫做 元素选择器 ,命名格式为标签名(元素名),例如:pdiv。下面示例代码用于设置所有的 P 元素的样式:

css 复制代码
p {
    margin: 1em 0;
    text-indent: 2em;
}

属性选择器

接下来的几个小节都是基于下面代码进行测试的(假设每个小节的测试都是独立的):

html 复制代码
<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>CSS属性选择器测试</title>
    <link rel="stylesheet" href="./style.css">
</head>
<body>
    <div data-title="true">《关雎》</div>
    <div data="aa">关关雎鸠,在河之洲。窈窕淑女,君子好逑。</div>
    <div data="aa bb">参差荇菜,左右流之。窈窕淑女,寤寐求之。</div>
    <div data="aa-bb">求之不得,寤寐思服。悠哉悠哉,辗转反侧。</div>
    <div data="aabb">参差荇菜,左右采之。窈窕淑女,琴瑟友之。</div>
    <div data="bbaacc">参差荇菜,左右芼之。窈窕淑女,钟鼓乐之。</div>
</body>
</html>

为了让渲染出来的效果好看一点,已为上面代码设计了基础样式:

[attribute]

[data-title] 这就是一个属性选择器,用于选择 含有 data-title 属性 的元素。下面是使用该选择器的示例代码:

css 复制代码
/* 将含有 data-title 属性的元素的字体颜色设置为红色 */
[data-title] {
    color: red;
}

页面效果如下图绿色矩形内部所示:

[attribute=value]

[data="aa"] 这也是一个属性选择器(最好加上双引号"",因为如果不加上双引号""可能会出现其他异常情况,假如aa换为数字且不加双引号的话,就会导致无法正确匹配对应的元素),用于选择 data 属性为 aa 的元素。下面是使用该选择器的示例代码:

css 复制代码
/* 将 data 属性值为 aa 的元素的字体颜色设置为粉红色 */
[data="aa"] {
    color: pink;
}

页面效果如下图绿色矩形内部所示:

[attribute~=value]

[data~=aa] 这也是一个属性选择器,选择 data 属性含有 aa 属性值的元素,这里的属性值指的是由空格分割的多个值。下面是使用该选择器的示例代码:

css 复制代码
/* 将 data 属性含有 aa 属性值的元素的字体颜色设置为蓝色 */
[data~="aa"] {
    color: blue;
}

页面效果如下图绿色矩形内部所示:

[attribute|=value]

[data|="aa"] 也是一个属性选择器,用于选择 data 属性值以 aa 值开头的元素,aa 必须是完整的单词,多个单词可以用分割线 - 隔开(空格、下划线等都不行,必须是中横线)。下面是使用该选择器的示例代码:

css 复制代码
[data|="aa"] {
    color: orange;
}

页面效果如下图绿色矩形内部所示:

[attribute^=value]

[data^="aa"] 也是一个属性选择器,用于选择 data 属性值以 aa 字符开头的元素。和 [data|="aa"] 不同的是,这里的 aa 不必是一个完整的单词,可以是单词的前缀,相当于 js 的 startsWith() 方法。下面是使用该选择器的示例代码:

css 复制代码
[data^="aa"] {
    color: orchid;
}

页面效果如下图绿色矩形内部所示:

[attribute$=value]

[data$="aa"] 也是一个属性选择器,用于选择 data 属性值以 aa 字符结束的元素。与 [data^="aa"] 相反,[data$="aa"] 相当于 js 的 String.endsWith() 方法。下面是使用该选择器的示例代码:

css 复制代码
[data$="aa"] {
    color: greenyellow;
}

页面效果如下图绿色矩形内部所示:

[attribute*=value]

[data*="aa"] 也是一个属性选择器,用于选择 data 属性值含有 aa 字符的所有元素。相当于 js 的 String.includes() 方法。下面是使用该选择器的示例代码:

css 复制代码
[data*="aa"] {
    color: brown;
}

页面效果如下图绿色矩形内部所示:

伪元素选择器

伪元素主要用于指定某些元素的特定部分 ,以表示无法用 HTML 语义表达的实体。与此不同,伪类主要用于区分元素的不同状态或行为 。通常情况下,伪元素前面是 ::,包含两个英文冒号;而伪类前面只有一个英文冒号 :。然而,不能单纯通过这个属性来判断是伪元素还是伪类,因为在 CSS2 中,伪元素和伪类都使用单个冒号,在 CSS3 中,为了区分伪元素和伪类,引入了双冒号 :: 的表示法。不过,浏览器仍然接受由 CSS2 引入的单冒号 : 的写法。

::before (:before)

::before 用于在某个元素的前面插入内容,插入的内容用 content 声明。

css 复制代码
.content-item::before {
    content: 'A';
}

上述代码表示在所有具有类名为 content-item 的元素前面插入一个符号 A

需要注意的是,部分元素不支持设置 beforeafter 伪元素:

表单元素:<input><textarea><select><option>

图像元素:<img><svg>

媒体元素:<video><audio>

其他元素:<canvas><iframe><br>

::after (:after)

::before 相反, ::after 选择器用于在某个元素的后面插入内容,插入的内容用 content 声明。

css 复制代码
.content-item::after {
    content: 'B';
}

上述代码表示在所有具有类名为 content-item 的元素后面插入一个符号 B

::first-line (:first-line)

::first-line 用于选择某个块级元素的第一行。

::first-line 只能在块级元素中使用,即 ::first-line 伪元素 只在display属性值为 block, inline-block, table-cell, list-item 或者 table-caption的元素上才起作用。具体可查看MDN

css 复制代码
/* 设置多行文本框 textarea 第一行文本的样式 */
textarea::first-line {
    font-size: 1.3em;
    font-weight: 600;
    margin-bottom: 8px;
}

::first-letter (:first-letter)

::first-letter 用于选择某个块级元素的的第一个文字,并且文字所处的行之前没有其他内容(如图片和内联的表格)。

::first-letter`` 只能在块级元素中使用,即 ::first-letter` 伪元素 只在display属性值为 block, inline-block, table-cell, list-item 或者 table-caption的元素上才起作用。具体可查看MDN

css 复制代码
/* 设置 p 元素的第一个字符的样式 */
p::first-letter {
    color: #000;
    font-weight: 600;
}

::selection

::selection 用于选择用户已选取的部分,即页面高亮的部分。

css 复制代码
/* 设置选中状态的字体颜色和背景 */
::selection {
    color: greenyellow;
    background-color: orange;
}

只有一小部分 CSS 属性可以用于::selection 选择器:

  • color
  • background-color
  • cursor
  • caret-color
  • outline and its longhands
  • text-decoration and its associated properties
  • text-emphasis-color (en-US)
  • text-shadow

::placeholder

placeholder 通常用作表单元素的占位文本,因此 ::placeholder 用来设置占位文本的样式。

css 复制代码
/* 设置输入框占位文本的字体颜色 */
input::placeholder {
  color: blue;
}

::marker

::marker 用于选中列表中标记的元素。它作用在任何设置了 display: list-item 的元素或伪元素上。

在将 ::marker 作为选择器的规则中,只能使用以下 CSS 属性:

  • 所有的字体属性(font-size、font-weight、text-align等)
  • white-space 属性
  • color 属性
  • text-combine-upright (en-US)、unicode-bidi 和 direction 属性
  • content 属性
  • 所有的 animation 和 transition 属性

滚动条相关的伪元素

滚动条相关的伪元素属于非标转规范,firefox 就不支持设置滚动条样式。

滚动条由多个伪元素共同构成,它们的对应关系如下图所示:

  • ::-webkit-scrollbar ------ 整个滚动条。
    • ::-webkit-scrollbar 用于选中整个滚动条。该伪类尽量不要单独设置,要设置该伪类就需要在伪类 ::-webkit-scrollbar-thumb 中设置滚动条滑块的背景颜色,否则滚动条的滑块就会变透明。
  • ::-webkit-scrollbar-button ------ 滚动条上的按钮(上下箭头)。
  • ::-webkit-scrollbar-thumb ------ 滚动条上的滚动滑块。
  • ::-webkit-scrollbar-track ------ 滚动条轨道(下图浅蓝色部分)。
  • ::-webkit-scrollbar-track-piece ------ 滚动条没有滑块的轨道部分。
    • ::-webkit-scrollbar-track-piece:start ------ 滚动条没有滑块的轨道部分,滑块的前面(横向滚动条滑块左边、纵向滚动条滑块上面)。
    • ::-webkit-scrollbar-track-piece:end ------ 滚动条没有滑块的轨道部分,滑块的后面(横向滚动条滑块右边、纵向滚动条滑块下面)
  • ::-webkit-scrollbar-corner ------ 当同时有垂直滚动条和水平滚动条时交汇的部分。通常是元素的右下角。
css 复制代码
/* 修饰整个滚动条 */
::-webkit-scrollbar {
    /* 纵向(竖向)滚动条的宽度 */
    width: 20px;
    /* 横向滚动条的高度 */
    height: 15px;
}
/* 滚动条上的滚动滑块,即鼠标可以拖动的那个小块 */
::-webkit-scrollbar-thumb {
    background: orangered;
    border-radius: 10px;
}
/* 滚动条的箭头按钮 */
::-webkit-scrollbar-button {
    /* 横向滚动条箭头按钮的宽度 */
    width: 10px;
    /* 纵向(竖向)滚动条箭头按钮的高度 */
    height: 20px;
    /* 按钮的背景颜色 */
    background-color: green;
}
/* 滚动条轨道 */
::-webkit-scrollbar-track {
    background-color: powderblue;
}
/* 滚动条轨道中滑块前 */
::-webkit-scrollbar-track-piece:start {
    background-color: purple;
}
/* 滚动条轨道中滑块后 */
::-webkit-scrollbar-track-piece:end {
    background-color: blue;
}
/* 当同时有垂直滚动条和水平滚动条时交汇的部分。 */
::-webkit-scrollbar-corner {
    background-color: black;
}

伪类选择器

伪元素主要用于指定某些元素的特定部分,伪类主要是用来区分元素的不同状态或者行为。

:root

选中文档的根元素。对于 HTML 来说,:root 表示 <html> 元素,除了优先级更高之外,与 <html> 选择器相同。在声明全局 CSS 变量时 :root 会很有用:

css 复制代码
:root {
    --background-color: #fff;
}

选中未访问过的链接标签,一般作用于带有 herf 属性的 <a> 标签和 <area> 标签。

css 复制代码
a:link {
    color: purple;
}

:visited

选中已访问过的链接元素,只作用于带有 herf 属性的 <a> 标签和 <area> 标签。

:visited 和未访问的 :link 伪类定义的样式可以被任何后续的用户动作伪类( :hover:active)覆盖,只要它们的特殊性至少相等。为了适当地样式化链接,将 :visited 规则放置在 :link 规则之后但在 :hover 和 :active 规则之前,按照 LVHA 顺序定义: :link --- :visited --- :hover --- :active:visited 伪类和 :link 伪类是互斥的。

css 复制代码
a:visited {
    color: cyan;
}

:hover

用于设置鼠标悬停在某个元素时候的样式。

:hover 伪类定义的样式将被任何后续的链接相关伪类(:link:visited:active)覆盖,这些伪类的特殊性至少相等。为了适当地为链接设置样式,应该在 :link 和 :visited 规则之后,:active 规则之前放置 :hover 规则,即按照 **LVHA** 定义的顺序::link--->:visited--->:hover--->:active`。

css 复制代码
a:hover {
    color: red;
}

:active

匹配被用户激活的元素,用于设置鼠标点击中这个状态的样式。(用户按下按键和松开按键之间的时间)

设置 CSS 样式时,应该按照 LVHA 定义的顺序::link ---> :visited ---> :hover ---> :active

css 复制代码
a:active {
    color: yellowgreen;
}

:focus

选中获得焦点的元素,一般作用于表单元素和 tabindex="0" 的元素(当用户点击或轻触一个元素或使用键盘的 Tab 键选择它时,它会被触发)。

css 复制代码
input:focus {
    background-color: tan;
}

:target

表示一个唯一的元素(目标元素),其 id 与当前 URL 片段匹配。

假设现有元素和样式如下:

html 复制代码
<div id="test">床前明月光</div>
css 复制代码
:target {
  color: red;
}

当页面 URL 的 hash 为 #test 时,即页面的 location.hash === '#test' 时,id 为 test 的元素就会红色高亮。

:indeterminate

表示任意的状态不确定的表单元素 此选择器针对下面元素:

  • <input type="checkbox"> 元素,其 indeterminate 属性被 JavaScript 设置为 true 时。
  • <input type="radio"> 元素,当表单中具有相同名称值的所有单选按钮均未被选中时。
  • 处于不确定状态的 <progress> 元素(<progress> 元素未设置 value 值)
css 复制代码
progress:indeterminate {
    box-shadow: 0 0 3px 3px red;
}

:lang(language)

:lang 选择器用于选取带有以指定值开头的 lang 属性的元素。

该值必须是整个单词,即可是单独的,比如 lang="en",也可后跟连接符,比如 lang="en-us"

:fullscreen

匹配当前处于全屏模式(像F11 这种全屏模式,要通过js设置)的所有元素。如果有多个元素被放置在全屏模式下,则此选择器将匹配所有这些元素。

:empty

用于选择不包含任何子元素的元素。子元素可以是元素节点或文本(包括空格)。但是注释、处理指令和 CSS content 不会影响元素是否被认定为空。

css 复制代码
div:empty {
    background-color: orange;
}

:not(selector)

用来匹配不符合一组选择器的元素(除了括号内中选择器匹配的元素之外的其他元素)。由于它的作用是防止特定的元素被选中,它也被称为反选伪类。

css 复制代码
button:not(.disabled) {
    cursor: pointer;
}

:not() 的参数是不可容错选择器列表的,括号里面可以用 :is() 或者 :where() 选择器增加容错性。关于 可容错性选择器 后面的小节中有示例代码及说明。

:not() 的优先级由括号内的优先级最高的选择器决定。:not() 伪类的参数可以接受多个参数,但是整个选择器的优先级是由参数中优先级最高的选择器决定的,也就是说伪类选择器 :not(#app, .content) 的优先级比 div.content 选择器高。

css 复制代码
:not(#app, .content) {
    color: red;
}

div.content {
    color: green;
}

如果 HTML 为:

html 复制代码
<div class="content">静夜思</div>
<div>【唐】李白</div>

该类名为 content 的元素的字体颜色为绿色,而另一个 <div> 的字体颜色为红色。

:is(selector)

:is() 伪类函数以选择器列表作为参数,selector 是一个或者多个(用逗号隔开)选择器,但是伪元素选择器。 :is() 用于选择该列表中任意一个选择器可以选择的元素,这对于以更紧凑的形式编写大型选择器非常有用。

css 复制代码
:is(ol, ul) :is(ol, ul) li {
  color: red;
}

上面样式规则表示所有的 <ol><ul> 标签的第三级 <li> 标签的字体颜色为红色。

:is() 的作用和 :where() 的作用是差不多的,但是 :where() 的优先级永远是 0,而 :is() 的优先级由括号内的优先级最高的选择器决定。:is() 伪类的参数可以接受多个参数,但是整个选择器的优先级是由参数中优先级最高的选择器决定的,也就是说伪类选择器 :is(#app, .content) 的优先级比 div.content 选择器高。

css 复制代码
:is(#app, .content) {
    color: red;
}

div.content {
    color: green;
}

如果 HTML 为:

html 复制代码
<div class="content">静夜思</div>

该类名为 content 的元素的字体颜色为红色。

:is() 是可容错性选择器 ,即 :is() 的参数是一个可容错性的选择器列表。关于 可容错性选择器 后面的小节中有示例代码及说明。

在 CSS 中,当使用选择器列表时,如果任何一个选择器无效,则整个列表将被视为无效。而可容错性选择器则不一样,在可容错选择器中如果一个选择器无法解析,整个选择器列表不会被视为无效,而是会忽略不正确或不支持的选择器,并使用其他的选择器。后面的小节中有示例代码及说明

:is() 选择器的兼容性:

:where(selector)

:is() 选择器一样,:where() 选择器也是用于选择该列表中任意一个选择器可以选择的元素。但是不同的是 :where() 不会增加整个选择器的权重,即 :where() 的权重优先级永远是 0, 而 :is() 的权重优先级由括号内的优先级最高的选择器决定。

:where() 也是可容错性选择器。

:where() 选择器的兼容性:

:has(selector)

这个伪类通过把可容错相对选择器列表作为参数,提供了一种针对引用元素选择父元素或者先前的兄弟元素的方法。

css 复制代码
/* 选择下一个兄弟元素是 <h2> 的 <h1> 选择器 */
h1:has(+h2) {
  /* ... */
}

/* 选择直接子元素含有 <p> 元素的 <div> 元素 */
div:has(>p) {
  /* ... */
}

/* 选择后代元素含有 <p> 元素的所有 <div> 元素 */
div:has(p) {
  /* ... */
}

/* 选择后代选择器中含有 <h1> 元素或者 <h2> 元素的 <div> 元素 */
div:has(h1, h2) {
  /* ... */
}

**:has() 也是可容错性选择器。**需要注意的是,:has() 伪类不能被嵌套在另一个 :has() 内,否则内部的 :has() 会被忽略。

:has() 选择器的优先级和 :is():not() 选择器的计算方式一致,都是由括号内部优先级最高的选择器决定。

:has() 选择器的兼容性:

:first-child

表示在一组兄弟元素中的第一个元素。

css 复制代码
/* 选择第一个类名为 content-item 的元素 */
.content-item:first-child {
    /* ... */
}

匹配上面样式规则的元素必须要满足下面所有条件:

  • 该元素必须含有 content-item 类名。
  • 该元素必须是父元素的第一个子元素(第一个子元素前面可以有伪元素或者文本节点)。

:last-child

:first-child 相反,:last-child 表示在一组兄弟元素中的最后一个元素。

css 复制代码
/* 选择最后一个类名为 content-item 的元素 */
.content-item:last-child {
    /* ... */
}

匹配上面样式规则的元素必须要满足下面所有条件:

  • 该元素必须含有 content-item 类名。
  • 该元素必须是父元素的最后一个子元素(最后一个子元素后面可以有伪元素或者文本节点)。

:first-of-type

选择父元素的第一个同类型的元素。和 :first-child 伪类不同的是,:first-of-type 伪类匹配的元素不要求一定是父元素第一个子元素。

css 复制代码
.content-item:first-of-type {
    /* ... */
}

匹配上面样式规则的元素必须要满足下面所有条件:

  • 该元素必须含有 content-item 类名。
  • 该元素对应的标签类型是其父元素的第一个同类型标签。

如果一个元素的父元素两个 <div> 子元素,第一个 <div> 子元素没有 content-item 类名,第二个子元素有 content-item 类名,则该元素的第一个和第二个子元素都不满足条件,因为 content-item 类名对应的元素类型是 <div>,而 <div> 不是其父元素的第一个子元素。

假设现有以下 DOM 结构:

html 复制代码
<section>
    <h3>《静夜思》</h3>
    <small class="content-item">【唐】李白</small>
    <div>床前明月光,</div>
    <div  class="content-item">疑是地上霜。</div>
    <p  class="content-item">举头望明月,</div>
    <p>低头思故乡。</div>
</section>

样式规则一:

css 复制代码
section :first-of-type {
    color: red;
}

当上面 DOM 结构使用样式规则一时:

样式规则二:

css 复制代码
section .content-item:first-of-type {
    color: red;
}

当上面 DOM 结构使用样式规则二时:

之所以 疑是地上霜。 不高亮是因为在这里 content-item 类名对应的元素类型是 <div>,而 <div> 不是其父元素 <section> 的第一个同类型子元素,该句之前还有一句 床前明月光, 也是 <div> 类型的。

:last-of-type

选择父元素的最后一个同类型的元素。和 :last-child 伪类不同的是,:last-of-type 伪类匹配的元素不要求一定是父元素最后一个子元素。

css 复制代码
/* 选择最后一个类名为 content-item 的元素 */
.content-item:first-of-type {
    /* ... */
}

假设现有以下 DOM 结构:

html 复制代码
<section>
    <h3>《静夜思》</h3>
    <small class="content-item">【唐】李白</small>
    <div>床前明月光,</div>
    <div class="content-item">疑是地上霜。</div>
    <p class="content-item">举头望明月,</div>
    <p>低头思故乡。</div>
</section>

样式规则一:

css 复制代码
section :first-of-type {
    background-color: yellow;
}

当上面 DOM 结构使用样式规则一时:

样式规则二:

css 复制代码
section .content-item:last-of-type {
    background-color: yellow;
}

当上面 DOM 结构使用样式规则二时:

:nth-child(n)

:nth-child(n) 伪类选择兄弟元素的第 n 个元素。n 可以是任何正整数,也可以是表达式。

  • n:nth-child(2) :表示选择其父元素的第 2 个元素。
  • :nth-child(n):表示选择其父元素的所有子元素。
  • :nth-child(2n) :表示选择其父元素的所有偶数位的子元素,相当于 :nth-child(even)
  • :nth-child(2n + 1) :表示选择其父元素的所有奇数位的子元素,相当于 :nth-child(odd)
  • :nth-child(even) :表示选择其父元素的所有偶数位的子元素,可以用 :nth-child(2n) 代替。
  • :nth-child(odd) :表示选择其父元素的所有奇数位的子元素,可以用 :nth-child(2n + 1) 代替。
  • :nth-child(-n+3):表示选择其父元素的前三位的所有子元素。
css 复制代码

:nth-last-child(n)

:nth-child(n) 伪类相反,:nth-last-child(n) 伪类表示选择兄弟元素的倒数第 n 个元素。关于 n 的说明可以看 :nth-child(n) 小节。

css 复制代码
/* 选择父元素中子元素为第三的且类名为 .content-item 的元素 */
.content-item:nth-child(3) {
    /* ... */
}

/* 选择父元素中第三个子元素 */
:nth-child(3) {
    /* ... */
}

:nth-of-type(n)

表示选择相同类型(标签名称)的兄弟元素中的第 n 个元素。关于 n 的说明可以看 :nth-child(n) 小节。

css 复制代码
section :nth-of-type(2) {
    color: red;
}

section span:nth-of-type(3) {
    background-color: yellow;
}
html 复制代码
<section>
    <h3><span>静</span><span>夜</span><span>思</span></h3>
    <small class="content-item">【唐】李白</small>
    <div>床前明月光,</div>
    <div class="content-item">疑是地上霜。</div>
    <p class="content-item">举头望明月,</div>
    <p>低头思故乡。</div>
</section>

:nth-last-of-type(n)

表示选择相同类型(标签名称)的兄弟元素中的倒数第 n 个元素。关于 n 的说明可以看 :nth-child(n) 小节。

css 复制代码
/* 选择父元素的倒数第三个 p 元素 */
p:nth-of-type(3) {
    /* ... */
}

:only-child

:only-child 伪类表示没有任何兄弟元素的元素。这与 :first-child:last-child:nth-child(1):nth-last-child(1) 相同,但前者具有更小的权重性。

css 复制代码
/* 选中没有任何兄弟元素且类名为 content-item 的元素 */
.content-item:only-child {
    /* ... */
}

匹配上面样式规则的元素必须满足:

  • 类名含有 content-item
  • 其父元素只有它一个元素,没有其他元素(可以含有伪元素或者文本节点)。

:only-of-type

代表了任意一个元素,这个元素没有其他相同类型的兄弟元素。

css 复制代码
.content-item:only-of-type {
    /* ... */
}

匹配上面样式规则的元素必须满足:

  • 类名含有 content-item
  • 其父元素只含有一个类名为 content-item 的元素,可以含有多个其他类名的元素。

表单元素相关伪类

:disabled

用于选择被禁用元素,通常用于表单元素,其他的普通元素一般使用属性选择器 [disabled]

:enabled

:disabled 相反,:enabled 用于选择未被禁用元素,通常用于表单元素。

:checked

用于选择所有被选中的元素,一般作用于被选中的 <input type="radio"><input type="checkbox"> 或者 <select> 元素中被选中的 <option> 元素。

:default

用于选择设置为默认值的表单元素,可用于 <button><radio><checkbox><option> 元素

:required

用于选择设置了 required 属性的 <input><select><textarea> 元素。

:optional

:required 相反,表示任何未设置 required 属性的 <input><select><textarea> 元素。

:read-only

用于选择不可被用户编辑的状态的表单元素(如设置了 readonly 属性的文本输入框),火狐浏览器需要加前缀(:-moz-read-only)。

:read-write

:read-only 相反,用于选择可被用户编辑的状态的表单元素,火狐浏览器需要加前缀(:-moz-read-write)。

:vaild

用于选择任何通过验证的 <form><fieldset><input> 或其他表单元素。

:invaild

:vaild 相反,用来选择任何未通过验证的 <form><fieldset><input> 或其他表单元素。

:in-range

代表一个 <input> 元素,其当前值处于属性 minmax 限定的范围之内(空状态,即未填写任何内容也是满足条件的)。

:out-of-range

:in-range 相反,表示一个 <input> 元素,其当前值处于属性 minmax 限定的范围外。

常见的组合选择器

后代选择器(selectorA selectorB)

后代选择器可以选择作为某元素后代的元素,也可以是两个以上的选择器,多个选择器之间用空格分隔。

css 复制代码
/* 选择 <ol> 元素内部所有的 <li> 元素 */
ol li {
    color: red;
}

子元素选择器(selectorA > selectorB)

与后代选择器相比,子元素选择器(Child selectors)只能选择作为某元素子元素的元素(中间的空格可以不要)。

css 复制代码
/* 选择直系父元素为 <div> 元素的 <p> 元素  */
div > p {
    color: red;
}

相邻兄弟选择器(selectorA + selectorB)

相邻兄弟选择器(Adjacent sibling selector)可选择紧接在另一元素后的元素,且二者有相同父元素(中间的空格可以不要)。

css 复制代码
/* 选择上一个选择器为 <div> 元素的 <p> 元素 */
div + p {
    color: red;
}

selectorA ~ selectorB

这个选择器比较难解释,直接看例子会比较容易理解(中间的空格可以不要):

css 复制代码
/* 将 <div> 元素后面的 <p> 元素的字体颜色设置为红色 */
div ~ p {
    color: red;
}

匹配上面样式规则的元素必须要满足下面所有条件:

  • <p> 元素排在 <div> 元素后面(不一定要紧接着)。
  • <p> 元素和 <div> 元素是兄弟元素,具有同一个父元素。

selectorAselectorB

匹配同时满足两个规则 selectorAselectorB 的元素,可以是两个以上的选择器,多个选择器之间不需要分隔。

css 复制代码
/* 类名为 app 的 <div> 元素 */
div.app {
    /*  */
}

/* 类名含有 app 也含有 test 的元素 */
.app.test {
    /*  */
}

selectorA, selectorB

用于同时选取多个元素,多个选择器用逗号分割(逗号后面的空格可以不要)。

css 复制代码
/* 同时设置 <div> 元素和 <p> 元素的字体大小 */
div, p {
    font-size: 16px;
}

可容错性选择器

在 CSS 中,当使用选择器列表时,如果任何一个选择器无效,则整个列表将被视为无效。而可容错性选择器则不一样,在可容错选择器中如果一个选择器无法解析,整个选择器列表不会被视为无效,而是会忽略不正确或不支持的选择器,并使用其他的选择器。

以下例子来源于 MDN

css 复制代码
:is(:valid, :unsupported) {
  /* ... */
}

即使在不支持 :unsupported 的浏览器中,仍将正确解析 :valid,而:

css 复制代码
:valid,
:unsupported {
  /* ... */
}

在不支持 :unsupported 浏览器中即使它们支持 :valid,仍将忽略。

CSS 选择器优先级

为了方便记忆可以简单理解样式规则优先级排序如下:important 标识符 》内联样式 》id选择器 》类名选择器 = 伪类选择器 = 属性选择器 》元素选择器 = 伪元素选择器 》通配符选择器。但是这是有例外的,例如伪类选择器 :is():not() 在优先级计算中是不应该看做伪类的,这二者的优先级是由其参数中的选择器决定的;再例如 :where() 伪类选择器在优先级计算中也是不应该看做伪类的,因为其优先级永远为 0,无论其参数中的选择器优先级多高。

对于选择器优先级(Calculating a selector's specificity),可以将其划分为(A, B, C)三个部分:

  • A 用于指代 ID 选择器的数量;
  • B 用于指代类选择器、属性选择器和伪类的数量;
  • C 用于指代标签选择器和伪元素选择器的数量;
  • 忽略通用选择器 * 的优先级

在 (A, B, C) 中,即使 B > A,其优先级也是低于 A 的,而且无论 B 是多少,也不会向前进位。请看下面例子:

选择器 优先级
* a=0 b=0 c=0
li a=0 b=0 c=1
ui li a=0 b=0 c=2
ul ol+li a=0 b=0 c=3
h1 + *[rel=up] a=0 b=1 c=1
ul ol li.red a=0 b=1 c=3
li.red.level a=0 b=2 c=1
#app a=1 b=0 c=0
#app:not(div) a=1 b=0 c=1
.foo :is(.bar, #baz) a=1 b=1 c=0
[id="app"] a=0 b=1 c=0

表格中出现了 [id="app"],这是一个属性选择器,即使该属性选择器使用了 id 属性,但是它只能是作为属性选择器计算优先级。

上面只提到了选择器的优先级排序,但是对于一个样式规则还存在内联样式和 !important 标识符等情况,这里对于这两种特殊情况进行说明:

  • 内联样式:本小节一开始已经提到过,内联样式的规则优先级是在 ID 选择器前面的。
  • !important!important 是作用在每条样式规则的标识符,例如: color: red !imporatnt;,该标识符可以提升该条规则的优先级,将其优先级提升为超过内联样式。!important 的作用
    • 覆盖内联样式
    • 覆盖优先级高的选择器

需要注意的是,很多资料会说优先级是 10 进制的,其实这个说法是有误的,因为选择器优先级是没有进位的,也就是说即使 100 个 class 选择器,其优先级也没有 1 个 id 选择器高。

相关推荐
dr李四维2 分钟前
iOS构建版本以及Hbuilder打iOS的ipa包全流程
前端·笔记·ios·产品运营·产品经理·xcode
雯0609~24 分钟前
网页F12:缓存的使用(设值、取值、删除)
前端·缓存
℘团子এ27 分钟前
vue3中如何上传文件到腾讯云的桶(cosbrowser)
前端·javascript·腾讯云
学习前端的小z32 分钟前
【前端】深入理解 JavaScript 逻辑运算符的优先级与短路求值机制
开发语言·前端·javascript
彭世瑜1 小时前
ts: TypeScript跳过检查/忽略类型检查
前端·javascript·typescript
FØund4041 小时前
antd form.setFieldsValue问题总结
前端·react.js·typescript·html
Backstroke fish1 小时前
Token刷新机制
前端·javascript·vue.js·typescript·vue
小五Five1 小时前
TypeScript项目中Axios的封装
开发语言·前端·javascript
小曲程序1 小时前
vue3 封装request请求
java·前端·typescript·vue
临枫5411 小时前
Nuxt3封装网络请求 useFetch & $fetch
前端·javascript·vue.js·typescript