# 选择器

# 一、选择器是什么

选择器一览表 (opens new window)

选择器用来指定页面上我们想要样式化的 html 元素,是 css 中获取 html 元素的一种手段。在简介了就提过 css 的基本语法选择器 {样式属性: 值},就是告诉浏览器你的这个页面的那个元素要设置什么样式,所以选择器的学习很重要。

前面使用过简单的选择器,其实选择器完整的形式是这样的:E[foo=val],E 是标签,foo 通常是属性,val 是属性值。例如:div[id="div_Big"]是选择了页面中 id 为"div_Big"的 div 元素。如果选择器写错了(语法错误),那么选择器的这条样式是失效的。

# 二、属性选择器

# 2.1 一般的属性选择器

可以给 html 元素添加属性,比如 id 和 class 等一些自定义属性(别忘了 id 的优先级更高哦),然后就可以通过属性选择器对元素进行样式添加。属性选择器的写法就是[att=val],其中att是属性,val是属性值。对了,别搞混 css 样式属性和 html 元素属性,根本就不是一个的东西。

<html>
  <head>
    <style type="text/css">
      /* id属性(html元素属性),section是值, background-color是css样式属性,yellow是值 */
      [id="section"] {
        background-color: yellow;
      }
    </style>
  </head>
  <body>
    <div id="section">示例文本</div>
  </body>
  <html></html>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 2.2 搭配通配符使用

在使用选择器的使用可以加上~|*^?$等通配

[att~=val]:如果 att 属性的值就是 val或者空格隔开的 val,那么就选择这个属性所在的元素。例如:选择器是[id~=section],那么 id 为"section""section search"的元素都会被选中。

[att|=val]:如果 att 属性的值就是 val或者以 val开头再接一个连字符,那么就选择这个属性所在的元素。例如:选择器是[id|=zh],那么 id 为"zh""zh-xxx"的元素都会被选中。

[att*=val]:如果 att 属性的值中包含val,那么就选择这个属性所在的元素。例如:选择器是[id*=section],那么 id 为"0section123""1section-456"的元素都会被选中。

[att^=val]:如果 att 属性的值开头是 val,那么就选择这个属性所在的元素。例如:选择器是[id^=section],那么 id 为"section12""section-46"的元素都会被选中。

[att$=val]:如果 att 属性的值结尾是 val,那么就选择这个属性所在的元素。例如:选择器是[id$=section],那么 id 为"12section""div_section"的元素都会被选中。如果是-1结尾的记得要在选择器中转义,[id$=\-1]

<html>
  <head>
    <style type="text/css">
      li[class] {
        font-size: 200%;
      }
      li[class="a"] {
        background-color: yellow;
      }
      li[class~="a"] {
        color: red;
      }
      li[class|="zh"] {
        color: green;
      }
    </style>
  </head>
  <body>
    <ul>
      <li>Item 1</li>
      <!--没有样式-->
      <li class="a">Item 2</li>
      <!--黄底红字-->
      <li class="a b">Item 3</li>
      <!--红字-->
      <li class="zh">Item 4</li>
      <!--绿字-->
      <li class="zh-b">Item 5</li>
      <!--绿字-->
    </ul>
  </body>
  <html></html>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

下面的例子是给以/结尾和以html结尾的 a 标签的末尾添加红色文字,给以jpg结尾的添加绿色文字

<html>
  <head>
    <style type="text/css">
      a[href$="\/"]:after,
      a[href$="html"]:after {
        content: "web网页";
        color: red;
      }
      a[href$="jpg"]:after {
        content: "JPEG图像文件";
        color: green;
      }
    </style>
  </head>
  <body>
    <a href="http://css3/">示例文本</a
    ><!--后面添加了红色文字-->
    <a href="http://css3/css3.html">示例文本</a
    ><!--后面添加了红色文字-->
    <a href="photo.jpg">示例文本</a
    ><!--后面添加了绿色文字-->
  </body>
  <html></html>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

# 2.3 大小写敏感

如果想在大小写不敏感的情况下匹配属性值的话,你可以在[]里面的末尾加上i

