Skip to content
On this page

CSS 选择器

  • 用于匹配 HTML 元素。选择器所选择的元素,叫做"选择器的对象"
  • 分类和权重
  • 解析方式和性能
  • 值得关注的选择器

CSS 选择器解析方式

CSS 选择器解析是指浏览器在渲染页面时,如何解析 CSS 选择器以确定哪些元素应该应用 CSS 样式。

  • 在解析选择器时,浏览器按从右到左的顺序进行匹配,以尽早确定是否匹配。
  • 比如,当解析后代选择器 div p 时,浏览器会先找到所有 p 元素,然后再检查它们是否是 div 元素的后代。
  • 如果选择器包含了 ID 或者 class 等属性选择器,则浏览器会先找到拥有该属性的元素。

CSS 选择器性能

CSS 选择器的性能与选择器的复杂度和页面结构有关。选择器越复杂,匹配所需的计算量就越大,因此影响性能的因素有:

  • 选择器的复杂度:选择器中包含的规则越多,匹配所需的计算量就越大。因此,应该尽量避免使用嵌套、通配符、后代选择器等复杂选择器。
  • 文档结构:文档结构越复杂,匹配所需的计算量就越大。如果文档层次结构较深,选择器中的后代选择器会导致匹配的计算量增加。
  • 样式数量:当页面中包含大量的样式规则时,浏览器需要更多的计算来确定哪些样式应该应用于元素。因此,应该尽量避免使用冗余或不必要的样式规则。
  • 缓存:浏览器会缓存已解析的样式规则,以便在后续的页面加载中加快渲染速度。因此,使用相同的选择器多次可以提高性能。

综上所述,为了提高 CSS 选择器的性能,应该尽量避免使用复杂的选择器,优化文档结构,避免冗余或不必要的样式规则,并尽可能使用已缓存的样式规则。

CSS 选择器分类

  • 通用选择器(Universal selector):选择所有元素。(可选)可以将其限制为特定的名称空间或所有名称空间。

    • 语法:* ns|* *|*
    • 例子:* 将匹配文档的所有元素。
  • 元素选择器(Type selector):按照给定的节点名称,选择所有匹配的元素。

    • 语法:elementname
    • 例子:input 匹配任何 <input> 元素。
  • 类选择器(Class selector):按照给定的 class 属性的值,选择所有匹配的元素。

    • 语法.classname
    • 例子.index 匹配任何 class 属性中含有 "index" 类的元素。
  • ID 选择器(ID selector):按照 id 属性选择一个与之匹配的元素。需要注意的是,一个文档中,每个 ID 属性都应当是唯一的。

    • 语法:#idname
    • 例子:#toc 匹配 ID 为 "toc" 的元素。
  • 属性选择器(Attribute selector):按照给定的属性,选择所有匹配的元素。

    • 语法:[attr] [attr=value] [attr~=value] [attr|=value] [attr^=value] [attr$=value] [attr*=value]
    • 例子:[autoplay] 选择所有具有 autoplay 属性的元素(不论这个属性的值是什么)。
  • 选择器列表(Selector list):, 是将不同的选择器组合在一起的方法,它选择所有能被列表中的任意一个选择器选中的节点。

    • 语法A, B
    • 示例div, span 会同时匹配 <div> 元素和 <span> 元素。
  • 后代组合器(Descendant combinator):" "(空格)组合器选择前一个元素的后代节点。

    • 语法:A B
    • 例子:div span 匹配所有位于任意 <div> 元素之内的 <span> 元素。
  • 直接子代组合器(Child combinator):> 组合器选择前一个元素的直接子代的节点。

    • 语法A > B
    • 例子ul > li 匹配直接嵌套在 <ul> 元素内的所有 <li> 元素。
  • 一般兄弟组合器(General sibling combinator):~ 组合器选择兄弟元素,也就是说,后一个节点在前一个节点后面的任意位置,并且共享同一个父节点。

    • 语法A ~ B
    • 例子p ~ span 匹配同一父元素下,<p> 元素后的所有 <span> 元素。
  • 紧邻兄弟组合器(Adjacent sibling combinator):+ 组合器选择相邻元素,即后一个元素紧跟在前一个之后,并且共享同一个父节点。

    • 语法:A + B
    • 例子:h2 + p 会匹配所有紧邻在 <h2> 元素后的 <p> 元素。
  • 列组合器(Column combinator):|| 组合器选择属于某个表格行的节点。

    • 语法: A || B
    • 例子: col || td 会匹配所有 <col> 作用域内的 <td> 元素。
  • 伪类:: 伪选择器支持按照未被包含在文档树中的状态信息来选择元素。

    • 例子:a:visited 匹配所有曾被访问过的 <a> 元素。
  • 伪元素::: 伪选择器用于表示无法用 HTML 语义表达的实体。

    • 例子:p::first-line 匹配所有 <p> 元素的第一行。

