# CSS3教程 - 4 CSS选择器
下面来讲解选择器,选择器的作用是用来选中页面中的元素,然后才可以给选中的元素添加样式。
这个章节是非常非常重要的!!!
# 4.1 常用选择器
# 1 元素选择器
也叫类型选择器、标签选择器
- 作用:根据标签名来选中指定的元素
- 语法:元素名称 {},
举个栗子:
<head>
    <meta charset="UTF-8">
    <title>CSS选择器</title>
    <style>
        h1 {
            color: green;
        }
        p {
            color: red;
        }
    </style>
</head>
<body>
    <h1>登鹳雀楼</h1>
    <p>白日依山尽,</p>
    <p>黄河入海流。</p>
    <p>欲穷千里目,</p>
    <p>更上一层楼。</p>
</body>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
使用了标签选择器选择了h1元素和 p 元素,并分别设置了颜色。那么样式会对页面中所有的 h1元素和 p 元素生效。
效果如下:

元素选择器是对所有元素生效的,如果只想对其中一个元素生效,该怎么做呢?下面来说ID选择器。
# 2 ID选择器
- 作用:根据元素的id属性值选中一个元素
- 语法:#id {}
举个栗子:
<head>
    <style>
        #last {
            color: pink;
        }
    </style>
</head>
<body>
    <h1>登鹳雀楼</h1>
    <p>白日依山尽,</p>
    <p>黄河入海流。</p>
    <p>欲穷千里目,</p>
    <p id="last">更上一层楼。</p>
</body>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
首先需要给元素加上一个id属性,值是自定义的,但需要注意 id 需要全局唯一,不能重复。 然后在样式表中通过 #id 来选中元素,添加样式。
id选择器只能对一个元素生效,如果要对两个元素生效,定义两个 id 然后定义两个样式,有点麻烦,那么怎么办呢?下面来说类选择器。
# 3 类选择器
- 作用:根据元素的 class 属性值选中一组元素
- 语法:.classname {}
举个栗子:
<head>
    <style>
        .test {
            color: blue;
        }
    </style>
</head>
<body>
    <h1>登鹳雀楼</h1>
    <p>白日依山尽,</p>
    <p>黄河入海流。</p>
    <p class="test">欲穷千里目,</p>
    <p class="test">更上一层楼。</p>
</body>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
首先需要给要选定的标签添加 class 属性,值是自定义的。然后在样式表中通过 .classname {} 来选定元素,并添加样式。
和 id 不同的是:
- class可以重复使用,给多个元素添加,相当于给元素进行分类;
- 可以同时为一个元素指定多个 class值;
<p class="title big-size">类选择器</p>
上面为 p 元素指定了两个 class:title 和 big-size。一个元素可以有多个 class,多个元素可以共享相同的 class 。
如果要选中页面中所有的元素,改怎么办呢?那么可以使用通配符选择器。
# 4 通配选择器
- 作用:选中页面中的所有元素
- 语法:* {}
<style>
  * {
    color: blue;
  }
</style>
2
3
4
5
上面的代码选中了页面中所有的元素,并添加了样式,设置颜色为蓝色。
显示效果:

通配选择器一般会在给页面的所有元素清除默认的样式的时候使用,元素都有默认的样式,例如间距,一般会先将默认的样式去掉,然后进行重新设置。
# 5 属性选择器
- 作用:根据元素的属性值选中一组元素。
- 语法 1:[属性名]选择含有指定属性的元素
- 语法 2:[属性名=属性值]选择含有指定属性和属性值的元素
- 语法 3:[属性名^=属性值]选择属性值以指定值开头的元素
- 语法 4:[属性名$=属性值]选择属性值以指定值结尾的元素
- 语法 5:[属性名*=属性值]选择属性值中含有某值的元素
举个栗子:
<style>
  /* 选择包含title属性的p元素 */
  p[title] {
    color: blue;
  }
  /* 选择title属性是hello的p元素 */
  p[title="hello"] {
    color: blue;
  }
  /* 选择title以hello开头的p元素 */
  p[title^="hello"] {
    color: blue;
  }
  /* 选择title以hello结尾的p元素 */
  p[title$="hello"] {
    color: blue;
  }
  /* 选择title值包含hello的p元素 */
  p[title*="hello"] {
    color: blue;
  }
