在日常的 CSS 开发中,我们经常会遇到需要对元素进行"序号选择"的场景,比如给列表中的第偶数项添加特殊样式,或者让某个容器内的第3个子元素变大。这时,:nth-child 和 :nth-of-type 这两个伪类就派上用场了。
虽然它们看起来很相似,但背后的逻辑却截然不同。今天我们就来深入剖析这两个伪类的区别,并通过实际案例帮助你彻底搞懂它们的用法!
🔍 一、基本语法
scss
/* 第 n 个子元素 */
:nth-child(n)
/* 第 n 个同类型子元素 */
:nth-of-type(n)
其中 n 可以是数字、关键字(如 odd, even),或表达式(如 2n+1)。
🧩 二、核心区别
| 特性 | :nth-child(n) |
:nth-of-type(n) |
|---|---|---|
| 匹配依据 | 所有子元素的顺序(包括非同类型) | 同一类元素的顺序(仅同类) |
| 是否受其他元素影响 | 是(会被其他标签打断) | 否(只看同类型) |
✅ 示例对比
假设我们有如下 HTML 结构:
css
<div class="container">
<p>第一段</p>
<span>一个 span</span>
<p>第二段</p>
<div>一个 div</div>
<p>第三段</p>
</div>
现在我们分别用两个伪类选择第 2 个 <p> 元素:
css
/* :nth-child(2) 选择的是第二个子元素 */
.container :nth-child(2) {
color: red;
}
/* :nth-of-type(2) 选择的是第二个 <p> 元素 */
.container p:nth-of-type(2) {
font-weight: bold;
}
📌 结果分析:
:nth-child(2)会选中<span>,因为它是第 2 个子元素。:nth-of-type(2)会选中第二个<p>(即"第二段"),因为它只关心<p>类型的顺序。
💡 三、实战应用场景
场景 1:交替行背景色(表格)
css
<table>
<tr><td>行1</td></tr>
<tr><td>行2</td></tr>
<tr><td>行3</td></tr>
</table>
css
tr:nth-child(even) {
background-color: #f0f0f0;
}
✅ 使用 :nth-child(even) 可以完美实现奇偶行交替背景色。
⚠️ 如果你在
<tr>中混入了<thead>或<tfoot>,nth-child依然会按顺序计算,而nth-of-type则只关注<tr>。
场景 2:只对特定类型的元素编号
css
<ul>
<li>项目1</li>
<li>项目2</li>
<li>项目3</li>
<span>广告位</span>
<li>项目4</li>
</ul>
如果我们想让每个 <li> 都加上序号,但不被 <span> 打断:
css
li:nth-of-type(1)::before { content: "① "; }
li:nth-of-type(2)::before { content: "② "; }
li:nth-of-type(3)::before { content: "③ "; }
li:nth-of-type(4)::before { content: "④ "; }
这样即使中间插入了非 <li> 元素,编号也不会出错。
❗ 常见误区
❌ 错误理解:nth-child 是"同类型第几个"
很多人误以为 :nth-child(n) 是"第 n 个同类型元素",其实不是!
它匹配的是"父元素下的第 n 个子元素" ,无论类型。
🛠 四、如何选择?
| 需求 | 推荐使用 |
|---|---|
| 按所有子元素顺序选 | :nth-child() |
| 按同类型元素顺序选 | :nth-of-type() |
| 表格行/列交替样式 | :nth-child() |
| 列表项编号(忽略其他元素) | :nth-of-type() |
✅ 总结
:nth-child(n):看"位置",不管类型。:nth-of-type(n):看"类型内顺序",只关心同类型。- 两者都支持
odd,even,2n+1等表达式。 - 实际开发中,根据是否受其他元素干扰来选择。
📚 小贴士
你可以用浏览器开发者工具查看元素的 :nth-child 和 :nth-of-type 索引,快速验证你的选择器是否生效。
📌 记住一句话:
"
nth-child看顺序,nth-of-type看类型。 "
掌握这一点,你的 CSS 选择器将更加精准高效!
如果你觉得这篇文章对你有帮助,欢迎点赞、收藏、转发!也欢迎在评论区分享你曾经踩过的坑