<html>
  <head>
    <style type="text/css">
      li[class^="a"] {
        background-color: yellow;
      }
      li[class^="a" i] {
        color: red;
      }
    </style>
  </head>
  <body>
    <ul>
      <li class="a">Item 1</li>
      <!--黄底红字-->
      <li class="A">Item 2</li>
      <!--仅红字-->
      <li class="Ab">Item 3</li>
      <!--仅红字-->
    </ul>
  </body>
  <html></html>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# 三、伪类选择器

伪类选择器是用来选择处于特定状态特定结构下的元素,特定状态或结构的名字在 css 中已经定义好了。实际上是对页面上现存的元素进行操作,行为比较像类选择器。伪类是以冒号为开头的,:xxx

# 3.1 常见的结构性伪类

有 4 个常见的结构性伪类选择器:root、not、empty 和 target。

# root

root选取页面的根元素,根元素是指位于页面最顶层结构的元素,一般是整个页面的<html>部分。

<html>
  <head>
    <style type="text/css">
      :root {
        background-color: yellow;
      } /* 整个页面底色是黄色 */
      body {
        background-color: limegreen;
      } /* 而body是绿色 */
    </style>
  </head>
  <body>
    <h2>选择器是什么</h2>
    <p>
      选择器是css中获取页面元素的一种手段,可以将样式与元素直接绑定起来,还可以实现各种复杂的指定,能精简样式表的代码量...
    </p>
  </body>
  <html></html>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# not

not是为了排除元素的某些子元素。

<html>
  <head>
    <style type="text/css">
      body *:not(h2) {
        background-color: yellow;
      } /* body都是黄色但除了h2元素 */
    </style>
  </head>
  <body>
    <h2>选择器是什么</h2>
    <p>
      选择器是css中获取页面元素的一种手段,可以将样式与元素直接绑定起来,还可以实现各种复杂的指定,能精简样式表的代码量...
    </p>
  </body>
  <html></html>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# empty

empty是选取元素中内容为空白的区域或者没有子元素的元素。

<html>
  <head>
    <style type="text/css">
      :empty {
        background-color: yellow;
      }
    </style>
  </head>
  <body>
    <table border="1" cellpadding="0" cellspacing="0">
      <tr>
        <td>A</td>
        <td>B</td>
        <td>C</td>
      </tr>
      <tr>
        <td>D</td>
        <td>E</td>
        <td></td>
      </tr>
      <!--最后一项没有内容,并且背景是黄色的-->
    </table>
  </body>
  <html></html>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

# target

target是选取页面中 URL 目标元素,点击超链接会跳转到 target 元素,然后:target就会起作用。类似于文章中的标题跳转到对应内容。

<html>
  <head>
    <style type="text/css">
      :target {
        background-color: yellow;
      }
    </style>
  </head>
  <body>
    <p id="menu">
      <a href="#text1">示例文字1</a> |<!--点击超链接就会跳转到对应id的元素上-->
      <a href="#text2">示例文字2</a> | <a href="#text3">示例文字3</a> |
    </p>
    <div id="text1">
      <h2>示例文字1</h2>
      <p>...此处略去</p>
    </div>
    <!--跳转到这里后变为黄色-->
    <div id="text2">
      <h2>示例文字2</h2>
      <p>...此处略去</p>
    </div>
    <div id="text3">
      <h2>示例文字3</h2>
      <p>...此处略去</p>
    </div>
  </body>
  <html></html>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

# 3.2 处理子元素

可以对一个父元素中的第一个、最后一个、指定序号、第偶数个、第奇数个子元素进行样式的指定,通用写法子元素名称:xxx-child

# first-child、last-child

first-child对父元素的第一个子元素进行指定样式(其实一般要配合使用才算是第一个子元素,例如ul li:first-child)。

last-child对父元素的最后一个子元素进行指定样式。

<html>
  <head>
    <style type="text/css">
      /*.ul1元素的直接子元素,并且是第一个元素也是Li元素*/
      .ul1 > li:first-child {
        background-color: yellow;
      }
      /*父元素中的最后一个元素并且是Li元素*/
      li:last-child {
        background-color: skyblue;
      }
    </style>
  </head>
  <body>
    <ul class="ul1">
      <li>项目列表1</li>
      <!--黄色,“>”配合first-child可以只改变第一层的第一个li-->
      <li>
        项目列表2
        <ul>
          <li>项目列表2-1</li>
          <!--没有改变-->
          <li>项目列表2-2</li>
          <li>项目列表2-3</li>
          <li>项目列表2-4</li>
          <!--浅蓝色-->
        </ul>
      </li>
      <li>项目列表3</li>
      <li>项目列表4</li>
      <!--浅蓝色,不加“>”限制的话就是所有的最后一项li-->
    </ul>
  </body>
  <html></html>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

