伪类修饰元素状态,不新增dom节点;伪元素创建虚拟内容片段,需content属性。:nth-child按子元素顺序匹配,:nth-of-type按同类型元素匹配。lvha顺序为规范强制要求,伪类须前置伪元素。

伪类和伪元素根本不是一回事,别混着用
伪类(如 :hover、:focus)选的是“已有元素的某种状态”,它不新增任何 DOM 节点;伪元素(如 ::before、::first-letter)选的是“文档里没有、但你可以样式化的虚拟部分”,本质是插入或定位内容片段。
-
:nth-child(2)是结构伪类——它看的是父元素下所有子元素的顺序,不管类型,第 2 个子元素是<span></span>还是<div> 都算 <li> <code>:nth-of-type(2)是类型伪类——它只数同为p的兄弟,跳过div、h3等其他标签 -
::before必须配content属性才生效,空字符串content: ""也行;而:before(单冒号)虽能用,但属于 CSS2 写法,语义模糊,容易和伪类混淆 - 浏览器兼容性上,
::placeholder是伪元素,但 IE 只认:placeholder(单冒号),现代项目建议用 Autoprefixer 或单独加一层降级 - 表单控件也一样:
:disabled和:focus可以共存,但input:disabled:focus永远不会匹配——因为禁用元素无法获得焦点,这个组合逻辑上就矛盾 -
:required::after这种“伪类+伪元素”链式写法合法,但要注意:伪类必须写在伪元素前面,::after:required是无效语法 - 移动端
:focus行为不稳定,iOS Safari 默认不给非可聚焦元素(如div)加 focus 样式,需加tabindex="0" -
content: attr(data-tip)可读取自定义属性,但如果data-tip为空或不存在,结果是空字符串,不是undefined—— 别指望靠它做条件渲染 - 图标字体(如 Font Awesome)用
content: "\f00c"时,必须确保font-family和font-weight正确,否则显示成方块或问号 -
::after清浮动(.clearfix::after { content: ""; display: table; clear: both; })至今有效,但 Flex/Grid 布局下已无必要,强行加反而干扰布局流 -
content不支持百分比、em等相对单位,只能用绝对单位(px)、attr()或字符串 -
p:first-of-type更可靠——它只找父元素内第一个p,不管前面有没有div或注释 -
:empty匹配的是“连空白符都没有”的元素,<p> </p>(含空格)或<p>\n</p>(含换行)都不算空,得用 JS trim 后判断才准 -
:not(:first-child)可以排除首项,但:not(.active, .disabled)在旧版 Safari 中不支持多参数,得拆成两个:not() -
:is()和:where()是现代替代方案,比如h2:is(:first-child, .intro),但 IE 完全不支持,需评估目标环境
表单交互样式必须按顺序写,否则失效
:link → :visited → :hover → :active 这个 LVHA 顺序不是建议,是规范强制要求。如果把 a:hover 放在 a:link 前面,悬停时样式可能完全不触发。
伪元素 content 属性的坑比想象中多
content 看似简单,实则限制极多:只能用于 ::before 和 ::after,不能用于 ::first-line 或 ::selection;值必须是字符串、属性值或计数器,不能是 HTML 片段或 JS 表达式。
结构性伪类在真实 DOM 中常被忽略的细节
:first-child 和 :last-child 容易误判,它们认的是“父元素下的第一个/最后一个子节点”,哪怕中间夹着注释、文本节点(比如换行空格)都可能导致匹配失败。
立即学习“前端免费学习笔记(深入)”;










