CSS的伪类和伪元素举例详解

本文深入讲解CSS伪类与伪元素的应用技巧,包括hover、active、first-child、nth-child及before、after等,通过实例展示如何优化交互效果与布局设计。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

之前介绍了8种选择器,基本上可以应对大部分的开发需求,但是如果不会使用伪类和伪元素,就跟下面的图差不多,后面会摔的。伪元素和伪类虽然不是特别常用,但是,很好用,可以帮你省掉很多无用功,效果还好。下面直接进入正题,尽量用最小的篇幅让人明白如何使用它们。
...

1.伪元素和伪类的区别

  • 伪元素和伪类都是为了给一些特殊需求加样式,定义上基本一致。
  • 伪类像类选择器一样给已存在某个元素添加额外的样式;伪元素则是给自己虚拟的元素添加样式。
  • 已存在元素是指DOM中存在的,伪元素则是虚拟的一种,样式也是给这个虚拟的元素使用的。比如虚拟一个div
  • 声明不同,伪类和选择器之间用一个冒号隔开,伪元素则是两个冒号隔.

2.常用的伪类

常用的伪类有两类UI伪类和结构伪类。这里只介绍5个,应该足够用了。

2.1 hover和active

这两个属于UI伪类(link/visited/active/hover)四个中的其中两个。

  • hover指当鼠标移动到元素上时触发某种样式activate指鼠标按下时的某种样式
  • hover使用场景:一些可点击的列表,表格行,卡片等,鼠标放上去之后背景颜色会发生变化,就可以使用hover。
  • active使用场景:按钮按下,图片按下以及一些可点击元素或者组件等的按下操作样式改变。
    下面是一个非常简单的按钮案例(在线MP4转GIF不知道这个图能存在多久,看不见的底下评论提醒我):
    在这里插入图片描述
    第一个按钮当鼠标放上去是改变边框和字体颜色第二则是在鼠标按下的时候改变背景和颜色。具体代码如下
    .btn{
            height: 34px;
            padding: 6px 12px;
            border-radius: 4px;
            font-size: 15px;
            color: rgba(0,0,0,.65);
            font-weight: 400;
            outline: none;
            border: 1px solid #cbcbcb;
        }
        .btn:hover{
            border-color: #3385ff;
            color: #3385ff;
        }
        
        .btn2{
            height: 34px;
            padding: 6px 12px;
            border-radius: 4px;
            font-size: 15px;
            color: #fff;
            background: #3385ff;
            border-width: 0;
            font-weight: 400;
            outline: none;
        }
        .btn2:active{
            border: 1px solid #3385ff;
            color: #3385ff;
            background: #fff;
        }

HTML:

        <div>
            <button class="btn">按钮</button>
            <button class="btn2">按钮</button>
        </div>

使用非常简单,就是在类选择器后面使用一个冒号后面根据需求是鼠标放上去时触发还是按下时触发决定使用哪一个伪类。如上面第一个btn是( .btn:hover ) 第二个则是( .btn2:active )。

2.2 first-child last-child nth-child(n/odd/even)

这三个属于结构伪类,常用来给表格或者列表添加样式。

  • 假设父元素是一个div,使用样式class=‘box’;
  • 那么当定义.box:first-child或者.box:last-child时分别是指给div的第一个或者最后一个子元素添加样式
  • nth-child这个就比较牛掰了,参数是一个数值代表给第几个元素添加样式,如果是odd标示给元素为奇数的添加样式,even则是给是偶数的元素添加样式

看个例子,首行添加灰色背景,其他奇数行橙色背景的一个表格
表格

css(简单不):

        td,th {
            padding: 12px;
        }
        
        table tr:nth-child(odd){
            background: #ffab00;
        }
        
        table tr:first-child{
            background: #ccc;
        }

