CSS3 伪类选择器详解

142 阅读8分钟

背景

在页面开发时,使用了伪类选择器将最后一个元素后的样式取消,测试的时候发现,打开明细时,最后一个元素后的样式没有按照预想的消失。

代码结构如下:

<template>
  <div class="parent">
    <div v-for="item in arr" class="child"></div>
    <van-action-sheet v-model="showDetail">hhhh</van-action-sheet>
  </div>
</template>
<style lang="scss" scoped>
  .parent {
    .child {
      &::after {
            content: '';
            display: block;
            position: absolute;
            top: 36px;
            left: 14px;
            transform: translateX(-50%);
            height: calc(100% - 40px);
            border: 2px dashed #e2e6f0;
        }
        &:last-child::after {
            display: none;
        }
    }
  }
</style>

没有打开明细之前,一切正常,打开明细展示 van-action-sheet 后,last-childdisplay: none 就失效了,排查后发现是自己对 CSS3 的伪类选择器了解的不够全面,所以趁着这个机会,对这个小知识点进行整理。

伪类选择器

结构伪类选择器主要根据文档结构来选择元素,常用于选择父亲里面的第几个孩子。

伪元素和伪类的区别:

伪元素:在内容元素的前后插入额外的元素或样式,但是这些元素实际上并不在文档中生成。它们只在外部显示可见,但不会在文档的源代码中找到它们,因此,称为“伪”元素。

伪类:将特殊的效果添加到特定选择器上。它是已有元素上添加类别的,不会产生新的元素。

分为以下这些类型:

选择符简介
E:first-child匹配父元素的第一个子元素Eul li:first-child 表示ul中的第一个li
E:last-child匹配父元素的最后一个E元素ul li:last-child 表示ul中的最后一个li
E:nth-child(n)匹配父元素中的第n个子元素En可以是数字、关键字和公式 1. ul li:nth-child(3) 表示ul中的第3个li; 2. 关键字:even偶数,odd奇数 3. 公式:常见公式下下表
E:first-of-type指定类型E的第一个
E:last-of-type指定类型E的最后一个
E:nth-of-type(n)指定类型E的第n个
公式取值
2n偶数
2n+1奇数
5n0 5 10 15……
n+5从第5个开始(包括第5个)到租后
-n+5前5个(包括第5个)

last-child 和 last-of-type

last-childlast-of-type 是 CSS3 中的两个伪类选择器,用于选择特定元素,但它们的作用和适用场景有所不同。

:last-child:不关心元素的类型,只关心它在父元素中的位置

  • 作用: 选择父元素中的最后一个子元素。
  • 条件: 该子元素必须是父元素的最后一个子元素,且不考虑元素类型。

:last-of-type:针对特定类型的元素进行操作,且只选择该类型的最后一个元素

  • 作用: 选择父元素中特定类型的最后一个子元素。
  • 条件: 该子元素必须是父元素中同类型元素的最后一个。

光看定义感觉有一丢丢枯燥,举几个🌰看看。

last-child 理解

例1

当 CSS 为 .parent .child:last-child 时,表示选中 parent 下的最后一个元素,并且类名需要是 child,将它的颜色变为红色。

<div class="parent">
    <div class="child">1111</div>
    <span class="child">2222</span>
    <div class="child">3333</div>
    <div class="child">4444</div>
</div>
<style>
    .parent {
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
    }
    .parent .child:last-child {
        color: red;
    }
</style>

1

例2

调整 html 结构为如下,将最后一个 div 样式名更改,会发现没有任何元素变为红色。因为 .parent .child:last-child 表示的是选中 parent 下的最后一个元素,并且类名需要是 child,将它的颜色变为红色。而当前的 html 结构,没有元素满足要求。

<div class="parent">
    <div class="child">1111</div>
    <span class="child">2222</span>
    <div class="child">3333</div>
    <div class="child1">4444</div>
</div>

2

例3

调整 css 为 .parent :last-child,发现最后一个元素变红色了,这时表示表中 parent 下最后一个子元素,不关注类型是什么

.parent :last-child {
   color: red;
}

1

last-of-type 理解

例1

当 CSS 为 .parent .child:last-of-type 时,表示先将 parent 下的子元素按照标签的不同分类,将所有类别中最后一个元素并且类名是 child 的元素变为红色。以下结构,有2个子元素满足要求

<div class="parent">
    <div class="child">1111</div>
    <span class="child">2222</span>
    <div class="child">3333</div>
    <div class="child">4444</div>
</div>
<style>
    .parent {
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
    }
    .parent .child:last-of-type {
        color: red;
    }
</style>

解释下为什么有2个子元素满足要求,先按照标签分类,

第1组:
<span class="child">2222</span>
第2组:
<div class="child">1111</div>
<div class="child">3333</div>
<div class="child">4444</div>

再从每一组里找到最后一个子元素并且类名需要是 child,所以可以选中2个子元素

3

例2

调整 html 结构为如下,将最后一个 div 样式名更改,会发现变为红色的元素变了。因为 .parent .child:last-of-type 表示选中将所有类别中最后一个元素并且类名是 child 的元素。

<div class="parent">
    <div class="child">1111</div>
    <span class="child">2222</span>
    <div class="child">3333</div>
    <div class="child1">4444</div>
