伪元素选择器

伪元素选择器用于选择元素的特定部分,而不是整个元素本身。伪元素选择器以双冒号 :: 开头(CSS2 中使用单冒号 :),能够让我们对元素的特定部分应用样式,或者在不修改 HTML 的情况下添加内容。

::before 伪元素

::before 伪元素在被选元素的内容前面插入内容。它常用于添加装饰性内容或图标。

基本语法

选择器::before {
  content: "内容";
  /* 其他样式 */
}

基本用法

/* 在标题前添加装饰 */
h1::before {
  content: "★ ";
  color: #f39c12;
}

/* 在链接前添加图标 */
a::before {
  content: "→ ";
  color: #3498db;
}

/* 在引用前添加符号 */
blockquote::before {
  content: "“";
  font-size: 3em;
  color: #bdc3c7;
  float: left;
  margin-right: 10px;
}

实际应用

/* 导航链接 */
.nav-link::before {
  content: "";
  display: inline-block;
  width: 8px;
  height: 8px;
  background: #3498db;
  border-radius: 50%;
  margin-right: 8px;
}

/* 列表项 */
.feature-item::before {
  content: "✓";
  color: #28a745;
  font-weight: bold;
  margin-right: 10px;
}

/* 警告信息 */
.warning::before {
  content: "⚠️ ";
  font-size: 1.2em;
}

::after 伪元素

::after 伪元素在被选元素的内容后面插入内容。它常用于添加装饰性内容、清除浮动或创建复杂的视觉效果。

基本语法

选择器::after {
  content: "内容";
  /* 其他样式 */
}

基本用法

/* 在链接后添加箭头 */
a.external-link::after {
  content: " ↗";
  font-size: 0.8em;
}

/* 在引用后添加符号 */
blockquote::after {
  content: "”";
  font-size: 3em;
  color: #bdc3c7;
  float: right;
  margin-left: 10px;
}

/* 在价格后添加货币符号 */
.price::after {
  content: " 元";
  font-size: 0.8em;
  color: #666;
}

清除浮动

::after 伪元素常用于清除浮动:

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

/* 使用示例 */
<div class="clearfix">
  <div style="float: left;">左侧内容</div>
  <div style="float: right;">右侧内容</div>
</div>

实际应用

/* 按钮悬停效果 */
.button::after {
  content: "→";
  opacity: 0;
  margin-left: 10px;
  transition: all 0.3s ease;
}

.button:hover::after {
  opacity: 1;
  margin-left: 15px;
}