html(也很简单都是重复的):

		<table border="1" frame="box" rules="all" width="50%">
            <tr>
                <th>标题1</th>
                <th>标题2</th>
                <th>标题3</th>
                <th>标题4</th>
            </tr>
            <tr>
                <td>content-1</td>
                <td>content-1</td>
                <td>content-1</td>
                <td>content-1</td>
            </tr>
            <tr>
                <td>content-2</td>
                <td>content-2</td>
                <td>content-2</td>
                <td>content-2</td>
            </tr>
            <tr>
                <td>content-3</td>
                <td>content-3</td>
                <td>content-3</td>
                <td>content-3</td>
            </tr>
            <tr>
                <td>content-4</td>
                <td>content-4</td>
                <td>content-4</td>
                <td>content-4</td>
            </tr>
            <tr>
                <td>content-5</td>
                <td>content-5</td>
                <td>content-5</td>
                <td>content-5</td>
            </tr>
         </table>

3.常用伪元素

before 和 after是经常经常重用的伪元素。我们直接看两个最简单的例子。再一句话的前面(before)和后面(after)分别添加一个圆形和一个矩形。简单样例

    <p class="eazy">我就是那句话!</p>

css:

        .eazy{
            font-size: 18px;
        }
        
        .eazy::before{
            content:'';
            display: inline-block;
            width: 10px;
            height:10px;
            background: #ffab00;
            border-radius:50%;
        }
        
        .eazy::after{
            content:'';
            display: inline-block;
            width: 10px;
            height:10px;
            background: #3385ff;
        }
  • 双冒号后面跟跟关键字before或者after,在后面的内容即是要给这个伪元素添加的样式
  • 其中content属性一定要设置,可以设置为空,否则不会显示;
  • 其次,设置了依然没有显示就要设置表明这个伪元素块级元素

3.1 在来看两个例子,项目开发中经常要画一些气泡,比如

气泡
这是两种气泡,带有背景色的和带有边框的,实现上稍微有些区别,但是他们的小突起就是用伪元素画的。
HTML:

        <div class="bubble-box">
            <div class="bubble-left">
                Hello, can I have a star?
            </div>
            &nbsp;&nbsp;&nbsp;
            <div class="bubble-top">
                Hello, can I have a star?
            </div>
            &nbsp;&nbsp;&nbsp;
            <div class="bubble-bottom">
                Hello, can I have a star?
            </div>
            &nbsp;&nbsp;&nbsp;
            <div class="bubble-right">
                Hello, can I have a star?
            </div>
            &nbsp;&nbsp;&nbsp;
            <div class="bubble-noColor">
                Hello, can I have a star?
            </div>
        </div>

css有点长,但是仔细观察90%的代码都是重复的并不难。主要变动是使用定位position属性控制小突起的位置,以及border-color来控制凸起箭头的朝向。三角形的画法原理可以看这里!

  .bubble-box{
            display: flex;
            padding: 10px;
        }
        .bubble-top{
            width: 120px;
            padding: 10px;
            background: #3385ff;
            border-radius: 6px;
            position: relative;
            color:#fff;
        }
        
        .bubble-top::before{
            content: '';
            width: 0;
            height: 0;
            position: absolute;
            border:6px solid #3385ff;
            border-color: transparent transparent #3385ff transparent;
            left: 46%;
            top: -12px;
        }
        
        .bubble-left{
            width: 120px;
            padding: 10px;
            background: #3385ff;
            border-radius: 6px;
            position: relative;
            color:#fff;
        }
        
        .bubble-left::before{
            content: '';
            width: 0;
            height: 0;
            position: absolute;
            border:6px solid #3385ff;
            border-color: transparent #3385ff transparent transparent;
            left: -12px;
            top: 24px;
        }
        
        .bubble-bottom{
            width: 120px;
            padding: 10px;
            background: #3385ff;
            border-radius: 6px;
            position: relative;
            color:#fff;
        }
        
        .bubble-bottom::before{
            content: '';
            width: 0;
            height: 0;
            position: absolute;
            border:6px solid #3385ff;
            border-color: #3385ff transparent transparent transparent;
            left: 46%;
            bottom: -12px;
        }
        
        .bubble-right{
            width: 120px;
            padding: 10px;
            background: #3385ff;
            border-radius: 6px;
            position: relative;
            color:#fff;
        }
        
        .bubble-right::before{
            content: '';
            width: 0;
            height: 0;
            position: absolute;
            border:6px solid #3385ff;
            border-color: transparent transparent transparent #3385ff;
            right: -12px;
            top: 24px;
        }
        
        .bubble-noColor{
            width: 120px;
            padding: 10px;
            border:1px solid #ccc;
            border-radius: 6px;
            position: relative;
            color:#0f0f0f;
        }
        
        .bubble-noColor::before{
            content: '';
            width: 9px;
            height: 9px;
            border-top: 1px solid #ccc;
            border-left: 1px solid #ccc;
            background: white;
            transform: rotate(45deg);
            position: absolute;
            left: 46%;
            top: -6px;
        }