# nth-child、nth-last-child

nth-child对父元素的第几个子元素进行指定样式。

nth-last-child对父元素的倒数第几个子元素进行指定样式。

<html>
  <head>
    <style type="text/css">
      .ul1 > li:nth-child(1) {
        background-color: yellow;
      }
      li:nth-last-child(2) {
        background-color: skyblue;
      }
    </style>
  </head>
  <body>
    <ul class="ul1">
      <li>项目列表1</li>
      <!--黄色,“>”配合nth-child可以只改变第一层的第一个li-->
      <li>
        项目列表2
        <ul>
          <li>项目列表2-1</li>
          <!--没有改变-->
          <li>项目列表2-2</li>
          <li>项目列表2-3</li>
          <!--浅蓝色-->
          <li>项目列表2-4</li>
        </ul>
      </li>
      <li>项目列表3</li>
      <!--浅蓝色,不加“>”限制的话就是所有的倒数第二项li-->
      <li>项目列表4</li>
    </ul>
  </body>
  <html></html>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

nth-childnth-last-child还可以对父元素中第奇数个或偶数个子元素使用样式。

<html>
  <head>
    <style type="text/css">
      .ul1 > li:nth-child(odd) {
        background-color: yellow;
      }
      li:nth-child(even) {
        background-color: skyblue;
      }
    </style>
  </head>
  <body>
    <ul class="ul1">
      <li>项目列表1</li>
      <!--黄色,“>”配合first-child可以只改变第一层的奇数项li-->
      <li>
        项目列表2
        <!--浅蓝色-->
        <ul>
          <li>项目列表2-1</li>
          <!--浅蓝色,因为父元素是浅蓝色-->
          <li>项目列表2-2</li>
          <!--浅蓝色-->
          <li>项目列表2-3</li>
          <!--浅蓝色-->
          <li>项目列表2-4</li>
          <!--浅蓝色-->
        </ul>
      </li>
      <li>项目列表3</li>
      <!--黄色,“>”配合first-child可以只改变第一层的奇数项li-->
      <li>项目列表4</li>
      <!--浅蓝色,不加“>”限制的话就是所有的最后一项li-->
    </ul>
  </body>
  <html></html>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

nth-childnth-last-child的使用其实还有个问题,比如p:nth-child(odd),它的意思是父元素的奇数项并且是p元素,而不是父元素的第奇数个p元素,因为父元素的子元素可能是多种类型的元素,这两种选择器就是第几项并且是 xxx 元素,这一点一定要分清楚的。

<html>
  <head>
    <style type="text/css">
      h2:nth-child(odd) {
        background-color: yellow;
      } /*解释起来就是父元素中的奇数项并且是h2元素*/
      h2:nth-child(even) {
        background-color: skyblue;
      } /*解释起来就是父元素中的偶数项并且是h2元素*/
    </style>
  </head>
  <body>
    <h2>文章标题1</h2>
    <!--黄色,父元素奇数项并且是h2元素-->
    <p>文章正文1</p>
    <!--无颜色,父元素偶数项但是是p元素-->
    <h2>文章标题2</h2>
    <!--黄色,父元素奇数项并且是h2元素-->
    <p>文章正文2</p>
    <!--无颜色,父元素偶数项但是是p元素-->
    <h2>文章标题3</h2>
    <!--黄色,父元素奇数项并且是h2元素-->
    <p>文章正文3</p>
    <!--无颜色,父元素偶数项但是是p元素-->
  </body>
  <html></html>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

# nth-of-type、nth-last-of-type

因为nth-childnth-last-child的问题,我们可以选择nth-of-typenth-last-of-type

nth-of-type对父元素里同类型子元素的第几项进行指定样式。