</style>
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
需要注意:
<!-- title="hello"满足包含title属性、 title属性是hello、以hello开头、以hello结尾、包含hello多种情况,在编写样式的时候,如果匹配到后面的规则,则会覆盖前面的规则 -->
<p title="hello">白日依山尽,</p>
<!-- 满足title以hello开头、包含hello -->
<p title="hello-foooor">黄河入海流。</p>
2
3
4
5
# 4.2 复合选择器
复合选择器是将多个选择器搭配使用。主要有交集选择器和并集选择器。
# 1 交集选择器
- 作用:选中同时符合多个条件的元素
- 语法:选择器1选择器2选择器3选择器n {},选中的元素需要同时满足所有的选择器的条件。
举个栗子:
<body>
  <h1>登鹳雀楼</h1>
  <p class="test">白日依山尽,</p>
  <div>黄河入海流。</div>
  <p class="test1 test2 test3">欲穷千里目,</p>
  <div class="test">更上一层楼。</div>
</body>
2
3
4
5
6
7
上面的元素,我们想选择最后一句更上一层楼,改如何选中呢?
div.test {
  color: blue;
}
2
3
上面表示选中 div,且这个 div 的 class 是 test,是并且的关系。
当然各个类也可以同时使用:
.test1.test2.test3 {
  color: red;
}
2
3
上面表示选中同时有 test,test1,test2 三个类的元素,也就是 欲穷千里目 这一句的元素。
注意:交集选择器中如果有元素选择器,必须使用元素选择器开头,另外各个选择器之间不能有空格。
# 2 并集选择器
并集选择器也叫分组选择器。
- 作用:同时选择多个选择器对应的元素
- 语法:选择器1,选择器2,选择器3,选择器n {},选中的元素只要满足一个选择器的条件。
举个栗子:
#last, .test1, h1, span, div.test2 {} {
  color: green;
}
2
3
上面同时选择了 id 为 last 的元素,类为 test1 的元素,所有的 h1 元素、所有的 span 元素、以及类为 test2 的所有 div 元素。可以看到并集选择器中可以包含交集选择器。
# 4.3 关系选择器
先说明一下元素之间可能存在的关系,有以下几种:
- 父元素:直接包含子元素的元素叫做父元素;
- 子元素:直接被父元素包含的元素是子元素;
- 祖先元素:直接或间接包含后代元素的元素叫做祖先元素,一个元素的父元素也是它的祖先元素;
- 后代元素:直接或间接被祖先元素包含的元素叫做后代元素,子元素也是后代元素;
- 兄弟元素:拥有相同父元素的元素是兄弟元素;
# 1 子元素选择器
- 作用:选中指定父元素的指定子元素
- 语法:父元素 > 子元素
举例1:选中所有 div 下的所有子 p 元素
div > p {
  color: orange;
}
2
3
举例2:选中 class 为 box 的 div 下的 p 元素
div.box > p {
  color: orange;
}
2
3
举例3:选中 class 为 box 的 div 下的 p 元素中的 span 元素。
div.box > p > span {
  color: orange;
}
2
3
可以一级一级的往下选择。
# 2 后代元素选择器
- 作用:选中指定元素内的指定后代元素
- 语法:祖先 后代
举例1:选中所有 div 下的所有级别的 span 元素
div span {
  color: blue;
}
2
3
举例2:选中所有 div 元素中的 p 元素中的 span 元素,是一级一级的包含关系。
div p span {
  color: blue;
}
2
3
# 3 兄弟元素选择器
- 作用:选择兄弟元素 
- 语法: - 前一个 + 下一个:用于选择下一个兄弟元素- 前一个 ~ 下一组:用于选择后面所有的兄弟元素
举例1:选中所有p元素后面的第一个span兄弟元素,如果一个p元素后面不是span元素,则不会选中后面的元素。
p + span {
  color: red;
}
2
3
举例2:选中p元素后面所有的span兄弟元素,注意只会选中所有的span元素。
p ~ span {
  color: red;
}
2
3
# 4.4 伪类选择器
# 1 常用伪类选择器
伪类(不存在的类,特殊的类),不像我们之前定义的 class。伪类用来描述一个元素的特殊状态,比如:第一个子元素、被点击的元素、被鼠标移入的元素.…
伪类一般情况下都是使用 : 开头
- :first-child:选中第一个子元素
- :last-child:选中最后一个子元素
- :nth-child():选中第 n 个子元素- n:第 n 个,n 的值从 1 开始
- 2n或- even:选中偶数位的元素
- 2n+1或- odd:选中奇数位的元素
 
