li + li 是加分割线最稳的写法,因其精准选择紧邻的同级li元素,天然跳过首项,不依赖类名、不触发重排、容错性高,且语义清晰。

为什么 li + li 是加分割线最稳的写法
因为你要的不是“每个 li 都有上边框”,而是“除第一个外,其余每个都带分隔线”——li + li 正好命中这个语义:只选紧接在另一个 li 后面的 li,天然跳过首项,无需额外 class 或 JS 判断。
它不依赖父容器类名、不关心层级深度(只要同级紧邻)、不触发重排(纯 CSS),比用 :not(:first-child) 更轻量,也比手动加 .divider 类更符合“样式即结构”的原则。
li + li 的实际写法和常见变形
基础写法就是一行 CSS,但细节决定是否真能跑通:
-
li + li本身只生效于同级、紧邻、且标签名完全一致的元素;如果列表项是<div class="item">,就得写 <code>.item + .item - 加边框时推荐用
border-top,而不是border-bottom,避免最后一项多出多余线条 - 若需左右分隔(如导航栏),可用
.nav-item + .nav-item::before配合content: "|" - 在 Flex 或 Grid 布局中,
+依然有效,但要注意换行后 DOM 顺序未变,视觉上“不紧邻” ≠ DOM 上不紧邻 - HTML 中两个
li之间夹了注释、空格或换行符?不影响——DOM 层面仍是相邻兄弟 - 中间插了一个
<li class="divider">?会断开链路:li + li只认同类标签,.divider不是li,所以第三个li不再匹配前一个li - 父容器用了
display: contents?小心:该属性会让子元素“脱离文档流”,+选择器将无法识别兄弟关系 -
li ~ li匹配所有后续同级li,包括第 3、4、5…个,容易误伤;而+只管“下一个”,精准可控 -
:nth-child(n+2)看的是位置序号,如果列表里混入了<li style="display:none">或服务端动态插入占位节点,序号就偏了 -
li + li只依赖真实存在的、紧邻的同类兄弟节点,结构容错性最高,也最容易被开发者一眼看懂意图
哪些情况会失效?重点排查这三点
li + li 看似简单,但真实项目里挂掉最多是因为结构没对齐:
和 li ~ li 或 :nth-child(n+2) 比有什么区别
三者都能避开首项,但行为完全不同:
真正难的不是写对选择器,而是确保 HTML 里那两个 li 确实挨着——别让构建工具自动注入的 wrapper、SSR 生成的 comment 节点,悄悄切断了这条兄弟链。











