三十的博客

CSS伪元素 ::before 和 ::after 详解

本文内容基于 AI 生成结果整理,可能包含不准确信息,仅供参考使用。
发布时间
阅读量 加载中...

MDN ::before 伪元素 | MDN ::after 伪元素

基本概念

::before 和 ::after 是 CSS 中的伪元素,它们允许你在元素的内容之前或之后插入内容,而不需要修改 HTML 结构。

语法

css
selector::before {
  content: "";
  /* 其他样式 */
}

selector::after {
  content: "";
  /* 其他样式 */
}

关键点 ​:

核心应用场景

1. 装饰性元素

场景 ​:为按钮添加图标或装饰线

此演示仅在桌面端浏览器中可用

html
<!DOCTYPE html>
<html>
  <head>
    <style>
      .fancy-button {
        position: relative;
        padding: 10px 20px;
        background: #4caf50;
        color: white;
        border: none;
        border-radius: 5px;
        cursor: pointer;
        font-size: 16px;
      }

      .fancy-button::before {
        content: "→";
        margin-right: 8px;
        transition: all 0.3s;
      }

      .fancy-button:hover::before {
        transform: translateX(5px);
      }
    </style>
  </head>
  <body>
    <button class="fancy-button">了解更多</button>
  </body>
</html>

2. 清除浮动

场景 ​:解决父元素高度塌陷问题

此演示仅在桌面端浏览器中可用

html
<!DOCTYPE html>
<html>
  <head>
    <style>
      .clearfix::after {
        content: "";
        display: table; /* 创建布局层 */
        clear: both; /* 清除两侧浮动 */
      }

      .float-left {
        float: left;
        width: 50%;
        height: 100px;
        background: #ddd;
      }
    </style>
  </head>
  <body>
    <div class="clearfix">
      <div class="float-left">左浮动元素</div>
      <div class="float-left">右浮动元素</div>
    </div>

    <p>父元素不会塌陷</p>
  </body>
</html>

3. 工具提示(Tooltip)

场景 ​:创建纯 CSS 的提示框

此演示仅在桌面端浏览器中可用

html
<!DOCTYPE html>
<html>
  <head>
    <style>
      .tooltip {
        position: relative;
        display: inline-block;
        border-bottom: 1px dotted black;
        cursor: help;
      }

      .tooltip::after {
        content: attr(data-tooltip);
        position: absolute;
        bottom: 125%;
        left: 50%;
        transform: translateX(-50%);
        width: 200px;
        background-color: #555;
        color: #fff;
        text-align: center;
        border-radius: 6px;
        padding: 5px;
        opacity: 0;
        transition: opacity 0.3s;
        pointer-events: none;
      }
      /* 
        pointer-events: none;

        该属性禁用元素的指针事件,使元素:
        1. 不会成为鼠标事件的目标
        2. 允许事件"穿透"到下层元素
        3. 不影响事件冒泡过程
      */

      .tooltip:hover::after {
        opacity: 1;
      }
    </style>
  </head>
  <body>
    <p>
      鼠标悬停查看
      <span class="tooltip" data-tooltip="这是一个提示内容">提示</span> 效果
    </p>
  </body>
</html>

4. 自定义复选框/单选按钮

场景 ​:美化原生表单元素

此演示仅在桌面端浏览器中可用