/* 卡片装饰 */
.card::after {
  content: "";
  position: absolute;
  bottom: 0;
  left: 0;
  width: 100%;
  height: 3px;
  background: linear-gradient(90deg, #3498db, #9b59b6);
}

/* 表单必填标记 */
.required-field::after {
  content: " *";
  color: #e74c3c;
}

::first-line 伪元素

::first-line 伪元素选择文本块的第一行。它只适用于块级元素。

基本用法

/* 段落第一行加粗 */
p::first-line {
  font-weight: bold;
  color: #2c3e50;
}

/* 文章首行大写 */
.article-intro::first-line {
  font-size: 1.2em;
  text-transform: uppercase;
  letter-spacing: 1px;
}

/* 引用第一行斜体 */
blockquote::first-line {
  font-style: italic;
  color: #7f8c8d;
}

限制

::first-line 伪元素只能应用以下属性:

  • 字体属性(font)
  • 颜色属性(color)
  • 背景属性(background)
  • 文本属性(text)
  • 行高(line-height)
  • 字间距(letter-spacing)
  • 词间距(word-spacing)
  • 垂直对齐(vertical-align)

::first-letter 伪元素

::first-letter 伪元素选择文本块的第一个字母。它常用于创建首字下沉效果。

基本用法

/* 首字下沉 */
p::first-letter {
  font-size: 3em;
  float: left;
  margin-right: 10px;
  line-height: 1;
  font-weight: bold;
}

/* 章节标题首字母 */
.chapter-title::first-letter {
  font-size: 2em;
  color: #e74c3c;
  font-weight: bold;
}

/* 引用首字母 */
blockquote::first-letter {
  font-size: 2.5em;
  color: #3498db;
  font-weight: bold;
}

实际应用

/* 文章首段首字下沉 */
.article-intro::first-letter {
  font-size: 4em;
  float: left;
  margin-right: 15px;
  margin-bottom: 5px;
  line-height: 0.8;
  font-weight: bold;
  color: #2c3e50;
}

/* 新闻标题首字母 */
.news-title::first-letter {
  font-size: 1.5em;
  color: #e74c3c;
  font-weight: bold;
}

/* 古典风格首字母 */
.classic-text::first-letter {
  font-family: 'Georgia', serif;
  font-size: 3.5em;
  float: left;
  margin-right: 12px;
  margin-bottom: -10px;
  line-height: 0.8;
  color: #8e44ad;
}

伪元素的 content 属性

content 属性是伪元素的核心,用于指定要插入的内容。

字符串内容

/* 插入文本 */
.warning::before {
  content: "警告:";
  color: #e74c3c;
}

/* 插入符号 */
.arrow::after {
  content: " →";
}

URL 内容

/* 插入图片 */
.external-link::before {
  content: url('external-icon.png');
  display: inline-block;
  vertical-align: middle;
  margin-right: 5px;
}

/* 插入背景图片 */
.icon::before {
  content: "";
  display: inline-block;
  width: 16px;
  height: 16px;
  background: url('icon.svg') no-repeat center;
  margin-right: 8px;
}

计数器

/* 定义计数器 */
body {
  counter-reset: section;
}

/* 使用计数器 */
h2::before {
  counter-increment: section;
  content: "第 " counter(section) " 章:";
  color: #3498db;
}

/* 列表计数器 */
ol {
  counter-reset: item;
}

ol li::before {
  counter-increment: item;
  content: counter(item) ". ";
  font-weight: bold;
  color: #2c3e50;
}

属性值

/* 插入属性值 */
a::after {
  content: " (" attr(href) ")";
  font-size: 0.8em;
  color: #999;
}

/* 插入 title 属性 */
[title]::after {
  content: " [" attr(title) "]";
  font-size: 0.9em;
  color: #666;
}

/* 插入 data 属性 */
[data-price]::after {
  content: attr(data-price) " 元";
  color: #e74c3c;
}

引号

/* 自动添加引号 */
q {
  quotes: "“" "”" "‘" "’";
}

q::before {
  content: open-quote;
}

q::after {
  content: close-quote;
}

伪元素的实际应用

卡片组件

.card {
  position: relative;
  padding: 20px;
  background: white;
  border-radius: 8px;
  box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}

/* 卡片顶部装饰线 */
.card::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 4px;
  background: linear-gradient(90deg, #3498db, #9b59b6);
  border-radius: 8px 8px 0 0;
}

/* 卡片底部装饰 */
.card::after {
  content: "";
  position: absolute;
  bottom: 0;
  left: 0;
  width: 100%;
  height: 2px;
  background: #ecf0f1;
}

按钮组件

.button {
  position: relative;
  display: inline-block;
  padding: 12px 24px;
  background: #007bff;
  color: white;
  text-decoration: none;
  border-radius: 4px;
  overflow: hidden;
}

/* 按钮悬停效果 */
.button::before {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 0;
  height: 0;
  background: rgba(255,255,255,0.2);
  border-radius: 50%;
  transform: translate(-50%, -50%);
  transition: width 0.6s ease, height 0.6s ease;
}

.button:hover::before {
  width: 300px;
  height: 300px;
}

/* 按钮箭头 */
.button-arrow::after {
  content: "→";
  margin-left: 10px;
  transition: transform 0.3s ease;
}

.button-arrow:hover::after {
  transform: translateX(5px);
}

列表组件

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

.feature-list li {
  position: relative;
  padding-left: 30px;
  margin-bottom: 15px;
}

/* 列表图标 */
.feature-list li::before {
  content: "✓";
  position: absolute;
  left: 0;
  top: 0;
  color: #28a745;
  font-weight: bold;
  font-size: 1.2em;
}

/* 列表分隔线 */
.feature-list li:not(:last-child)::after {
  content: "";
  position: absolute;
  bottom: -8px;
  left: 0;
  width: 100%;
  height: 1px;
  background: #ecf0f1;
}

引用样式

blockquote {
  position: relative;
  padding: 20px 20px 20px 60px;
  background: #f8f9fa;
  border-left: 4px solid #3498db;
  font-style: italic;
  color: #555;
}

/* 引用开始符号 */
blockquote::before {
  content: "“";
  position: absolute;
  left: 15px;
  top: 10px;
  font-size: 3em;
  color: #3498db;
  font-family: Georgia, serif;
  line-height: 1;
}

/* 引用结束符号 */
blockquote::after {
  content: "”";
  position: absolute;
  right: 15px;
  bottom: -10px;
  font-size: 2em;
  color: #bdc3c7;
  font-family: Georgia, serif;
}

伪元素选择器的注意事项

1. content 属性是必需的

对于 ::before 和 ::after,content 属性是必需的,即使设置为空字符串:

/* 正确 */
.element::before {
  content: "";
  display: block;
  width: 10px;
  height: 10px;
}

/* 错误 - 缺少 content 属性 */
.element::before {
  display: block;
  width: 10px;
  height: 10px;
}

2. 伪元素默认是行内元素

伪元素默认是行内元素,如果需要设置宽高,需要设置为块级元素:

/* 正确 */
.element::before {
  content: "";
  display: block;
  width: 10px;
  height: 10px;
}

/* 错误 - 行内元素不能设置宽高 */
.element::before {
  content: "";
  width: 10px;
  height: 10px;
}

3. 每个选择器只能使用一次伪元素

一个选择器只能使用一次 ::before 和一次 ::after:

/* 正确 */
.element::before {
  content: "前缀";
}

.element::after {
  content: "后缀";
}

/* 错误 - 不能使用多个 ::before */
.element::before {
  content: "前缀1";
}

.element::before {
  content: "前缀2";
}

总结

伪元素选择器让我们能够选择和样式化元素的特定部分,或者在不修改 HTML 的情况下添加内容:

  1. ::before:在元素内容前插入内容
  2. ::after:在元素内容后插入内容
  3. ::first-line:选择文本的第一行
  4. ::first-letter:选择文本的第一个字母

记住以下几点:

  • 伪元素以双冒号开头(CSS2 中使用单冒号)
  • ::before 和 ::after 必须有 content 属性
  • 伪元素默认是行内元素
  • 伪元素可以创建装饰性效果和交互效果
  • 合理使用伪元素可以减少 HTML 标记的使用