</div>

解释下为什么只有一个子元素选中,先按照标签分类,

第1组:
<span class="child">2222</span>
第2组:
<div class="child">1111</div>
<div class="child">3333</div>
<div class="child1">4444</div>

再从每一组里找到最后一个子元素并且类名需要是 child,所以只有第1组的span 元素满足要求

4

例3

调整 css 为 .parent :last-of-type,表示选中 parent 下所有分类的最后一个子元素,不关注类型是什么

.parent :last-of-type {
   color: red;
}

5

nth-child 和 nth-of-type

其实和 last-child 和 last-of-type 类似,只是选中的是特定的第几个子元素

:nth-child:不关心元素的类型,只关心它在父元素中的位置

  • 作用: 选择父元素中的第n个子元素。
  • 条件: 该子元素必须是父元素的第n个子元素,且不考虑元素类型。

:nth-of-type:针对特定类型的元素进行操作,且只选择该类型的最后一个元素

  • 作用: 选择父元素中特定类型的第n个子元素。
  • 条件: 该子元素必须是父元素中同类型元素的第n个。

nth-child 理解

例1

当 CSS 为 .parent .child:nth-child(2) 时,表示选中 parent 下的第2个子元素,并且类名需要是 child,将它的颜色变为红色。

<div class="parent">
    <div class="child">div1111</div>
    <span class="child">span1111</span>
    <div class="child">div3333</div>
    <span class="child">span2222</span>
    <div class="child">div4444</div>
    <div class="child">div5555</div>
</div>
<style>
    .parent {
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
    }
    .parent .child:nth-child(2) {
        color: red;
    }
</style>

1

例2

调整 html 结构为如下,将第2个元素样式名更改,会发现没有任何元素变为红色。因为 .parent .child:lnth-child(2) 表示的是选中 parent 下的第2个元素,并且类名需要是 child,将它的颜色变为红色。而当前的 html 结构,没有元素满足要求。

<div class="parent">
    <div class="child">div1111</div>
    <span class="child1">span1111</span>
    <div class="child">div3333</div>
    <span class="child">span2222</span>
    <div class="child">div4444</div>
    <div class="child">div5555</div>
</div>

2

例3

调整 css 为 .parent :nth-child(2),发现第2个子元素又变红色了,这时表示表中 parent 下第2个子元素,不关注类型是什么

.parent :nth-child(2) {
   color: red;
}

1

nth-of-type 理解

例1

当 CSS 为 .parent .child:nth-of-type(2) 时,表示先将 parent 下的子元素按照标签的不同分类,将所有类别中第2个元素并且类名是 child 的元素变为红色。以下的结构,有2个子元素满足要求

<div class="parent">
    <div class="child">div1111</div>
    <span class="child">span1111</span>
    <div class="child">div3333</div>
    <span class="child">span2222</span>
    <div class="child">div4444</div>
    <div class="child">div5555</div>
</div>
<style>
    .parent {
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
    }
    .parent .child:nth-of-type(2) {
        color: red;
    }
</style>

解释下为什么有2个子元素满足要求,先按照标签分类,

第1组:
<span class="child">span1111</span>
<span class="child">span2222</span>
第2组:
<div class="child">1111</div>
<div class="child">3333</div>
<div class="child">4444</div>
<div class="child">div5555</div>

再从每一组里找到第2子元素并且类名需要是 child,所以可以选中2个子元素

3

例2

调整 html 结构为如下,将span 分类的 第2个样式名更改,会发现变为红色的元素变了。因为 .parent .child:nth-of-type(2) 表示选中将所有类别中第2个元素并且类名是 child 的元素。

<div class="parent">
    <div class="child">div1111</div>
    <span class="child">span1111</span>
    <div class="child">div3333</div>
    <span class="child1">span2222</span>
    <div class="child">div4444</div>
    <div class="child">div5555</div>
</div>

解释下为什么只有一个子元素选中,先按照标签分类,

第1组:
<span class="child">2222</span>
<span class="child1">span2222</span>
第2组:
<div class="child">1111</div>
<div class="child">3333</div>
<div class="child1">4444</div>

再从每一组里找到第2子元素并且类名需要是 child,所以只有第2组的第2个元素满足要求

4

例3

调整 css 为 .parent :nth-of-type(2),表示选中 parent 下所有分类的最后一个子元素,不关注类型是什么

.parent :nth-of-type(2) {
   color: red;
}

5

总结

样式解释
.parent .child:last-child选中 parent 下的最后一个元素,并且类名需要是 child
.parent :last-child表示表中 parent 下最后一个子元素,不关注类型是什么
.parent .child:nth-child(2)选中 parent 下的第2个子元素,并且类名需要是 child
.parent :nth-child(2)表中 parent 下第2个子元素,不关注类型是什么
样式解释
.parent .child:last-of-type先将 parent 下的子元素分类,将所有类别中最后一个元素并且类名是 child 的元素选中
.parent :last-of-type选中 parent 下所有分类的最后一个子元素,不关注类型是什么
.parent .child:nth-of-type(2)先将 parent 下的子元素分类,将所有类别中第2个元素并且类名是 child 的元素选中
.parent :nth-of-type(2)选中 parent 下所有分类的最后一个子元素,不关注类型是什么