一、伪元素(Pseudo-elements)

1.1 核心概念

伪元素是CSS中用于创建并设置文档中特定部分样式的虚拟元素,它们不存在于DOM中,但表现得如同真实元素。伪元素以**双冒号::**为前缀(CSS3规范),用于区分伪类(单冒号:)。

核心作用

  • 生成装饰性内容(如图标、分隔线)
  • 操作文本特定部分(如首字母、首行)
  • 避免为样式单独添加无意义的HTML元素(语义化优化)

1.2 常用伪元素及语法

1.2.1 ::before::after

在元素内容前/后插入虚拟内容,需配合content属性使用。

伪元素 位置 核心用途
::before 元素内容之前 添加图标、前缀文本、装饰性元素
::after 元素内容之后 添加图标、后缀文本、清除浮动(经典 clearfix 方案)

基础语法

/* 语法结构 */
选择器::before {
  content: "插入内容"; /* 必选属性,可取值:字符串、url()、attr()等 */
  /* 其他样式属性 */
}

/* 示例1:添加图标前缀 */
.btn::before {
  content: "→"; /* 插入箭头符号 */
  margin-right: 8px; /* 与文本间距 */
  color: #165DFF;
}

/* 示例2:清除浮动(clearfix方案) */
.clearfix::after {
  content: ""; /* 空内容 */
  display: block; /* 转为块级元素 */
  clear: both; /* 清除左右浮动 */
  height: 0; /* 避免占据空间 */
  visibility: hidden;
}

1.2.2 文本相关伪元素

伪元素 作用 适用场景
::first-letter 选中元素首字母 段落首字母下沉排版
::first-line 选中元素首行文本 首行文本特殊样式(如加粗)
::selection 选中用户鼠标高亮的文本部分 自定义选中文本背景色

示例

/* 首字母下沉 */
.article p::first-letter {
  font-size: 2em;
  font-weight: bold;
  color: #165DFF;
  float: left;
  margin-right: 5px;
}

/* 自定义选中文本样式 */
::selection {
  background: #FFE066; /* 黄色背景 */
  color: #333; /* 深灰文本 */
}

1.3 伪元素实战案例

案例1:装饰性按钮(带前后图标)

<button class="decorative-btn">提交订单</button>

<style>
.decorative-btn {
  padding: 10px 20px;
  border: none;
  background: #165DFF;
  color: white;
  border-radius: 4px;
  font-size: 16px;
  cursor: pointer;
}

/* 前图标 */
.decorative-btn::before {
  content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' viewBox='0 0 16 16'%3E%3Cpath d='M8 16s6-5.686 6-10A6 6 0 0 0 2 6c0 4.314 6 10 6 10zm0-7a3 3 0 1 1 0-6 3 3 0 0 1 0 6z'/%3E%3C/svg%3E");
  margin-right: 8px;
  vertical-align: middle;
}

/* 后图标 */
.decorative-btn::after {
  content: "→";
  margin-left: 8px;
  transition: transform 0.3s ease;
}

/* 悬停效果 */
.decorative-btn:hover::after {
  transform: translateX(3px); /* 箭头右移 */
}
</style>

案例2:使用::after实现三角形箭头

.arrow {
  width: 0;
  height: 0;
  border-style: solid;
  border-width: 8px 0 8px 10px;
  border-color: transparent transparent transparent #333;
}

/* 等价于使用伪元素生成 */
.arrow::after {
  content: "";
  display: inline-block;
  width: 0;
  height: 0;
  border-style: solid;
  border-width: 8px 0 8px 10px;
  border-color: transparent transparent transparent #333;
}

二、CSS优先级计算

2.1 优先级概念

CSS优先级是浏览器决定哪个样式规则应用于元素的算法,当多个规则匹配同一元素时,优先级高的规则会覆盖优先级低的规则。

2.2 优先级权重计算规则

优先级通过权重值衡量,权重值越高,优先级越高。权重计算基于选择器类型,具体规则如下:

选择器类型 权重值(十进制) 示例
!important 无穷大 color: red !important;
内联样式(style属性) 1000 <div style="color: red">
ID选择器 0100 #header { ... }
类选择器/伪类/属性选择器 0010 .active { ... }:hover { ... }[type="text"] { ... }
元素选择器/伪元素 0001 div { ... }::before { ... }
通配符(*)/组合符 0000 * { ... }div p { ... }

计算方法
将选择器中各类选择器的权重值相加,从左到右比较,左侧数值大的优先级更高(不进位)。

示例对比:

选择器组合 权重值(千位-百位-十位-个位) 优先级排序(由高到低)
div#header .nav li.active 0-1-2-2(ID:1,类:2,元素:2) 1
#header .active 0-1-1-0(ID:1,类:1) 2
div.nav .active 0-0-2-1(类:2,元素:1) 3
div ul li 0-0-0-3(元素:3) 4

2.3 优先级特殊规则

2.3.1 !important 优先级最高

!important 会覆盖所有普通规则,但需注意:

  • 仅作用于属性值,不影响选择器优先级
  • 避免滥用(破坏样式层级关系,难以维护)
  • 内联样式 + !important > 外部样式 + !important

示例

/* 即使ID选择器权重更高,但!important覆盖 */
#box {
  color: blue; /* 权重0-1-0-0 */
}
.text {
  color: red !important; /* 权重0-0-1-0,但!important优先级更高 */
}

2.3.2 继承样式优先级最低

元素从父元素继承的样式优先级低于所有直接应用的样式
示例

.parent {
  color: red; /* 父元素样式 */
}
.child {
  color: blue; /* 子元素直接样式,覆盖继承样式 */
}

2.3.3 相同优先级时,后定义的规则生效

当两个规则权重完全相同时,后出现的规则会覆盖先出现的规则。
示例

/* 优先级相同,后者生效 */
.box { color: red; }
.box { color: blue; } /* 最终文本为蓝色 */

2.4 优先级实战技巧

技巧1:避免过度嵌套选择器

嵌套层级越深,权重计算越复杂,且可能导致优先级过高难以覆盖。
反例

/* 过度嵌套,权重冗余 */
div.container > section.content > article.post > h2.title {
  color: #333;
}

优化

/* 精简为类选择器,权重清晰 */
.post-title {
  color: #333;
}

技巧2:使用优先级计算器验证

复杂选择器可通过在线工具(如 Specificity Calculator)计算权重,避免手动计算错误。

技巧3:利用伪类提升优先级

当需要微调样式且避免使用!important时,可叠加伪类:not()提升权重(不影响逻辑)。
示例

/* 原权重0-0-1-0 */
.btn { padding: 8px; }

/* 叠加:not()后权重0-0-2-0,优先级提升 */
.btn:not(.none) { padding: 10px; }

三、注意事项

3.1 伪元素的常见误区

  • ❌ 错误:为伪元素添加content属性后未设置display类型,导致样式不生效
    ✅ 正确:根据需求设置display: inline-block/block(如::after清除浮动需设为block
  • ❌ 错误:使用单冒号:定义CSS3伪元素(如:before
    ✅ 正确:CSS3规范中伪元素需用双冒号::,但为兼容旧浏览器,单冒号仍可识别(建议双冒号)

3.2 优先级调试技巧

  • 使用浏览器开发者工具(Elements > Styles)查看已应用样式,被划掉的样式表示被覆盖
  • 在样式后添加!important临时测试优先级问题(调试后移除)
  • 通过添加/移除选择器类型(如临时添加ID)快速定位权重问题

四、自测题

  1. 以下CSS选择器的优先级从高到低排序正确的是:
    A. #nav .item.nav-itemdiv ul lidiv
    B. div#nav .item#nav .item.nav .itemdiv.item
    C. ::beforediv::before.box::before#box::before

  2. 如何仅使用CSS实现“点击按钮时,按钮文本前添加√图标”的效果?(提示:结合:active伪类和::before伪元素)

  3. 解释为什么以下代码中文本最终颜色为蓝色:

    .container p { color: red; }
    #content p { color: blue; }
    <div class="container" id="content">
      <p>文本内容</p>
    </div>
    

(答案见附录C)