3.2 利用伪元素画一个时间轴

如图
时间轴
解析

  • 每一行都只设置左边框,这样就这回出现一条竖线。
  • 然后每一行前面加一个圆点,就会呈现时间轴的样式,加圆点当然是用伪元素了。

先看HTML,很简单:

       <div>
            <ul class="list">
                <li>2018-11-15 吃了好吃的</li>
                <li>2018-11-16 不开心</li>
                <li>2018-11-18 蓝瘦香菇</li>
                <li>2018-11-23 滚蛋</li>
                <li>2018-12-10 嗯哼随心随遇把</li>
            </ul>
        </div>

css 先给li标签设置左边框border-left,

        .list{
            padding: 10px;
            border: 1px solid #fff;
        }
        .list li{
            list-style: none;
            padding: 10px;
            border-left: 1px solid #ccc;
        }

第二步,添加伪元素

        .list li::before{
            content: '';
            display: inline-block;
            width: 6px;
            position: absolute;
            height: 6px;
            left: 16px;
            margin-top: 7px;
            border: 1px solid #ffab00;
            border-radius: 50%;
            background: #3385ff;
        }

3.3 伪元素怎么添加内容的

伪元素虽然是不存在于DOM树种的元素,但是也是可以添加内容的,就是上面提到的content属性。content属性可以是URL、字符串甚至是图片,视频等

我们把第三节刚开始的那个前后圆形和矩形的content设置为’1’和’2’.就变成这样了。
content 有值
所以content就是这只伪元素中内容的入口,这也解释了为什么不设置这个属性就不显示的原因,哪怕设置为空,也相当于我定义了这个伪元素

最后再看一个例子:
目录结构

如果人工去标示会非常的消耗成本,实际上伪元素就可以轻松解决这个问题。content + counters实现目录结构。
HTML:

        <div class="list2">
            <ul>
                <li>吃了好吃的
                    <ul>
                        <li>content</li>
                        <li>content</li>
                        <li>content</li>
                    </ul>
                </li>
                <li>不开心</li>
                <li>蓝瘦香菇
                    <ul>
                        <li>content</li>
                        <li>content</li>
                        <li>content</li>
                    </ul>
                </li>
                <li>滚蛋</li>
                <li>嗯哼随心随遇把</li>
            </ul>
        </div>

css counter-reset定义一个计数器后面跟一个名字,这个属性在哪个元素上设置则标示遇到这个元素我就重新开始计数,如上面的HTML,我们把这个属性设置到ul上,则遇到ul就重新计数(添加一个新的计数器,原计数器不受影响)。

        .list2{
            padding: 10px;
            border: 1px solid #ccc;
        }
        .list2 li{
            list-style: none;
        }
        .list2 ul{
            counter-reset: xuhao;
        }
        
        .list2 li::before{
            counter-increment: xuhao;
            content: counters(xuhao, ".") " ";
        }

在li元素的伪元素上接受这个计数值通过counters,第一参数接收计数器,第二参数指明新的计数值以什么字符链接在上一级计数值得后面

