:nth-child(4n+1)直接选中每4个一组的首个元素,按父容器所有子元素物理位置计数,n从0开始,结果为1、5、9…;它不依赖类型,但受注释/文本节点干扰,需清理DOM或改用JS实现。

用 :nth-child(4n+1) 直接选中每组第一个
这是最直接的解法,:nth-child(4n+1) 会匹配位置为 1、5、9、13… 的元素,恰好是每 4 个一组时的首项。注意它依赖的是元素在父容器中的**物理位置**,不是“第几组里的第几个”这种逻辑分组。
常见错误是写成 :nth-of-type(4n+1) —— 如果父容器里混有其他类型标签(比如 div 和 span),:nth-of-type 会跳过非目标类型,导致序号错位;而 :nth-child 对所有子元素统一计数,更符合“每 4 个一组”的直觉。
示例:
ul li:nth-child(4n+1) {
background: #e0f7fa;
}假设 ul 下有 12 个 li,那么第 1、5、9 个 li 会被选中。
立即学习“前端免费学习笔记(深入)”;
当元素不连续或中间有干扰节点时,:nth-child 失效怎么办
如果父容器中存在非目标元素(比如注释、文本节点、其他标签),:nth-child(4n+1) 仍按全部子节点计数,结果就会偏移。例如:
<div class="grid"> <!-- 注释 --> <div class="item">A</div> <div class="item">B</div> <div class="item">C</div> <div class="item">D</div> </div>
此时 .item:nth-child(4n+1) 实际匹配不到任何元素,因为第一个 .item 是第 2 个子节点。
解决方法只有两个:
- 清理 DOM,移除注释和空白文本节点(推荐,语义清晰)
- 改用 JavaScript 动态加类,比如遍历所有
.item,对索引i满足i % 4 === 0的元素添加first-in-group类
4n+1 中的 n 是从 0 开始算的
别被公式吓住:4n+1 中 n 取 0、1、2、3…,结果就是 1、5、9、13…。这不是“第 n 组”,而是数学通项式。
容易混淆的写法:
-
:nth-child(4n)→ 选中第 4、8、12… 个(每组最后一个) -
:nth-child(4n+2)→ 选中第 2、6、10… 个(每组第二个) -
:nth-child(4n-3)和:nth-child(4n+1)等价,但可读性差,不建议
浏览器兼容性没问题,IE9+ 都支持 :nth-child。
Flex/Grid 布局下仍适用,但要注意源顺序
即使用了 display: flex 或 display: grid 并通过 order 改变视觉顺序,:nth-child 依然按 HTML 源码中的 DOM 顺序计算。也就是说,它选中的是“文档流中第 1、5、9… 个子元素”,不是“视觉上每行第一个”。
如果需要按视觉行/列选中(比如 Grid 中每行首项),CSS 本身做不到,必须靠 JS 结合 getBoundingClientRect() 或利用 Grid 的 grid-row/grid-column 属性做判断。
真正容易被忽略的是:只要父容器子元素结构稍有变化(比如服务端渲染插入一个 div,或 JS 动态 prepend 节点),4n+1 就可能全线失效——它看起来简单,实则对 DOM 结构敏感。


