nth-last-of-type对父元素里同类型子元素的倒数第几项进行指定样式。

<html>
  <head>
    <style type="text/css">
      h2:nth-of-type(odd) {
        background-color: yellow;
      }
      h2:nth-of-type(even) {
        background-color: skyblue;
      }
    </style>
  </head>
  <body>
    <h2>文章标题1</h2>
    <!--黄色,父元素里的h2元素奇数项-->
    <p>文章正文1</p>
    <h2>文章标题2</h2>
    <!--浅蓝色,父元素里的h2元偶数项-->
    <p>文章正文2</p>
    <h2>文章标题3</h2>
    <!--黄色,父元素里的h2元素奇数项-->
    <p>文章正文3</p>
  </body>
  <html></html>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

# nth-child 的循环使用

**nth-child(an+b)**可以对父元素里的子元素进行样式的循环使用,特别适合父元素里元素繁多的场景;a 表示每次循环中共包括几种样式,b 表示指定的样式在循环中所处的位置。

<html>
  <head>
    <style type="text/css">
      li:nth-child(4n + 1) {
        background-color: yellow;
      }
      li:nth-child(4n + 2) {
        background-color: limegreen;
      }
      li:nth-child(4n + 3) {
        background-color: red;
      }
      li:nth-child(4n + 4) {
        background-color: white;
      }
    </style>
  </head>
  <body>
    <ul class="ul1">
      <li>项目列表1</li>
      <!--黄色-->
      <li>
        项目列表2
        <!--绿色-->
        <ul>
          <li>项目列表2-1</li>
          <!--黄色-->
          <li>项目列表2-2</li>
          <!--绿色-->
          <li>项目列表2-3</li>
          <!--红色-->
          <li>项目列表2-4</li>
          <!--白色-->
        </ul>
      </li>
      <li>项目列表3</li>
      <!--红色-->
      <li>项目列表4</li>
      <!--白色-->
      <li>项目列表5</li>
      <!--黄色-->
      <li>项目列表6</li>
      <!--绿色-->
      <li>项目列表7</li>
      <!--红色-->
      <li>项目列表8</li>
      <!--白色-->
    </ul>
  </body>
  <html></html>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

# only-child

对父元素里只有一个元素时使用的样式,可以采用子元素:nth-child(1):nth-last-child(1),也可以使用子元素:only-child

<html>
  <head>
    <style type="text/css">
      li:only-child {
        background-color: yellow;
      }
      /*li:nth-child(1):nth-last-child(1) { background-color: yellow; }*/
    </style>
  </head>
  <body>
    <h2>ul列表A</h2>
    <ul>
      <li>列表项目A1</li>
      <!--黄色-->
    </ul>
    <h2>ul列表B</h2>
    <ul>
      <li>列表项目B1</li>
      <!--无色-->
      <li>列表项目B2</li>
      <!--无色-->
      <li>列表项目B3</li>
      <!--无色-->
    </ul>
  </body>
  <html></html>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

# 3.3 状态伪类选择器

状态伪类选择器是对 UI 元素某种状态下的一种伪类选择器,在默认状态下是不起作用的。

# hover、active、focus

hover为鼠标指针悬浮“头顶”的元素指定样式。

active为处于激活状态(例如鼠标按下)的元素指定样式。

focus为已获取焦点的元素指定样式。

<html>
  <head>
    <style type="text/css">
      input[type="text"]:hover {
        background-color: blue;
      }
      input[type="text"]:focus {
        background-color: red;
      }
      input[type="text"]:active {
        background-color: yellow;
      }
    </style>
  </head>
  <body>
    <form>
      <p>姓名:<input type="text" name="name" /></p>
      <!--鼠标悬浮时蓝色,获得焦点时红色,按住时黄色-->
      <p>地址:<input type="text" name="address" /></p>
      <!--鼠标悬浮时蓝色,获得焦点时红色,按住时黄色-->
    </form>
  </body>
  <html></html>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

# enabled、disabled

enabled为处于可用状态下的元素指定样式。

disabled为处于禁用状态下的元素指定样式。

