:first-child和:last-child匹配父元素中第一个或最后一个直接子节点,不区分类型;若父元素首尾为注释、空格文本节点或非目标标签,则失效;:first-of-type/:last-of-type按类型分组选取首尾,更实用。

:first-child 和 :last-child 能选中父容器中**位置上第一个或最后一个子元素**,但前提是该元素必须是其父元素的直接子节点,且类型不限——哪怕它前面/后面混着其他标签,只要它是第一个或最后一个子节点,就能命中。
为什么 :first-child 有时不生效?
常见现象:给列表项加样式,写 li:first-child { color: red; },结果第一项没变色。
原因通常是父容器开头有注释、空格文本节点、或非 li 元素(比如 div 或标题)。
- HTML 中换行和缩进会产生文本节点,它们也是“子节点”
-
:first-child不看元素类型,只看 DOM 树中的顺序位置 - 如果父元素第一个子节点是
#header,那任何li都不会匹配li:first-child
:first-of-type 和 :last-of-type 更实用
当你要选“第一个 li”或“最后一个 p”,而不是“第一个子元素”,就该换用这两个伪类。
立即学习“前端免费学习笔记(深入)”;
它们按元素类型分组后取首尾,无视中间夹杂的其他标签。
ul > li:first-of-type { font-weight: bold; }
article > p:last-of-type { margin-bottom: 0; }
注意::first-of-type 不等于“父元素下第一个出现的该类型”,而是“该类型在所有同级同类元素中排第一”——这在动态插入内容时行为更稳定。
兼容性与现代替代方案
:first-child 和 :last-child IE9+ 支持良好;:first-of-type / :last-of-type IE9+ 同样可用。
如果目标环境支持较新标准,可考虑:
-
:nth-child(1)等价于:first-child -
:nth-last-child(1)等价于:last-child - 需要更灵活控制(如每 3 个选一个),直接上
:nth-child()更清晰
但别为了“看起来高级”硬套 :nth-child(1) ——语义不如 :first-child 直观,可读性反而下降。
真正容易被忽略的是:这些伪类都只作用于**直接子元素**。如果嵌套了两层 div,外层 div 的 :first-child 不会穿透到内层去匹配。要跨层级选,得靠 JS 或重构 HTML 结构。


















