CSS中的结构伪类选择器
结构伪类选择器主要根据文档结构来选择元素, 常用于根据父级选择器里面的子元素。合理使用结构伪类选择器,可以节省类名的定义,减少代码量。
结构伪类选择器的用法
| 选择符 | 简介 |
|---|---|
| E:first-child | 匹配父元素中的第一个子元素E |
| E:last-child | 匹配父元素中最后一个E元素 |
| E:nth-child(n) | 匹配父元素中的第n个子元素E |
| E:first-of-type | 指定类型E的第一个 |
| E:last-of-type | 指定类型E的最后一个 |
| E:nth-of-type(n) | 指定类型E的第n个 |
选择器中n值
- n可以是数字,关键字和公式
- 如果是数字,就是选择第n个子元素,里面数字从1开始
- n可以是关键字:even偶数,odd奇数
- n可以是公式:常见的公式如下(如果n是公式,则从0开始计算,但是第0个元素或者超出了元素的个数会被忽略)
| 公式 | 取值 |
|---|---|
| 2n | 偶数 |
| 2n+1 | 奇数 |
| 5n | 5 1015 ... |
| n+5 | 从第5个开始(包含第五个)到最后 |
| -n+5 | 前5个(包含第5个)... |
用法详解
直入主题,我们将常用的结构伪类选择器分为两类:
- 选择兄弟元素
:first-child:last-child:nth-child(n)
- 选择同类型兄弟元素
:first-of-type:last-of-type:nth-of-type(n)
这两者的区别主要在于:前者是对父元素里面的所有孩子进行排序选择(序号固定),先找到第n个孩子,再看是否与该元素类型匹配;后者是对父元素里面指定的子元素(同类型)进行排序选择,先去匹配元素类型,再根据元素找第n个孩子
下面举个例子。
假设盒子结构如下:
<div class="father">
<div>第一个div</div>
<p>第一个p</p>
<div>第二个div</div>
<h3>第一个h3</h3>
<p>第二个p</p>
<h3>第二个h3</h3>
</div>
这里,我要去找第一个div和第二个div。先直接使用:first-child和:last-child,看看能否正常选中。
.father div:first-child {
background-color: red;
}
.father div:last-child {
background-color: yellow;
}
结果并不能找到第二个div,我们放弃:last-child写法,使用:nth-child(3)来看能否选中。
.father div:first-child {
background-color: red;
}
.father div:nth-child(3) {
background-color: aqua;
}
正确找到了第二个div。那么为什么:last-child写法找不到,使用:nth-child(3)就能正确找到了呢?
原因如下:
- 沿用上文的解释:在进行选择前,会把父元素里面的所有孩子进行排序选择(div,p,h3全部进行排序,序号固定),先找到第n个孩子,再看是否与该元素类型匹配。
:last-child找不到的原因是因为,这里选择的是序号为最后的孩子,也就是上图中的第二个h3,选中后再进行类型匹配,发现最后一个元素类型为h3与div类型不同,因此没有找到。同理,:nth-child(3)之所以能找到,是当选中第三个孩子后,进行元素类型匹配,同为div,因而正确选中。
我们在看上文的第二句话就好理解了:“选择前对父元素里面指定的子元素(同类型)进行排序选择,先去匹配元素类型,再根据元素找第n个孩子”。
因此,对于刚刚的情形,我们可以直接使用:first-of-type和:last-of-type或者:nth-of-type(1)和:nth-of-type(2)更直观的选择第一个div和第二个div。
.father div:first-of-type {
background-color: blue;
}
.father div:last-of-type {
background-color: green;
}
总结:当父元素里面的子元素类型统一时,:nth-child(n)和:nth-of-type(n)效果上没有区别,推荐使用前者;当父元素里面的子元素类型不统一时,使用:nth-of-type(n)。
不常用用法补充
除去直接写标签名+伪类选择器的形式,还可以使用类名+伪类选择器。这种方法不常用,但也存在,某种程度上不太好理解,特在此补充,供大家参考。
- 当我们使用
类 :nth-child(n)时,依旧是将父元素的子代元素标签排序,然后进行类名匹配,与直接使用标签类似。 - 当我们使用
类 :nth-of-type(n)时,先是找不同类型满足条件的标签进行分类,随后排序,最终进行类名匹配,这点与直接使用标签有略微差别,下面有个例子能很好诠释这个情况(实际开发中,不这么用,仅供参考和理解)。
<p class="banner">p-banner</p>
<div class="item">div-item</div>
<div class="title">div-title</div>
<div class="banner">div-banner1</div>
<div class="banner">div-banner2</div>
<p class="banner">p-banner1</p>
<p class="banner">p-banner2</p>
.banner:first-of-type {
background-color: aqua;
}
.banner:last-of-type {
background-color: blue;
}
首先,在选择前会进行分类,p标签为一类,div标签为一类,随后分别进行排序,序号独自计算。
对于
.banner:first-of-type:p-banner是p标签一类的第一个元素并且类名匹配,因此会天蓝色高亮;div标签的第一个元素类名为item,不与banner匹配,因此不会被选中,因而只有p-banner高亮。对于
.banner:last-of-type:原理与上面类似,会选择两类标签排序最后的一个元素,并且他们的类名也匹配,因此div-banner2和p-banner2变成蓝色高亮。