li:not(:first-child)最直接可靠,因它只排除第一个li节点,不依赖位置序号;而li:nth-child(n+2)易受中间非li元素干扰导致漏选,结构鲁棒性差。

li:not(:first-child) 是最直接、兼容性最好的写法,能稳定选中除第一个 li 外的所有同级 li 元素。
为什么不用 :nth-child(n+2)?
它看起来更“数学”,但实际容易误匹配:只要父元素下第 2、3、4… 个子节点是 li,就会被选中;如果中间夹着 p 或 span,li:nth-child(n+2) 会跳过那些位置,导致漏选或错选。
-
ul > li:nth-child(n+2)在<ul> <li>A</li> <p>text</p> <li>B</li> </ul>中根本不会选中B(因为B是第 3 个子元素,但不是第 3 个li) -
li:not(:first-child)只看是否为li且不是第一个li,结构鲁棒性强 - IE9+ 全支持
:not(:first-child),而:nth-child()在 IE9 也 OK,但逻辑陷阱更多
:first-of-type 和 :first-child 到底该用哪个?
关键区别在「类型」和「位置」:
立即学习“前端免费学习笔记(深入)”;
-
:first-child要求元素必须是父元素的第一个子节点(不管类型),所以div:first-child只匹配「是第一个子节点且是div」的元素 -
:first-of-type匹配父元素下第一个出现的该类型元素,不关心它前面有没有其他标签,更符合「第一个div」这种语义 - 选中「除第一个
div外的所有div」,应写div:not(:first-of-type),而不是div:not(:first-child)(后者在<p></p> <div>1</div> <div>2</div>中会错误地把div全选中)
兄弟选择符 + 和 ~ 的适用边界
它们不是「选中所有非首项」,而是「从第二项开始,逐个选中后续兄弟」,行为隐含顺序依赖:
-
li + li只匹配紧接在另一个li后面的li—— 即第 2、3、4… 个,但要求前一个也是li;如果中间有非li元素,链就断了 -
li ~ li匹配所有在某个li后面的li(不一定要紧邻),在纯li列表里效果等价于:not(:first-child),但语义模糊、可读性差 - 这两者无法表达「排除第一个」这个明确意图,调试时容易误判匹配范围
真正要注意的是:没有万能选择器。:not(:first-of-type) 适合按元素类型排除,:not(:first-child) 适合按 DOM 位置排除,~ 仅当结构绝对干净且你只想要「后续所有兄弟」时才考虑 —— 多数情况下,先想清楚你要排除的是「第一个该类型」还是「第一个子节点」,再选对应伪类。


















