11.1 CSS 伪类(pseudo-classes)

用来增强CSS选择器

我们已经学习过CSS的3种主要的选择器

  • 通用标签:CSS代码中的 p 用来选择HTML元素 <p>
  • 类(classes): CSS代码中的 .intro 用来选择带有属性 class="intro" 的HTML元素。
  • ids:CSS代码中的 #logo 用来选择带有属性 id="logo" 的HTML元素。

所有这些选择器都可以附加使用伪类(pseudo-classes)。一个伪类用来:

  • 定义一个元素的特殊状态,这个状态往往和用户的动态交互行为或文档的动态结构化特征有关,因此不能提前写入HTML文档中。
  • 是以冒号(colon) : 开始的一个关键词。

语法

伪类不能单独存在。它必须附加在一个选择器上。伪类将只是定义那个选择器的特殊状态。

语法看起来如下:

.selector:pseudo-class{ }

在选择器和伪类中间没有空格, between the selector and the pseudo-class, 以表示它们是连接在一起的

:hover

一个常用的伪类是 :hover,用来给一个悬停状态(即用户鼠标悬停在元素上时触发的状态)下的目标元素添加样式。我们可以把这个伪类用于链接。因为悬停是最基本的链接交互动作

a{ color: blue;}
a:hover{ color: red;}

悬停在这个链接上,文本颜色会变红。

第一行定义所有的 <a> 链接颜色为蓝色。
第二行定义当被悬停时,<a> 链接颜色为红色。

第二行选择的是同样的HTML元素,但是有特定的行为发生。(本例中是发生了用户悬停动作)。

:visited

这个伪类的目标对象是被访问过的链接。默认情况下,链接是蓝色的,当被您访问(点击或触摸)过后,变成紫色。

a{ color: dodgerblue;}
a:visited{ color: rebeccapurple;}

<a href="https://taobao.com">淘宝</a>
<a href="https://baidu.com">百度</a>
<a href="https://www.mozilla.org">Mozilla</a>
<a href="http://techbrood.com">Techbrood</a>

这个样式应用通常被开发者忽视,不过它有助于帮助用户浏览一系列的结果链接(比如百度搜索结果页),用户可以很方便的知道哪些链接我已经访问过,从而做出判断是否要再次访问以提高浏览效率。

:focus

这个伪类的目标对象是处于焦点状态的HTML元素。这对于用户输入类HTML元素inputs非常有用,因为聚焦是这类元素最基本的交互行为。

.form-input{ border: 2px solid grey; padding: 5px;}
.form-input:focus{ background: lightyellow; border-color: blue; outline: none;}

:checked

:checked伪类是CSS3引入的一个很棒的状态选择器,用来表示选择框(radio box、check box或options)的选中状态。

有些读者可能会有点疑问,我们在文档中也可以放入初始状态(如Section 17.2.1 of HTML4里面定义的selected或checked)。因此严格而言:checked伪类的确不完全是作用于文档以外的信息,但其本质上是一个动态交互行为。

我们一样通过一个在线实例来学习:checked伪类的使用,这是一个经典的纯CSS手风琴导航栏,无须任何js脚本:

和:checked类似的和UI界面组件状态有关的动态选择器还有:enabled和:disabled,较少使用,这里不做更多介绍。

上面都是和元素状态相关的伪类(Dynamic pseudo-classes),除此之外,我们经常使用的还有结构化伪类(Structural pseudo-classes),如:first-child等。

:first-child 和 :last-child

这两个伪类和HTML元素层级关系有关。它们依据HTML元素在代码中出现的顺序来定位目标元素。

我们可以把元素顺序或层级关系看成是一种特殊的状态

<ul>
  <li>One</li>
  <li>Two</li>
  <li>Three</li>
  <li>Four</li>
</ul>
li:first-child{ background: greenyellow;}
li:last-child{ background: lightsalmon;}
  • One
  • Two
  • Three
  • Four

可以看到,我们并没有给第一个和最后一个 <li> 元素添加 class 属性。 它们在文档中的位置定义了CSS规则的应用。

在这类例子中,我们可以通过给这些元素添加特定的类(class)来实现同样的目的,这可以帮助我们理解为什么上述通过元素状态或顺序来选择元素的CSS规则被称为“伪类”。

如果我们再添加一条列表项,使用相同的CSS,样式会被自动调整:

  • One
  • Two
  • Three
  • Four
  • Five

:nth-child

这个伪类是 :first-child:last-child的通用版本,用来选择第n个子元素。

比如,如果你想选择第2个子元素,你可以使用 :nth-child(2)

li:nth-child(2){ background: violet;}
  • One
  • Two
  • Three
  • Four

奇数和偶数(odd 和 even)

除了使用直接的数字外,:nth-child 还支持以奇偶数的方式来通配选择子元素,这对于设置一些动态表格样式有帮助。

  • :nth-child(odd) 目标对象为所有的奇数子元素。
  • :nth-child(even) 目标对象为所有的偶数子元素。
li:nth-child(odd){ background: gold;}
  • One
  • Two
  • Three
  • Four

n遍历器(iterator)

还有更为强大的选择规则,:nth-child 支持基于 n 遍历器关键词的选择计算方法。

n 的取值从 0 开始。代表每n个元素进行遍历。

比如如果我们想选择顺序为3的倍数的所有子元素,可以使用如下的规则:

li:nth-child(3n){ background: hotpink;}
  • One
  • Two
  • Three
  • Four
  • Five
  • Six
  • Seven

上例中,选择了0(实际没有)、3、6的列表项。这个例子中0没有用,但是我们将看到n从0开始是必要的。

3n + 1

上面这个规则可以用来选择目标元素为第一个以及随后每隔开3个位置的子元素。

li:nth-child(3n+1){ background: limegreen;}
  • One
  • Two
  • Three
  • Four
  • Five
  • Six
  • Seven

3n+1 规则包含2个部分:

  • 3n 选择顺序为3的倍数的列表项。
  • +1 在前面选择的基础上向后偏移1个位置。

可以看到,n遍历器是非常灵活和强大的。

否定选择器(:not)

否定选择器和jQuery中的:not选择器类似,是一个带参数的函数式选择器,语法如下:

*:not(FOO)

它表示除了符合FOO选择条件的元素均被选中。比如我们想给列表项添加下边线,但最后一条不加(以免和列表容器的边线重复),此时就可以使用:not来实现

li.item:not(:last-child) {
    border-bottom: 1px solid #dedede;
}

注意否定选择器不是结构化选择器,有些网上教程比如慕课网上的描述是错误的。另外否定选择器不能嵌套使用。

其它伪类

有很多可用的伪类,可以从这个链接查看完整列表:可用伪类列表,有一些的使用非常有限。最常用的就是我们上面讨论过的这些。