伪类和伪元素

4 阅读4分钟

CSS 中的伪类和伪元素是两组非常强大但也容易混淆的选择器。它们的核心区别可以用一句话概括:

伪类是给“真实存在的元素”添加特定的“状态”;而伪元素是在页面上凭空“捏造”出一个原本不存在的虚拟元素。

下面是它们的区别、语法规范以及常见的应用场景。

核心区别与语法规范

特性维度伪类 (Pseudo-classes)伪元素 (Pseudo-elements)
核心作用选中元素的特定状态特定位置创建并选中一个虚拟的、不存在的元素
是否改变DOM否(仅改变样式,不增加节点)否(在CSS渲染层生成虚拟盒子,HTML中依然没有)
语法标识单冒号 :双冒号 :: (CSS3规范,用于区分伪类)
典型代表:hover, :first-child, :checked::before, ::after, ::first-line

关于冒号的补充说明: 在 CSS2 时代,伪类和伪元素都使用单冒号。CSS3 为了严格区分两者,规定伪元素必须使用双冒号 ::。不过,为了向下兼容,现代浏览器对 :before:after 这类老牌伪元素依然支持单冒号写法,但建议在日常开发中遵循规范,使用双冒号。


伪类 (Pseudo-classes) 的应用场景

伪类就像是一个“条件触发器”,当元素满足某个条件(如被鼠标悬停、处于特定位置)时,样式才会生效。

  1. 用户交互状态: 最常用的场景,无需 JavaScript 就能实现基础的交互反馈。
    /* 鼠标悬停在按钮上时变色 */
    button:hover {
      background-color: #007bff;
    }
    /* 输入框获得焦点时改变边框 */
    input:focus {
      border-color: blue;
    }
    /* 链接被点击激活的瞬间 */
    a:active {
      color: red;
    }
    
  2. 文档结构与位置: 根据元素在 HTML 树中的位置来精准打击,省去很多多余的 class 命名。
    /* 选中列表的第一个子元素 */
    li:first-child {
      font-weight: bold;
    }
    /* 选中表格的偶数行,实现斑马纹效果 */
    tr:nth-child(even) {
      background-color: #f2f2f2;
    }
    /* 选中没有子元素的空 div */
    div:empty {
      display: none;
    }
    
  3. 表单验证状态: 配合 HTML5 表单验证,给用户直观的视觉提示。
    /* 输入内容符合格式要求时显示绿色边框 */
    input:valid {
      border-color: green;
    }
    /* 输入内容不符合要求时显示红色边框 */
    input:invalid {
      border-color: red;
    }
    /* 复选框被勾选时改变标签颜色 */
    input[type="checkbox"]:checked + label {
      color: green;
    }
    

伪元素 (Pseudo-elements) 的应用场景

伪元素就像是 CSS 的“影分身术”,可以在不污染 HTML 结构的前提下,凭空创造出装饰性的内容或选中元素的某一部分。

  1. 创造虚拟装饰元素 (::before::after): 这是伪元素最强大的功能,常用于添加纯装饰性的图标、文字或清除浮动。注意:使用它们时必须设置 content 属性(哪怕为空字符串 ""
    /* 在每个外部链接后面添加一个箭头图标 */
    a[href^="http"]::after {
      content: " \2197"; /* Unicode 箭头字符 */
      font-size: 0.8em;
    }
    /* 给标题前面加一根装饰竖线 */
    h2::before {
      content: "";
      display: inline-block;
      width: 4px;
      height: 20px;
      background-color: #007bff;
      margin-right: 10px;
    }
    /* 经典的清除浮动 (Clearfix) 方案 */
    .clearfix::after {
      content: "";
      display: table;
      clear: both;
    }
    
  2. 选中元素的特定排版部分: 用于实现类似 Word 文档中的首字下沉等排版效果。
    /* 让段落的首字母放大并加粗(首字下沉) */
    p::first-letter {
      font-size: 2em;
      font-weight: bold;
      float: left;
    }
    /* 让段落的第一行文字变为蓝色 */
    p::first-line {
      color: blue;
    }
    
  3. 改变用户交互的默认样式: 定制用户在网页上操作时的默认视觉体验。
    /* 自定义用户用鼠标选中文字时的背景色和字体颜色 */
    ::selection {
      background-color: gold;
      color: black;
    }
    /* 改变输入框占位符文字的样式 */
    input::placeholder {
      color: #999;
      font-style: italic;
    }
    

总结来说,需要根据状态(如悬停、点击)或位置(如第一个、偶数个)来改变样式时,请使用伪类;当你需要凭空添加装饰性内容,或者精准控制元素内部的某一部分(如首字母)时,请使用伪元素