举个栗子:
<head>
    <style>
        /**选中第一个li*/
        ul > li:first-child {
            color: red;
        }
        /**选中最后一个li*/
        ul > li:last-child {
            color: blue;
        }
        /**选中第三个li*/
        ul > li:nth-child(3) {
            color: green;
        }
    </style>
</head>
<body>
    <ul>
        <li>第一个</li>
        <li>第二个</li>
        <li>第三个</li>
        <li>第四个</li>
        <li>第五个</li>
    </ul>
</body>
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
效果如下:

当我们在第一个 li 元素前面和最后一个 li 元素后面添加一个span的时候
<ul>
    <span>一个牛A的span</span>
    <li>第一个</li>
    <li>第二个</li>
    <li>第三个</li>
    <li>第四个</li>
    <li>第五个</li>
    <span>一个牛B的span</span>
</ul>
2
3
4
5
6
7
8
9
最终的效果如下:

发现第一个 li 和最后一个 li 都没有被选中了,这里因为以上这些伪类都是根据所有的子元素进行排序的。
如果要根据同类型的标签进行选择,可以使用如下标签
- :first-of-type:同类型中的第一个子元素
- :last-of-type:同类型中的最后一个子元素
- :nth-of-type():选中同类型中的第 n 个子元素
这几个伪类的功能和前面的类似,不同点是他们是在同类型元素中进行排序的。
演示一下:
<style>
    /**选中第一个li*/
    ul > li:first-of-type {
      color: red;
    }
    /**选中最后一个li*/
    ul > li:last-of-type {
      color: blue;
    }
    /**选中第3个li*/
    ul > li:nth-of-type(3) {
      color: green;
    }
</style>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
显示效果:

还有一个常用的伪类:
- :not():否定伪类,将符合条件的元素从选择器中去除
/*除了第一个都选中*/
ul > li:not(:first-child) {
  color: red;
}
/*除了第三个都选中*/
ul > li:not(:nth-child(3)) {
  color: red;
}
2
3
4
5
6
7
8
9
# 2 动态伪类
- :link:未访问的链接状态,超链接特有伪类;
- :visited:已访问的链接状态,由于隐私的原因,所以- visited这个伪类只能修改链接的颜色,这个也是超链接特有伪类;
- :hover:鼠标移入到元素时的状态,所有的元素都有这个伪类;
- :active:鼠标点击元素时候的状态,所有元素都有这个伪类;
举个栗子:
<style>
    /* 未访问的链接是红色 */
    a:link {
      color: red;
    }
    /* 已被访问的链接会变成绿色 */
    a:visited {
      color: green;
    }
    /* 鼠标移入时,会变成黄色 */
    a:hover {
      color: yellow;
    }
    /* 元素被点击时,会变成蓝色 */
    a:active {
      color: blue;
    }
</style>
<body>
    <a href="http://www.baidu.com">百度</a>
    <a href="http://www.163.com">网易</a>
</body>
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
- 上面的伪类书写的顺序是有要求的,如果要同时使用上面的多个伪类,需要按照 link、visited、hover、active的顺序来写,否则会导致有些伪类不生效。
效果如下:

还有一个伪类 :focus ,表示获取焦点时候的伪类,只有表单类元素才会有,例如文本框、下拉列表等。
再看一个例子,如果想在鼠标悬浮 box1 的时候,才设置 box1 中的 box2 的背景,该如何设置呢?
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      .box1 {
        width: 200px;
        height: 200px;
        background-color: blue;
      }
      .box2 {
        width: 100px;
        height: 100px;
      }
      .box1:hover .box2 {
        background-color: red;
      }
    </style>
  </head>
  <body>
    <div class="box1">
      <div class="box2"></div>
    </div>
  </body>
