CSS伪类/伪元素整理笔记

比较官方的解释

伪类

伪类选择元素基于的是当前元素处于的状态,或者说元素当前所具有的特性,而不是元素的id、class、属性等静态的标志。由于状态是动态变化的,所以一个元素达到一个特定状态时,它可能得到一个伪类的样式;当状态改变时,它又会失去这个样式。由此可以看出,它的功能和class有些类似,但它是基于文档之外的抽象,所以叫伪类。

伪元素

伪元素是对元素中的特定内容进行操作,它所操作的层次比伪类更深了一层,也因此它的动态性比伪类要低得多。实际上,设计伪元素的目的就是去选取诸如元素内容第一个字(母)、第一行,选取某些内容前面或后面这种普通的选择器无法完成的工作。它控制的内容实际上和元素是相同的,但是它本身只是基于元素的抽象,并不存在于文档中,所以叫伪元素。

用一句话区分

伪类描述“这个元素现在处于什么状态或关系中”,伪元素则是“在不增加真实 HTML 节点的情况下,选中或生成元素的一部分”。前者常见单冒号,例如 :hover:focus:checked:nth-child();后者在现代 CSS 中使用双冒号,例如 ::before::after::first-line::selection

/* 伪类:按钮被鼠标悬停时 */
.button:hover {
  background: #007acc;
}

/* 伪元素:在标题前生成装饰 */
.title::before {
  content: "#";
  margin-right: 0.4em;
  color: #007acc;
}

几个容易混淆的点

:first-child 是伪类,它选中“作为父元素第一个子节点的元素”;::first-letter 是伪元素,选中的是某个块级内容的首字。:before:after 的单冒号写法是为了兼容早期 CSS,新代码中更建议写成 ::before::after,让伪元素在语法上一眼可辨。

::before::after 需要 content 才会生成可渲染的盒子,即使只是做纯装饰,也通常要写 content: ""。它们适合图标、背景、边框和视觉标记,但不要放承载核心语义的文字,因为复制、搜索、翻译和辅助技术对生成内容的处理可能不一致。

实际开发中的用法

/* 键盘用户聚焦时显示轮廓,鼠标点击不强制显示 */
.button:focus-visible {
  outline: 3px solid rgba(0, 122, 204, 0.35);
  outline-offset: 2px;
}

/* 根据表单验证状态显示提示 */
input:invalid:not(:placeholder-shown) {
  border-color: #d93025;
}

/* 给列表中的偶数项添加底色 */
.list > li:nth-child(even) {
  background: #f6f8fa;
}

伪类和伪元素的目的都是减少为纯样式添加的 class 和空节点,但选择器不要写得过度依赖 DOM 层级。当结构一调整就全部失效时,用一个语义明确的 class 反而更容易维护。

可用性说明:本文发布于 2019 年 10 月,距今已超过五年。文中涉及的软件版本、接口、下载地址、命令参数和操作界面可能已经发生变化,部分方案在当前环境下可能失效。请结合官方最新文档核对后再操作,生产环境使用前务必先行验证。

版权声明: 本文首发于 指尖魔法屋-CSS伪类/伪元素整理笔记https://blog.thinkmoon.cn/post/419-notes-css/) 转载或引用必须申明原指尖魔法屋来源及源地址!