html
<!DOCTYPE html>
<html>
  <head>
    <style>
      /* 复选框容器样式 */
      .custom-checkbox {
        position: relative; /* 为子元素绝对定位提供参照 */
        padding-left: 30px; /* 为伪元素留出空间 */
        cursor: pointer;
        user-select: none;
      }

      /* 
        user-select: none;

        该属性禁用元素的文本选择功能,使元素:
        1. 无法被鼠标拖动选中
        2. 阻止光标插入
        3. 不影响程序化选择(如 JavaScript 操作)
      */

      /* 隐藏原生复选框(视觉隐藏但保留可访问性) */
      .custom-checkbox input {
        position: absolute;
        opacity: 0;
        cursor: pointer;
        height: 0; /* 高度为0避免占用空间 */
        width: 0; /* 宽度为0避免占用空间 */
      }

      /* 自定义复选框视觉样式 */
      .custom-checkbox .checkmark {
        position: absolute; /* 相对于父容器定位 */
        top: 0;
        left: 0;
        height: 20px;
        width: 20px;
        background-color: #eee;
        border-radius: 4px;
      }

      /* ~	匹配之后的所有同级元素 */

      /* 悬停状态样式 */
      .custom-checkbox:hover input ~ .checkmark {
        background-color: #ccc;
      }

      /* 选中状态样式 */
      .custom-checkbox input:checked ~ .checkmark {
        background-color: #2196f3;
      }

      /* 复选框勾选标记(默认隐藏) */
      .custom-checkbox .checkmark::after {
        content: "";
        position: absolute;
        display: none;
        left: 7px;
        top: 3px;
        width: 5px; /* 勾的宽度 */
        height: 10px; /* 勾的高度 */
        border: solid white; /* 白色边框 */
        border-width: 0 2px 2px 0; /* 只显示右下边框 */
        transform: rotate(45deg); /* 旋转45度形成勾状 */
      }

      /* 选中时显示勾选标记 */
      .custom-checkbox input:checked ~ .checkmark::after {
        display: block; /* 显示伪元素 */
      }
    </style>
  </head>
  <body>
    <label class="custom-checkbox">
      <!-- 实际checkbox被隐藏但保留功能 -->
      <input type="checkbox" checked />
      <!-- 可视化的自定义复选框 -->
      <span class="checkmark"></span>
      我同意条款
    </label>
  </body>
</html>

5. 价格标签效果

场景 ​:为价格添加装饰性符号

此演示仅在桌面端浏览器中可用

html
<!DOCTYPE html>
<html>
  <head>
    <style>
      .price {
        position: relative;
        display: inline-block;
        padding: 10px 20px;
        background: #f8f8f8;
        border-radius: 5px;
        font-size: 24px;
        font-weight: bold;
      }

      .price::before {
        content: "¥";
        font-size: 16px;
        vertical-align: super;
        margin-right: 5px;
        color: #888;
      }

      .price::after {
        content: "特价";
        position: absolute;
        top: -10px;
        right: -10px;
        background: #ff4757;
        color: white;
        font-size: 12px;
        padding: 2px 5px;
        border-radius: 3px;
      }
    </style>
  </head>
  <body>
    <div class="price">199</div>
  </body>
</html>

高级技巧

1. 多语言内容处理

场景 ​:为不同语言内容添加前缀

此演示仅在桌面端浏览器中可用

html
<!DOCTYPE html>
<html>
  <head>
    <style>
      [lang="en"]::before {
        content: "English: ";
        color: #888;
      }

      [lang="zh"]::before {
        content: "中文: ";
        color: #888;
      }
    </style>
  </head>
  <body>
    <p lang="en">Hello, world!</p>
    <p lang="zh">你好,世界!</p>
  </body>
</html>

2. 响应式分隔符

场景 ​:在不同屏幕尺寸下改变分隔符

此演示仅在桌面端浏览器中可用

html
<!DOCTYPE html>
<html>
  <head>
    <style>
      .breadcrumb {
        display: flex;
        flex-wrap: wrap; /* 换行 */
        padding: 0;
        list-style: none;
      }

      .breadcrumb li {
        margin-right: 10px;
      }

      .breadcrumb li:not(:last-child)::after {
        content: ">";
        margin-left: 10px;
        color: #999;
      }

      @media (max-width: 600px) {
        .breadcrumb li:not(:last-child)::after {
          content: "→";
        }
      }
    </style>
  </head>
  <body>
    <ul class="breadcrumb">
      <li>首页</li>
      <li>产品</li>
      <li>详情</li>
    </ul>
  </body>
</html>

3. 计数器应用

场景 ​:为章节标题添加序号

此演示仅在桌面端浏览器中可用

html
<!DOCTYPE html>
<html>
  <head>
    <style>
      body {
        counter-reset: section;
      }

      h2 {
        counter-increment: section;
      }

      h2::before {
        content: "第" counter(section) "章 ";
        color: #4caf50;
      }
    </style>
  </head>
  <body>
    <h2>CSS基础</h2>
    <h2>JavaScript入门</h2>
    <h2>前端框架</h2>
  </body>
</html>

注意事项

  1. 性能考虑 ​:过度使用伪元素会增加渲染负担
  2. 可访问性 ​:伪元素内容不会被屏幕阅读器读取(除非使用 aria-label)
  3. 内容限制 ​:伪元素不能包含 HTML ,只能是文本或图片
  4. 伪元素层级 ​:::before 在内容前,::after 在内容后

兼容性提示

#Before伪元素 #After伪元素 #CSS基础 #网页布局