欢迎光临
我们一直在努力

第07篇:伪元素详解

第07篇:伪元素详解

如果说伪类是给已有元素添加"状态",那伪元素就是凭空"创造"元素。::before 和 ::after 可以在不修改 HTML 的情况下,在元素前后插入内容,是 CSS 中最具创造性的特性之一。


学习目标

  • 理解伪元素与伪类的本质区别
  • 掌握 ::before 和 ::after 的基本用法与 content 属性
  • 学会用伪元素创建装饰性元素(引号、分隔线、图标、背景等)
  • 了解 ::first-line、::first-letter、::selection 的排版增强能力
  • 掌握伪元素的层叠上下文和定位技巧

核心知识点

一、伪元素 vs 伪类

伪类 (Pseudo-class)伪元素 (Pseudo-element)
符号 : ::
作用 选中元素的状态 在元素前后创建虚拟内容
典型 :hover、:nth-child() ::before、::after
数量 不影响 DOM 元素数量 每个元素可创建 2 个伪元素

💡 CSS2 中伪元素也用单冒号 :before,CSS3 规范改为 ::before 以区分。现代浏览器两种写法都支持,但推荐使用双冒号。


二、::before 与 ::after

基本语法

/* 在元素内容前面插入 */
.element::before {
content: "前缀";
color: #999;
}

/* 在元素内容后面插入 */
.element::after {
content: "后缀";
color: #999;
}

关键点:

  • content 属性必须存在,即使值为空字符串 content: ""
  • 伪元素默认是行内元素(display: inline)
  • 每个真实元素最多有 2 个伪元素(一个 ::before,一个 ::after)
创建一个视觉元素