<html>
  <head>
    <script>
      const change = () => {
        const radio = document.getElementById("radio1");
        const text = document.getElementById("text");
        text.disabled = radio.checked ? "" : "disabled";
      };
    </script>
    <style type="text/css">
      input[type="text"]:enabled {
        background-color: yellow;
      }
      input[type="text"]:disabled {
        background-color: red;
      }
    </style>
  </head>
  <body>
    <form>
      <input type="radio" id="radio1" name="radio" onchange="change()" />可用<br />
      <input type="radio" id="radio2" name="radio" onchange="change()" checked />不可用<br />
      <input type="text" id="text" disabled /><!--禁用时是红色的,可用时是黄色的-->
    </form>
  </body>
  <html></html>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

# read-only、read-write

read-only为处于只读状态下的元素指定样式。

read-write为处于可读及可写状态下的元素指定样式。

<html>
  <head>
    <style type="text/css">
      input[type="text"]:read-only {
        background-color: gray;
      }
      input[type="text"]:read-write {
        background-color: yellow;
      }
    </style>
  </head>
  <body>
    <form>
      <p>姓名:<input type="text" name="name" /></p>
      <!--可读及可写是黄色的-->
      <p>地址:<input type="text" name="address" value="上海" readonly="readonly" /></p>
      <!--只读是灰色的-->
    </form>
  </body>
  <html></html>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

# indeterminate

indeterminate为打开页面时单选框或多选框中**没有一个选项被选中(未定状态)**时指定整个元素的样式。

<html>
  <head>
    <style type="text/css">
      input[type="radio"]:indeterminate {
        outline: 3px solid red;
      }
    </style>
  </head>
  <body>
    <form>
      性别:<br />
      <input type="radio" name="radio" value="male" /><!--进入页面没有一项是被选中的,那么都为红色边框-->
      <input type="radio" name="radio" value="femal" /></form>
  </body>
  <html></html>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# invalid、valid

E:valid为处于处于合法状态下的元素指定样式。

E:invalid为处于处于非法状态下的元素指定样式。

<html>
  <head>
    <style type="text/css">
      input[type="text"]:valid {
        background: white;
      }
      input[type="text"]:invalid {
        background: red;
      }
    </style>
  </head>
  <body>
    <p>请输入任意文字:<input type="text" required /></p>
    <!--输入文字时白色,没有输入时红色-->
  </body>
  <html></html>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# required、optional

required为已设置了必填属性的元素指定样式。

optional为没有设置必填的元素(选填)指定样式。

<html>
  <head>
    <style type="text/css">
      input[type="text"]:required {
        border-color: red;
        border-width: 3px;
      }
      input[type="text"]:optional {
        border-color: black;
        border-width: 1px;
      }
    </style>
  </head>
  <body>
    <form>
      <p>姓名:<input type="text" required placeholder="必须输入姓名" /></p>
      <!--必填项为红色框-->
      <p>地址:<input type="text" /></p>
      <!--选填项为黑色框-->
    </form>
  </body>
  <html></html>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# in-range、out-of-range

in-range为处于有效值的元素指定样式。

out-of-range为处于失效值的元素指定样式。

<html>
  <head>
    <style type="text/css">
      input[type="number"]:in-range {
        background-color: white;
      }
      input[type="number"]:out-of-range {
        background-color: red;
        border-width: 1px;
      }
    </style>
  </head>
  <body>
    <form>输入1到100之间的数值:<input type="number" min="0" max="100" /><!--数值超过范围就会显示红色--></form>
  </body>
  <html></html>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 四、伪元素选择器

伪元素选择器针对的是元素中的一部分来定义样式,而不是真实元素本身整个整体,因为那一部分并不能用 html 标签表示;和伪类选择器一样是 css 中已经定义好的选择器,不能随便取名。使用方法就是元素::伪元素 {样式属性:值}或者元素.类名::伪元素 {样式属性:值},其实早期是使用单冒号的,现在你可能会看到一部分伪元素是使用单冒号(向前兼容)。

# first-line、first-letter

first-line用于向某个元素中的第一行文字使用样式。

first-letter用于向某个元素中文字的首字母或第一个字使用的样式。

