:nth-child(n) 按元素在父容器中的物理位置(第几个子元素)匹配,与标签类型无关;若目标位置的子元素不是指定标签(如li),则不生效。

怎么用 :nth-child() 选中特定位置的列表项
直接说结论::nth-child(n) 是按元素在其父容器中的**物理位置**(即第几个子元素)来匹配的,不是按类型。哪怕你写的是 li:nth-child(2),如果第二个子元素不是 <li>(比如是 <div> 或文本节点),那它就完全不生效。
常见误用场景:想给“第二个 <li>”加样式,但父元素里混了其他标签,结果样式没出现——大概率就是这个原因。
-
:nth-child(1)→ 选中第一个子元素(且必须是目标标签,如li) -
:nth-child(odd)或:nth-child(2n+1)→ 所有奇数位子元素 -
:nth-child(even)或:nth-child(2n)→ 所有偶数位子元素 -
:nth-child(3n)→ 第 3、6、9… 个子元素(3 的倍数位) -
:nth-child(3n+2)→ 第 2、5、8… 个子元素(从第 2 个开始,每 3 个一循环)
:nth-child() 和 :nth-of-type() 的关键区别在哪
这是最容易混淆的一点::nth-child() 数的是「所有子元素」的顺序;:nth-of-type() 数的是「同类型标签」的顺序。
比如父元素是:
立即学习“前端免费学习笔记(深入)”;
<ul> <div>说明文字</div> <li>苹果</li> <li>香蕉</li> <span>分隔线</span> <li>橙子</li> </ul>
那么:
-
li:nth-child(2)✅ 匹配「香蕉」(因为<li>正好在第 2 个位置) -
li:nth-child(3)❌ 不匹配「香蕉」,也不匹配「橙子」——第 3 个子元素是<li>(香蕉),但第 3 个子元素确实是<li>,所以这里其实 ✅;真正失效的是li:nth-child(4)(第 4 个是<span>) -
li:nth-of-type(2)→ 匹配「香蕉」(它是第 2 个<li>) -
li:nth-of-type(3)→ 匹配「橙子」(它是第 3 个<li>),不管前面插了多少非li元素
实用列表样式控制示例:斑马纹 + 首尾特殊处理
真实项目中经常要实现「奇偶行不同背景」「第一项加图标」「最后一项去边框」这类效果。用 :nth-child() 写起来很直接,但要注意兼容性和语义。
下面这段 CSS 会作用于一个干净的 <ul><li>...</li></ul> 结构(无其他子元素干扰):
ul li {
padding: 8px 12px;
border-bottom: 1px solid #eee;
}
<p>/<em> 奇数项浅灰背景 </em>/
ul li:nth-child(odd) {
background-color: #f9f9f9;
}</p><p>/<em> 偶数项白色背景(可省略,除非要覆盖) </em>/
ul li:nth-child(even) {
background-color: #fff;
}</p><p>/<em> 第一项加左侧蓝条 </em>/
ul li:nth-child(1) {
border-left: 4px solid #007bff;
}</p><p>/<em> 最后一项去掉下边框 </em>/
ul li:last-child {
border-bottom: none;
}注意::last-child 比 :nth-child(n) 更安全,只要最后一个子元素确实是 <li> 就能命中;但如果末尾有 <div class="footer">,那 :last-child 就会失效——此时该用 :last-of-type。
容易被忽略的坑:伪类优先级和 DOM 变动影响
:nth-child() 是静态计算的,浏览器在解析 HTML 时就确定了每个元素的位置索引。这意味着:
- JS 动态插入新
<li>后,原有元素的:nth-child()索引可能全部改变(比如在开头prepend()一个<li>,原来:nth-child(1)的元素就变成:nth-child(2)) -
:nth-child()的优先级和普通类名一样(specificity = 0,0,1,0),但比标签选择器高;如果同时写了li.active和li:nth-child(1),后者不会自动覆盖前者——得看谁在 CSS 里写在后面,或加!important - IE8 及更早版本完全不支持
:nth-child(),如果还要兼容,得用 JS 或额外 class 控制(如class="first"/"odd")
最常出问题的不是语法写错,而是没意识到「它数的是所有子元素的位置」——检查 DOM 结构比查文档更快。