/* 用空 content + 样式创建纯视觉元素 */
.divider::before {
content: "";
display: block;
width: 100%;
height: 1px;
background: linear-gradient(90deg, transparent, #ddd, transparent);
}


三、content 属性详解

content 是伪元素的灵魂,它决定了伪元素"显示什么"。

1. 纯文本

.price::before {
content: "¥";
font-size: 0.8em;
}

.tag::after {
content: " HOT";
color: #e74c3c;
font-size: 0.7em;
vertical-align: super;
}

2. 属性值引用

<a href="https://example.com" data-tooltip="点击查看详情">链接</a>

/* 显示元素的属性值 */
a[href^="http"]::after {
content: " (" attr(href) ")"; /* 显示链接地址 */
color: #999;
font-size: 0.85em;
}

/* 用 data 属性实现工具提示 */
.tooltip::after {
content: attr(data-tooltip);
position: absolute;
background: #333;
color: white;
padding: 6px 12px;
border-radius: 4px;
font-size: 14px;
white-space: nowrap;
opacity: 0;
transition: opacity 0.3s;
}

.tooltip:hover::after {
opacity: 1;
}

3. Unicode 字符和图标

/* 使用 Unicode 字符 */
.external-link::after {
content: "\\2197"; /* ↗ 箭头 */
margin-left: 4px;
}

.success::before {
content: "\\2713"; /* ✓ 对勾 */
color: #2ecc71;
margin-right: 6px;
}

/* 使用 emoji */
.warning::before {
content: "\\26A0\\FE0F"; /* ⚠️ 警告 */
margin-right: 6px;
}

4. 计数器

/* 自动编号 */
ol.chapter {
counter-reset: chapter; /* 初始化计数器 */
}

ol.chapter li::before {
counter-increment: chapter; /* 计数器 +1 */
content: "第 " counter(chapter) " 章:";
font-weight: bold;
color: #4a90d9;
}

/* 多级嵌套计数器 */
ol.nested {
counter-reset: item;
}

ol.nested li::before {
counter-increment: item;
content: counters(item, ".") " "; /* 1.1, 1.2, 2.1… */
color: #666;
}

5. 空 content(纯视觉装饰)

/* 清浮动 */
.clearfix::after {
content: "";
display: table;
clear: both;
}

/* 背景装饰 */
.card::before {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
height: 4px;
background: linear-gradient(90deg, #667eea, #764ba2);
}


四、伪元素实战应用

1. 引号装饰

.quote {
position: relative;
padding: 20px 40px;
font-style: italic;
color: #555;
}

/* 大引号装饰 */
.quote::before {
content: "\\201C"; /* 左双引号 " */
position: absolute;
top: -10px;
left: 10px;
font-size: 60px;
color: #ddd;
font-family: Georgia, serif;
line-height: 1;
}

.quote::after {
content: "\\201D"; /* 右双引号 " */
position: absolute;
bottom: -30px;
right: 10px;
font-size: 60px;
color: #ddd;
font-family: Georgia, serif;
line-height: 1;
}

2. 带图标的列表

.feature-list {
list-style: none;
padding: 0;
}

.feature-list li {
padding: 10px 0 10px 30px;
position: relative;
}

.feature-list li::before {
content: "\\2713"; /* ✓ */
position: absolute;
left: 0;
color: #2ecc71;
font-weight: bold;
}

/* 不同类型的图标 */
.feature-list li.warning::before {
content: "\\26A0"; /* ⚠ */
color: #ffc107;
}

.feature-list li.error::before {
content: "\\2717"; /* ✗ */
color: #e74c3c;
}

3. 工具提示(Tooltip)

.tooltip {
position: relative;
cursor: help;
border-bottom: 1px dashed #999;
}

/* 提示文字 */
.tooltip::after {
content: attr(data-tip);
position: absolute;
bottom: 100%;
left: 50%;
transform: translateX(-50%) translateY(-8px);
background: #333;
color: white;
padding: 8px 14px;
border-radius: 6px;
font-size: 14px;
white-space: nowrap;
opacity: 0;
visibility: hidden;
transition: all 0.3s ease;
}

/* 小三角箭头 */
.tooltip::before {
content: "";
position: absolute;
bottom: 100%;
left: 50%;
transform: translateX(-50%) translateY(-2px);
border: 6px solid transparent;
border-top-color: #333;
opacity: 0;
visibility: hidden;
transition: all 0.3s ease;
}

/* 悬停时显示 */
.tooltip:hover::before,
.tooltip:hover::after
{
opacity: 1;
visibility: visible;
}

4. 图片遮罩效果

.image-overlay {
position: relative;
display: inline-block;
}

.image-overlay img {
display: block;
}

/* 渐变遮罩 */
.image-overlay::after {
content: "";
position: absolute;
inset: 0; /* 等价于 top:0; right:0; bottom:0; left:0 */
background: linear-gradient(to top, rgba(0,0,0,0.7), transparent 50%);
pointer-events: none; /* 让鼠标事件穿透到图片 */
}

/* 遮罩上的文字 */
.image-overlay .caption {
position: absolute;
bottom: 16px;
left: 16px;
right: 16px;
color: white;
z-index: 1;
}

5. 自定义复选框(纯 CSS)

/* 隐藏原生复选框 */
.custom-checkbox input[type="checkbox"] {
position: absolute;
opacity: 0;
width: 0;
height: 0;
}

/* 自定义方框 */
.custom-checkbox label {
position: relative;
padding-left: 32px;
cursor: pointer;
line-height: 24px;
display: inline-block;
}

.custom-checkbox label::before {
content: "";
position: absolute;
left: 0;
top: 0;
width: 20px;
height: 20px;
border: 2px solid #ddd;
border-radius: 4px;
transition: all 0.2s;
}

/* 选中状态:背景变蓝 + 对勾 */
.custom-checkbox input:checked + label::before {
background: #4a90d9;
border-color: #4a90d9;
}

.custom-checkbox input:checked + label::after {
content: "";
position: absolute;
left: 7px;
top: 3px;
width: 5px;
height: 10px;
border: solid white;
border-width: 0 2px 2px 0;
transform: rotate(45deg);
}

/* 聚焦状态 */
.custom-checkbox input:focus + label::before {
box-shadow: 0 0 0 3px rgba(74, 144, 217, 0.3);
}


五、排版伪元素

::first-line — 首行样式

/* 文章段落的首行加大、加粗 */
article p::first-line {
font-weight: bold;
font-size: 1.1em;
line-height: 1.4;
}

/* 注意:只能用于块级元素,且只能设置以下属性:
font、color、background、word-spacing、letter-spacing、
text-decoration、text-transform、line-height
*/

::first-letter — 首字下沉

/* 杂志风格的首字下沉 */
.article-body::first-letter {
float: left;
font-size: 3.5em;
line-height: 1;
padding-right: 8px;
color: #4a90d9;
font-family: Georgia, serif;
}

::selection — 选中文本的样式

/* 自定义文字选中的高亮色 */
::selection {
background: #4a90d9;
color: white;
}

/* 特定元素的选中文本 */
.dark-section ::selection {
background: #ffc107;
color: #1a1a2e;
}

/* 注意:::selection 只能设置 color、background-color、text-shadow 等少数属性 */

::placeholder — 占位符样式

input::placeholder {
color: #bbb;
font-style: italic;
}

input:focus::placeholder {
color: #ddd; /* 获得焦点时占位符变淡 */
}


六、伪元素的定位与层叠

伪元素的包含块

伪元素的包含块就是其依附的元素。

.card {
position: relative; /* 给伪元素创建定位上下文 */
}

/* 角标 */
.card::before {
content: "NEW";
position: absolute;
top: -10px;
right: -10px;
background: #e74c3c;
color: white;
padding: 4px 12px;
font-size: 12px;
border-radius: 4px;
}

伪元素的层叠顺序

默认情况下,::before 在内容下方,::after 在内容上方。

.layer-demo {
position: relative;
}

/* z-index 控制层叠 */
.layer-demo::before {
content: "";
position: absolute;
z-index: -1; /* 放到最底层 */
background: #e3f2fd;
}

.layer-demo::after {
content: "";
position: absolute;
z-index: 1; /* 放到最上层 */
background: rgba(0,0,0,0.5);
}


动手练习

练习 1:创建步骤指示器

用伪元素创建一个横向的步骤指示器(Stepper),要求:

  • 每个步骤之间有连接线(用 ::before 或 ::after)
  • 已完成步骤为蓝色,当前步骤为橙色,未开始为灰色
  • 步骤编号用计数器自动生成

练习 2:面包屑导航

实现面包屑导航,要求用伪元素在每个链接后添加 > 分隔符,但最后一个不添加:

<nav class="breadcrumb">
<a href="#">首页</a>
<a href="#">分类</a>
<a href="#">子分类</a>
<span>当前页面</span>
</nav>

练习 3:加载动画

用 ::before 和 ::after 创建一个纯 CSS 的加载动画:

  • 两个伪元素都是圆形,不同大小
  • 一个顺时针旋转,一个逆时针旋转
  • 使用 border 的透明部分实现圆弧效果

常见误区 ⚠️

误区真相
“伪元素是真实 DOM 元素” 伪元素不在 DOM 树中,无法用 JS 直接操作(但可以通过 CSS 变量间接控制)
“content 可以省略” content 必须存在,即使是空字符串。不写 content 伪元素不会显示
“伪元素可以添加在所有元素上” 大多数元素支持,但替换元素(如 img、input、iframe)的伪元素支持有限或不稳定
“::before 在内容前面,::after 在内容后面,所以 before 的 z-index 更低” 默认 ::before 确实在内容下层、::after 在上层,但可以用 z-index 改变
“伪元素可以无限嵌套” 每个元素最多只有 ::before 和 ::after 两个伪元素,伪元素自身不能再有伪元素
“content: url('image.png') 和 background-image 一样” content: url() 插入的图片无法控制尺寸,且会被拉伸失真。装饰性图片建议用 background-image
“::selection 可以设置任意样式” 只能设置 color、background-color、text-shadow 等少数属性
“伪元素的内容可以被选中复制” ::before/::after 生成的文本可以被选中复制,但计数器生成的数字不行

速查卡片 📋

常用伪元素

伪元素作用
::before 元素内容之前插入
::after 元素内容之后插入
::first-line 首行样式
::first-letter 首字样式
::selection 选中文本样式
::placeholder 占位符样式

content 取值类型

写法示例
文本 content: "前缀"
Unicode content: "\\2713"
属性 content: attr(data-tip)
计数器 content: counter(item)
content: ""
URL(不推荐) content: url(icon.png)

伪元素必备三件套

.element::before {
content: ""; /* 必须 */
display: block; /* 视情况 */
position: absolute; /* 视情况 */
}


扩展阅读

  • MDN: 伪元素
  • MDN: ::before
  • MDN: ::after
  • CSS-Tricks: A Whole Bunch of Amazing Stuff Pseudo Elements Can Do(英文)
  • CSS 计数器详解

📌 配套代码:

  • CODE/07/pseudo-elements-decoration.html — 装饰性伪元素实战
  • CODE/07/pseudo-elements-tooltip.html — 工具提示完整示例

🎉 下一步:进入 第08篇:字体与排版基础,学习如何让文字看起来更专业。

赞(0)
未经允许不得转载:171主机测评 » 第07篇:伪元素详解
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址