<html>
  <head>
    <style type="text/css">
      p#text1::first-line {
        color: #0000ff;
      }
      p#text2::first-letter {
        color: #0000ff;
      }
      p#text3::first-letter {
        color: #0000ff;
      }
    </style>
  </head>
  <body>
    <p id="text1">段落中的第一行。<br />段落中的第二行。</p>
    <!--段落中第一行为蓝色-->
    <p id="text2">This is an english text.</p>
    <!--首字母为蓝色-->
    <p id="text3">这是一段中文文字。</p>
    <!--第一个字为蓝色-->
  </body>
  <html></html>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

# before、after

before用于在某个元素之前插入一些内容。用法就是元素::before { content: 插入内容 }

after用于在某个元素之后插入一些内容。用法就是元素::after { content: 插入内容 }

<html>
  <head>
    <style type="text/css">
      li::before {
        content: "###";
      }
      li::after {
        content: "(仅用于测试,请勿用于商业用途。)";
        font-size: 12px;
        color: red;
      }
    </style>
  </head>
  <body>
    <ul>
      <li><a href="movie1.mp4">狄仁杰之通天帝国</a></li>
      <!--前面会带上"###",后面会带上红色文字-->
      <li><a href="movie2.mp4">精武风云</a></li>
      <!--前面会带上"###",后面会带上红色文字-->
      <li><a href="movie3.mp4">大笑江湖</a></li>
      <!--前面会带上"###",后面会带上红色文字-->
    </ul>
  </body>
  <html></html>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

这两种选择器的contentnone的话就代表不插入内容,有些情况下normal也是同样的效果。这个功能就能控制哪些使用追加哪些不使用,比如提示博客哪些是上新的在头部或尾部加个小提示。

而且content还能插入图片例如url(mark.png),它比background-image:url(mark.png)这种方式追加多一个好处就是,它可以使用打印机打印出来。

content使用counter可以作为编号追加到元素上,常和 css 的counter-increment搭配使用。甚至使用counter的第二个参数给编号指定类型,例如counter(section, upper-alpha),这是使用了大写字母编号,upper-roman是大写罗马字母等等。

<html>
  <head>
    <style type="text/css">
      body {
        counter-reset: section;
      } /*设置或重置section*/
      h1 {
        counter-reset: subsection;
      } /*设置或重置subsection*/
      h1::before {
        counter-increment: section; /*增量计数section*/
        content: "第" counter(section) "章 "; /*使用section*/
        /*其他样式*/
      }
      h2::before {
        counter-increment: subsection; /*增量计数subsection*/
        content: counter(section) "." counter(subsection) " "; /*使用section和subsection*/
        /*其他样式*/
      }
    </style>
  </head>
  <body>
    <h1>HTML tutorials</h1>
    <h2>HTML Tutorial</h2>
    <h2>XHTML Tutorial</h2>
    <h2>CSS Tutorial</h2>

    <h1>Scripting tutorials</h1>
    <h2>JavaScript</h2>
    <h2>VBScript</h2>
  </body>
  <html></html>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

content除了使用counter,还可以使用open-quoteclose-quote来给元素的首尾添加引号、括号等嵌套文字字符

<html>
  <head>
    <style type="text/css">
      h1 {
        quotes: "(" ")" "[" "]";
      } /* 前两个值规定第一级引用嵌套,后两个值规定下一级引号嵌套。 */
      h1::before {
        content: open-quote;
      }
      h1::after {
        content: close-quote;
      }
    </style>
  </head>
  <body>
    <h1>标题</h1>
  </body>
  <html></html>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# selection

selection用处于被选中的那部分进行指定样式。

<html>
  <head>
    <style type="text/css">
      input[type="text"]::selection {
        background: gray;
        color: #fff;
      }
      p::selection {
        background: red;
        color: #fff;
      }
    </style>
  </head>
  <body>
    <p>这是一段测试文字</p>
    <!--鼠标选中一部分文字时,选中区域是红色的-->
    <input type="text" value="这是一段测试文字" /><!--鼠标选中一部分文字时,选中区域是灰色的-->
  </body>
  <html></html>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# 五、关系选择器

# 5. 后代选择器

后代选择器是用单个空格来组合多个选择器,这些被组合起来的选择器是祖先与后代的关系。

<html>
  <head>
    <style type="text/css">
      .box p {
        color: red;
      }
    </style>
  </head>
  <body>
    <div class="box"><p>Text in .box</p></div>
    <p>Text not in .box</p>
  </body>
  <html></html>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 5.2 子代关系选择器

