nth-child按子元素位置选中,非列表项顺序;应优先用nth-of-type;transition-delay需逐项设置;动画需配合opacity/transform/visibility控制;ie不支持css变量。

nth-child 选中的是元素位置,不是列表项顺序
很多人以为 nth-child(1) 就是“第一个列表项”,其实它只看父容器里第几个子元素——如果前面插了标题、空 <div> 或注释节点,<code>li:nth-child(1) 可能根本选不到第一个 <li>。真正稳定的做法是用 li:nth-of-type(1),它只数同类型标签。
实操建议:
- 检查 DOM 结构,用浏览器开发者工具确认目标
<li>实际是第几个子节点 - 若列表前有非
<li>元素,优先改用li:nth-of-type(n) - 避免依赖
nth-child(2n)做偶数项样式,除非你确定所有子元素都是<li>
transition-delay 需要为每个项单独计算,不能靠父容器统一设
滑入动效的本质是让每个 <li> 的 opacity 和 transform 在不同时间触发过渡。父元素上写 transition-delay: 0.2s 没用——CSS 过渡不会自动“分发”到子元素。
正确做法是用 :nth-child(n) 给每个项单独加延时:
立即学习“前端免费学习笔记(深入)”;
li:nth-child(1) { transition-delay: 0s; }
li:nth-child(2) { transition-delay: 0.1s; }
li:nth-child(3) { transition-delay: 0.2s; }更实用的写法是配合 CSS 自定义属性动态算:
ul {
--delay-step: 0.1s;
}
li:nth-child(1) { --delay: calc(0 * var(--delay-step)); }
li:nth-child(2) { --delay: calc(1 * var(--delay-step)); }
li:nth-child(3) { --delay: calc(2 * var(--delay-step)); }
li { transition-delay: var(--delay); }动画触发时机必须配合 visibility / opacity / transform 控制
只写 transition 不够,得让元素初始状态“不可见但占位”,否则布局会跳变。常见错误是用 display: none 开头——它无法触发 CSS 过渡,因为 display 属性本身不支持过渡。
推荐组合(兼顾可访问性与动效):
- 初始状态:
opacity: 0; transform: translateY(10px); visibility: hidden; - 触发状态(如加类
.is-loaded):opacity: 1; transform: translateY(0); visibility: visible; - 必须给
li设transition: opacity 0.3s, transform 0.3s, visibility 0s 0.3s——visibility的延迟是为了等 opacity/transform 动画结束再切换,避免闪一下
IE 和旧版 Safari 对 nth-child(n) 和自定义属性支持有限
nth-child 在 IE9+ 是可用的,但 CSS 变量(--delay)在 IE 完全不支持,旧版 Safari(
兼容性兜底建议:
- 用 PostCSS 插件(如
postcss-custom-properties)把 CSS 变量转成静态值 - 对 IE 用户降级:去掉延时,所有项同时滑入,或直接禁用动效
- 避免用
nth-child(an+b)复杂公式(比如nth-child(3n+2)),某些老 Android WebView 解析会出错
动效越简单,越容易被不同引擎一致执行;延时变量看着聪明,但一不小心就卡在某个安卓 WebView 里不动了。










