:first-child精准匹配父元素的第一个子元素,要求<li>必须是<ul>或<ol>的首个子节点;若存在注释、空格文本节点或其他标签则失效;与:nth-child(1)效果一致但语义更明确。

用 :first-child 设置列表第一项样式最直接
只要第一项确实是父元素的第一个子元素,:first-child 就能精准命中。常见于 <ul> 或 <ol> 下紧接 <li> 的结构。
注意:它匹配的是「第一个子元素」,不是「第一个 li」。如果列表前面有注释、空格文本节点(在 HTML 中通常被忽略),或意外插入了其他标签(比如 <div>),:first-child 就会失效。
- 确保
<li>是<ul>或<ol>的第一个子节点 - 避免在第一个
<li>前写 HTML 注释或换行导致的空白文本节点(现代浏览器大多忽略纯空白,但保险起见可删掉) - 不推荐用
:first-of-type替代——它按标签类型匹配,虽更宽松,但语义不如:first-child明确
:first-child 和 :nth-child(1) 有区别吗
在标准列表中,li:first-child 和 li:nth-child(1) 效果完全一致,都只选中第一个 <li> 子元素。但底层逻辑不同:
-
:first-child是:nth-child(1)的语法糖,性能无差异 - 如果未来要扩展为「第 2 项、第 4 项」等规律样式,直接改用
:nth-child(2n)更连贯 - 若列表结构可能混入其他标签(如
<li>+<div class="divider">),:nth-child(1)仍只看位置,和:first-child行为一致;真正需要区分时得用:nth-of-type()
实际 CSS 写法和容易忽略的细节
单独加粗、变色、去点、加图标都可直接写。关键是别漏掉选择器权重或继承干扰。
立即学习“前端免费学习笔记(深入)”;
ul li:first-child {
font-weight: bold;
color: #2563eb;
list-style-type: none;
}
ul li:first-child::before {
content: "★ ";
color: #f59e0b;
}
- 如果列表用了
list-style: none全局重置,:first-child里再设list-style-type: disc不会恢复原点——因为已被父级覆盖,需用list-style: inherit或显式还原 -
::before插入内容时,注意display默认是inline,若想垂直居中,需配合line-height或vertical-align - 在 Flex/Grid 列表中,
:first-child依然有效,但若用order属性调整了渲染顺序,伪类仍按 DOM 顺序匹配,不是视觉顺序
当 :first-child 不生效时先查什么
最常见的原因是 DOM 结构不符合预期。打开浏览器开发者工具,逐层检查元素的「实际子节点」列表,看第一个是不是你认为的 <li>。
- 右键检查第一个
<li>→ 查看其父节点的childNodes(在 Console 中输入$0.parentNode.childNodes) - 确认没有隐藏的文本节点(类型为
Text)、注释节点(Comment)或服务端注入的占位符 - 如果是 Vue/React 渲染的列表,检查是否用了
v-if/ 条件渲染导致第一个li实际上不是首个子节点 - 临时加一条通用规则测试:
ul *:first-child { outline: 2px solid red; },看红框套在谁身上
:first-child 的“第一”永远绑定在 DOM 树结构上,而不是你肉眼看到的渲染结果。结构一变,样式就断——这点比 JS 逻辑更容易被忽略。