子代关系选择器是用大于号来组合元素与它的直接子元素的。

<html>
  <head>
    <style type="text/css">
      .ulc > li {
        border-top: 5px solid red;
      }
    </style>
  </head>
  <body>
    <ul class="ulc">
      <li>Unordered item</li>
      <!--有上边框-->
      <li>
        Unordered item
        <!--有上边框-->
        <ul>
          <li>Item 1</li>
          <!--没有边框-->
          <li>Item 2</li>
          <!--没有边框-->
        </ul>
      </li>
    </ul>
  </body>
  <html></html>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

# 5.3 邻接兄弟选择器

邻接兄弟选择器是用加号来选中同级的邻接兄弟元素(下一个)。

<html>
  <head>
    <style type="text/css">
      h1 + p {
        color: red;
      }
    </style>
  </head>
  <body>
    <article>
      <h1>标题</h1>
      <p>文章段落1</p>
      <!--文字红色-->
      <p>文章段落2</p>
    </article>
  </body>
  <html></html>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# 5.4 通用兄弟选择器

通用兄弟选择器是用波浪号来选中同级的某类兄弟元素,不管是否紧挨着。

<html>
  <head>
    <style type="text/css">
      h1 ~ p {
        color: red;
      }
    </style>
  </head>
  <body>
    <article>
      <h1>A heading</h1>
      <p>I am a paragraph.</p>
      <!--文字红色-->
      <div>I am a div</div>
      <p>I am another paragraph.</p>
      <!--文字红色-->
    </article>
  </body>
  <html></html>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# 六、层叠与继承

# 6.1 层叠和继承的简述

css 的首字母cascade,也就是层叠的意思。你可以对同一个元素使用多个 css 样式,规则相同(同一优先级)时前面写的样式会被后面写的样式覆盖掉,如果规则(优先级)不同,即使写在前面也是优先级高的生效。

<html>
  <head>
    <style type="text/css">
      h1 {
        color: red;
      }
      h1 {
        color: blue;
      }
    </style>
  </head>
  <body>
    <!-- 两个样式同规则,最后一个生效,蓝色 -->
    <h1>This is my heading.</h1>
  </body>
  <html></html>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

样式也可以继承,具体来说是设置在父元素上的 css 属性是可以被子元素继承的。

<html>
  <head>
    <style type="text/css">
      ul {
        color: red;
      }
    </style>
  </head>
  <body>
    <ul>
      <li>111</li>
      <!-- 继承ul的颜色:红色 -->
      <li>222</li>
      <!-- 继承ul的颜色:红色 -->
      <li>333</li>
      <!-- 继承ul的颜色:红色 -->
    </ul>
  </body>
  <html></html>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# 6.2 继续了解 css 继承

有些样式是可以继承的,但有些样式是不可以的,比如widthmarginpaddingborder等,像最最基础的fontcolor这些非常常用就会让它们可以被继承,而一些宽度、边框、比距要是能继承那在操作子元素时会非常麻烦,这些属性在一些场景下都是使用默认值。

<html>
  <head>
    <style type="text/css">
      .main {
        color: red;
        border: 2px solid #ccc;
        padding: 1em;
      }
      .special {
        font-weight: bold;
      }
    </style>
  </head>
  <body>
    <ul class="main">
      <li>111</li>
      <li>222</li>
      <li>
        333
        <!--继承了父元素的红色,但是border和padding继承不了-->
        <ul class="special">
          <li>444</li>
          <li>555</li>
        </ul>
      </li>
    </ul>
  </body>
  <html></html>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

可以看到最外层的 ul 是有边框和边距的,内层的 ul 就没有继承这两个属性,只继承了颜色。注意:千万别把.main替换成ul,这样就不是讨论继承了,这是对所有ul设置一样的样式。

为了控制继承,css 为属性提供了四个通用值:

  • initial:使用浏览器默认样式
  • inherit:继承父元素
  • unset:属性默认是可继承就为 inherit 否则为 initial,其实一般默认不可继承
  • revert:还原,会使用用户定义样式表,其他情况跟 unset 差不多。链接 (opens new window)