<think>我们已经了解了用户的需求,他想要了解CSS伪元素的区别及用法。根据之前的对话历史,用户已经看到了一些关于伪元素的引用内容,现在需要我进行更清晰的解释总结。首先,回顾一下引用内容:引用[1]提到伪元素是两种不同的选择器,用于定义元素的特殊状态,而伪元素用于创建样式化不在文档树中的元素。引用[2]详细解释了伪元素的区别,并指出:-根据状态改变元素样式,是对选择器的扩展;-伪元素则是在逻辑上创建虚拟的新元素,可以给新元素添加样式。-使用单冒号,伪元素CSS3中引入了双冒号(但也支持单冒号),建议使用双冒号以区分。-一个选择器可以同时使用多个,但只能使用一个伪元素(多个伪元素无效)。引用[3]再次强调了的作用:选择HTML元素的特定状态或位置,应用特殊样式。因此,我的回答需要整合这些信息,并清晰地分点说明两者的区别,同时给出用法示例。计划结构:1.定义:解释的概念,举例说明常用(如:hover,:active,:nth-child等),以及它们的作用(改变元素在特定状态下的样式)。2.定义伪元素:解释伪元素的概念,举例说明常用伪元素(如::before,::after,::first-line等),以及它们的作用(创建虚拟元素并设置样式)。3.主要区别:从作用、语法、使用限制等方面对比。4.用法示例:用代码展示两者不同的使用场景。需要注意的是,在CSS3中,为了区分伪元素,规定伪元素使用双冒号(::),而使用单冒号(:)。但为了兼容旧的写法,伪元素也可以使用单冒号,但推荐使用双冒号。另外,根据引用[2]中的例子,说明选择器可以同时使用多个(如div:first-child:hover),而伪元素不能连续使用(如.province::before::first-letter无效)。最后,生成相关问题供用户进一步学习。注意:回答中引用的内容要添加引用标识。</think> ### CSS伪元素的区别及用法详解 #### 一、核心概念差异 1. **(Pseudo-classes)** - 作用:基于元素的状态或位置进行选择 - 语法:使用单冒号`:`(如`:hover`、`:active`) - 本质:选择**已存在元素**的特殊状态 - 示例: ```css /* 鼠标悬停状态 */ a:hover { color: red; } /* 访问过的链接 */ a:visited { color: purple; } /* 第一个子元素 */ li:first-child { font-weight: bold; } ``` 2. **伪元素(Pseudo-elements)** - 作用:创建**不在文档树中的虚拟元素** - 语法:使用双冒号`::`(如`::before`、`::first-line`) - 本质:生成并样式化**新的虚拟元素** - 示例: ```css /* 在元素前插入内容 */ p::before { content: "▶"; color: green; } /* 选择首行文本 */ article::first-line { font-variant: small-caps; } ``` #### 二、关键区别总结 | **特性** | | 伪元素 | |------------------|-------------------------------|----------------------------| | 选择目标 | 选择**已有元素**的特定状态 | 创建**新的虚拟元素** | | 语法 | 单冒号 `:`(如`:hover`) | 双冒号 `::`(如`::before`) | | 可叠加性 | 可多个组合(如`:hover:active`)| 不可叠加(如`::before::after`无效)[^2] | | DOM表现 | 不修改DOM结构 | 在渲染层创建虚拟节点 | | 典型应用 | 交互状态、结构选择 | 装饰性内容、文本片段控制 | #### 三、使用场景对比 1. **典型场景** ```css /* 表单元素状态 */ input:disabled { opacity: 0.5; } /* 子元素位置选择 */ tr:nth-child(odd) { background: #eee; } /* 用户交互反馈 */ button:active { transform: scale(0.98); } ``` 2. **伪元素典型场景** ```css /* 添加装饰性内容 */ blockquote::after { content: "”"; font-size: 2em; } /* 首字母下沉效果 */ p::first-letter { font-size: 200%; float: left; } /* 自定义选中文本样式 */ ::selection { background: yellow; color: black; } ``` #### 四、混合使用示例 ```css /* 组合使用:悬停时在链接前添加图标 */ a:hover::before { content: "→ "; color: blue; } /* 首个子元素的首行文本 */ article:first-child::first-line { letter-spacing: 1px; } ``` > **语法最佳实践**: > 虽然浏览器支持单冒号伪元素(如`:before`),但根据CSS3规范建议: > - **始终用** `:`(如`:nth-child()`) > - 伪元素**始终用** `::`(如`::first-letter`) > 以明确区分两者,提高代码可读性[^2]。 #### 五、注意事项 1. **不可堆叠限制**:伪元素不能连续使用(如`div::before::after`无效) 2. **内容属性要求**:`::before`/`::after`必须定义`content`属性(空值也需设置:`content: ""`) 3. **表单元素限制**:伪元素在`<input>`、`<img>`等替换元素上部分效果受限 4. **可访问性考量**:伪元素内容不会被屏幕阅读器识别,重要内容需使用真实DOM
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值