选择器权重

  • !important 声明,具有最高优先级,其权重为 999999。

  • 内联样式(通过 style 属性定义的样式),其权重为 1000。

  • ID 选择器 #id{} ,其权重为 100

  • 类选择器、属性选择器、伪类选择器和关系选择器的组合,其权重为 10

  • 元素 伪元素,其权重为 1

  • 其它选择器 (通配符选择器*和继承的样式),其权重为 0

  • 具有相同的选择器权重,则最后定义的规则将覆盖先前定义的规则

选择器权重计算

#id .link a[href] : 结果 111

  • #id +100
  • .link +10
  • a +1
  • [href] +0

#id .link.active:结果 120

  • #id +100
  • .link +10
  • .active +10
html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>basic</title>
    <style>
      #test1 { 
        color: red;
      }
      #test1.test1 {
        color: blue;
      }

      .test2 {
        color: red;
      }
      div.test2 {
        color: blue;
      }

      #test3 {
        color: red;
      }
      .c1.c2.c3.c4.c5.c6.c7.c8.c9.c10.c11 { // 这里类选择器在计算权重时不进位,因为它们之间没有使用空格或其他组合符号分隔
        color: blue;
      }
    </style>
  </head>
  <body class="body" id="body"> 
    <div id="test1" class="test1">test1</div>
    <div class="test2">test2</div>
    <div id="test3" class="c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11">test3</div>
  </body>
</html>
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>basic</title>
    <style>
      #test1 { 
        color: red;
      }
      #test1.test1 {
        color: blue;
      }

      .test2 {
        color: red;
      }
      div.test2 {
        color: blue;
      }

      #test3 {
        color: red;
      }
      .c1.c2.c3.c4.c5.c6.c7.c8.c9.c10.c11 { // 这里类选择器在计算权重时不进位,因为它们之间没有使用空格或其他组合符号分隔
        color: blue;
      }
    </style>
  </head>
  <body class="body" id="body"> 
    <div id="test1" class="test1">test1</div>
    <div class="test2">test2</div>
    <div id="test3" class="c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11">test3</div>
  </body>
</html>
html
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>basic</title>
    <style>
        .test1{ 
            color: red;
        }
        .test1{
            color: blue;
        }

        .test2{
            color: red !important;
        }
        .test2{
            color: blue;
        }

        #test3{
            color: red;
        }
    </style>
</head>
<body class="body" id="body"> 
    <div class="test1">test1</div>
    <div class="test2">test2</div>
    <div id="test3" style="color: blue">
        test3
    </div>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>basic</title>
    <style>
        .test1{ 
            color: red;
        }
        .test1{
            color: blue;
        }

        .test2{
            color: red !important;
        }
        .test2{
            color: blue;
        }

        #test3{
            color: red;
        }
    </style>
</head>
<body class="body" id="body"> 
    <div class="test1">test1</div>
    <div class="test2">test2</div>
    <div id="test3" style="color: blue">
        test3
    </div>
</body>
</html>