这个四个通用属性值一般用于单个属性上,其实也可以对一个元素所有样式进行控制,也就是使用all这个属性:

<html>
  <head>
    <style type="text/css">
      div {
        background-color: red;
        border: 2px solid green;
      }
      .fix-this {
        all: unset;
      }
    </style>
  </head>
  <body>
    <div>
      <p>This blockquote is styled</p>
    </div>
    <!--all: unset,回到最初的样式,也就是浏览器默认样式-->
    <div class="fix-this">
      <p>This blockquote is not styled</p>
    </div>
  </body>
  <html></html>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# 6.3 继续了解层叠

我们回过头来说层叠,规则不同会影响同一元素的显示效果,即使优先级高的代码靠前也不会被后面低优先级的覆盖。那么优先级是如何计算的呢?其实不同类型的选择器有不同的分数值,把目标元素的某一个样式中使用的选择器加起来就可以进行比较优先级了。

  1. 千位: 样式定义在元素的style属性上,则得一千分。
  2. 百位: 选择器中包含ID 选择器,则得一百分。
  3. 十位: 选择器中包含类选择器属性选择器或者伪类,则得十分。
  4. 个位: 选择器中包含元素选择器伪元素选择器,则得一分。

例如:

选择器 千位 百位 十位 个位 优先级
h1 0 0 0 1 0001
h1 + p::first-letter 0 0 0 3 0003
li > a[href*="en-US"] > .inline-warning 0 0 2 2 0022
#identifier 0 1 0 0 0100
内联样式 1 0 0 0 1000
<html>
  <head>
    <style type="text/css">
      #outer a {
        /* specificity: 0101 */
        background-color: red;
      }
      #outer #inner a {
        /* specificity: 0201 */
        background-color: blue;
      }
      #outer div ul li a {
        /* specificity: 0104 */
        color: yellow;
      }
      /* specificity: 0113 */
      #outer div ul .nav a {
        color: white;
      }
      /* specificity: 0024 */
      div div li:nth-child(2) a:hover {
        border: 10px solid black;
      }
      /* specificity: 0023 */
      div li:nth-child(2) a:hover {
        border: 10px dashed black;
      }
      /* specificity: 0033 */
      div div .nav:nth-child(2) a:hover {
        border: 10px double black;
      }
      a {
        display: inline-block;
        line-height: 40px;
        font-size: 20px;
        text-decoration: none;
        text-align: center;
        width: 200px;
        margin-bottom: 10px;
      }
      ul {
        padding: 0;
      }
      li {
        list-style-type: none;
      }
    </style>
  </head>
  <body>
    <div id="outer" class="container">
      <div id="inner" class="container">
        <ul>
          <li class="nav"><a href="#">One</a></li>
          <!-- 0201分获胜,蓝色 -->
          <li class="nav"><a href="#">Two</a></li>
          <!-- 0201分获胜,蓝色 -->
        </ul>
      </div>
    </div>
  </body>
  <html></html>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62

!important这个属性设置会覆盖原有的优先级(针对属性),尽管我这条样式的优先级很低,但我样式中的属性使用了!important,那么其他地方的样式中的这个属性只能听我的。

<html>
  <head>
    <style type="text/css">
      #winning {
        background-color: red;
        border: 1px solid black;
      }
      .better {
        background-color: gray;
        border: none !important;
      }
      p {
        background-color: blue;
        color: white;
        padding: 5px;
      }
    </style>
  </head>
  <body>
    <p class="better">This is a paragraph.</p>
    <p class="better" id="winning">One selector to rule them all!</p>
  </body>
  <html></html>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

上面这个例子逐步分析:

  • 初步分析 p 标签应该是蓝底白字
  • 因为类选择器的缘故应该是灰底白字没有边框
  • 而第二个<p>单独使用了 ID 选择器,那么第二个<p>应该是红底白字有边框
  • border 曾设置过!important,那么即使 ID 选择器优先级高也不能忽视低优先级类选择器里设置的!important,所以第二个<p>也无边框

注意:不到万不得已不要使用!important,它打乱了优先级,覆盖已有的!important又要在同优先级或高优先级使用!important来抵消,要是其他地方也要改也要这样设置。