</html>
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
- .box1:hover .box2表示只有在 box1 元素被鼠标悬浮的时候,才会选择 box2。所以上面代码只有在 box1 被鼠标悬浮的时候,才会设置 box2 的背景。
- 上面 width和height是设置元素的宽度和高度,background-color是设置元素的背景颜色,后面再讲。这里主要关注选择器的使用。
显示如下:

# 4.5 伪元素选择器
伪元素,表示页面中一些特殊的并不真实的存在的元素,表示的是一个特殊的位置,例如元素的开始和结束的位置,内容的第一个字母等。
伪元素使用 :: 开头,常用的伪元素选择器如下:
- ::first-letter:表示第一个字母;
- ::first-line:表示第一行;
- ::selection:表示内容被选中时候的状态;
- ::before:元素的开始位置;
- ::after:元素的最后位置;
- ::before和- ::after必须结合- content属性来使用。
举个栗子:
<!DOCTYPE html>
<html>
  <head>
    <style>
      /* 段落首字母设置大小为30px */
      p::first-letter {
        font-size: 30px;
      }
      /* 段落第一行设置为黄色背景 */
      p::first-line {
        background-color: yellow;
      }
      /* 段落选中的内容变绿色 */
      p::selection {
        background-color: green;
      }
      /* div前加上内容 */
      div::before {
        content: "<";
        color: blue;
      }
      /* div后加上内容 */
      div::after {
        content: ">";
        color: blue;
      }
    </style>
  </head>
  <body>
    <p>
      A lawyer dies and goes to Heaven. "There must be somemistake," the lawyer
      argues. "I'm too young to die. I'm only55." "Fifty-five?" says Saint
      Peter. "No, according to outcalculations, you're 82." "How'd you get
      that?" the lawyer asks.Answers St. Peter, "We added up your time sheets."
    </p>
    <div>Love never ends.</div>
  </body>
</html>
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
显示如下:
可以看到 p 元素的首字母变大了,div 标签的前后位置添加了一对尖括号 <>,但是 div 的文本中并没有尖括号。

通过开发者工具可以查看到伪元素,可以看到 ::before 和 ::after 的位置,是在元素最前端和最后端的位置:

注: 其他的伪元素用的不多,但是 ::before 和 ::after  两个伪元素在开发中用的是很频繁的。
# 4.6 CSS Dinner 游戏
目前我们暂时还无法编写页面,只是学习了理论的知识,请还不要着急,慢慢来。
我们通过下面的一个页面游戏来练习 CSS 选择器的使用。
官方地址:CSS Diner - Where we feast on CSS Selectors! (opens new window)
CSS Dinner 是一个帮助初学者快速熟悉 CSS 各种选择器的网页游戏,在网页上面的桌子上会有元素晃动,然后需要在下面的 CSS Editor 中编写选择器,选中晃动的元素。

注:例如选中上面的两个盘子,直接用元素选择器,在 CSS Editor 中编写 plate,然后回车即可。
# 4.7 命名规则
在 HTML 和 CSS 中,为元素定义ID,或者创建样式类的类名,一般遵循一些规则,有助于提高代码的一致性和可读性。
# 1 ID命名规则
- 每个 - id在文档中必须是唯一的。一个- id只能在整个页面中出现一次;
- id值应该由字母、数字、下划线(- _)和连字符(- -)组成,不能包含空格或其他特殊字符。当使用多个单词时,推荐使用小写字母加连字符(- -)分隔多个单词,如:- main-left-box、- nav-wrap。我看到有不同的规则,例如使用下划线分隔或使用首字母小写的驼峰规则,具体看你公司要求吧;
- id不能以数字开头,但可以包含数字;
- id应该具有描述性,能够清楚地表达元素的作用或内容。
# 2 class命名规则
- 一个元素可以有多个 - class,多个元素可以共享相同的- class;
- class名称只能包含字母、数字、下划线(- _)和连字符(- -),不能包含空格、点(- .)或其他特殊字符。当使用多个单词时,通常使用小写字母和连字符(- -)来分隔多个单词,如:- primary-button,- search-result;
- 尽量避免将 - class名称与 CSS 样式规则的关键字或伪类(如- hover、- active)冲突;
- class名称应简洁且具有描述性,反映元素的作用或用途。
← 03-CSS语法 05-继承权重长度颜色 →
