资讯动态

CSS :nth-child() 选择器完全指南:an+b公式与实战避坑

发布时间:2026/9/29 15:48:25 来源:尧图企业网站定制
这在CSS里其实是个“看着简单、用起来容易翻车”的选择器。:nth-child()的括号里可以填数字、关键词、甚至是数学公式但很多人一遇到n就懵圈分不清“第几个”和“每隔几个”的写法更别提它跟:nth-of-type()有什么区别了。这篇文章不会停留在“记住公式”的层面我会把anb的数学逻辑拆开讲清楚每个热门场景都给你实测可跑的代码再附上我在真实项目中踩过的几个坑最后一part给你一份可以直接抄的排查方法。无论你是刚接触CSS的新手还是被各种选择器绕晕的熟手照着这篇文章的思路去用基本就不会再“选错人”了。1. 内容整体设计与思路拆解1.1:nth-child()到底是什么先用一句话说透:nth-child()是在同一父元素的所有子元素集合里按照它们在DOM中的“排行顺序”来选中某一个或某一类元素。它看的是“排行”而不是“看长相”。这里有个新手最容易理解错的点——它不关心元素是不是p、是不是div它只关心这个孩子排在“第几桌”。这么说可能有点抽象我拿一个班级类比班主任手上有全班学生的花名册花名册的排列顺序就是他们在教室里的座位顺序也就是DOM中的出现顺序)。:nth-child(3)相当于说“点名册上的第3个人不管他是男是女、穿什么衣服就要这个人”。而:nth-of-type(3)则是“先把穿红衣服的人单独拎出来在红衣服人群里数第3个”。这个区别非常关键。比如你写ul li第一项/li li第二项/li li第三项/li li第四项/li /ul:nth-child(2)选中“第二项”。如果把第二个li改成span那么:nth-child(2)选中的还是这个span因为它在父元素里的排行没有变。但:nth-of-type(2)就会选中“第三项”因为它在li这个类型里是第2个。理解这个底层逻辑之后后面所有花里胡哨的“隔行变色”“删掉某一行”“选中前N个”都是在同一个坐标系里做筛选。坐标系对了写出来的选择器才稳。1.2 为什么需要系统性地学它很多开发者写CSS时习惯性地给每个元素加class然后用.item-1、.item-2这种方式去控制样式。短时间没问题但一旦列表是动态渲染的DOM数量不固定类名也没法穷举这条路就走死了。nth-child系列恰恰是解决这类“批量元素有规律地变化”问题的利器。比如给一个不定长度的列表做斑马纹li:nth-child(even) { background: #f5f5f5; }只要这个写法正确不管列表是3行还是300行斑马纹永远会自动匹配。不需要JS不需要额外类名性能上也比JS遍历DOM要轻量得多。它还有一个很大的价值是可以精确地控制某个位置的元素样式而不是用类名去“标记一个身份”。比如“第一屏的简介卡片要去掉上边框”以前可能要单独打个类现在直接.card:first-child { border-top: none; }少了很多维护成本。但前提是你真的搞懂了它括号里那套anb公式。我在网上看过太多人抄公式抄错最后选了整整一行“奇怪”的元素问题就出在只背了形式、没理解逻辑。这篇文章就把逻辑本身给你理顺。2. 核心细节解析与实操要点2.1 三种基础写法数字、关键词、公式:nth-child()的括号里可以填三种东西整数、英文关键词、还有anb形式的函数式。这三种不仅写法不同适用场景也完全不同我把它们分开拆。整数写法li:nth-child(1) { color: red; } li:nth-child(2) { color: blue; }这种写法最直观就是“指定老几”。注意这里的nth-child(1)其实等价于:first-child但可读性上:first-child更好。整数写法适合那种“我就想改前几个”的静态需求比如首行加粗、第二个卡片加特殊阴影。关键词写法li:nth-child(odd) { background: #eee; } li:nth-child(even) { background: #fff; }odd等于奇数1、3、5...even等于偶数2、4、6...。斑马纹、双列布局里左右卡片交替样式、手风琴里的奇偶项间距全都用得上。它本质上是2n1和2n的语法糖但语义化更好团队里其他人一看就懂。公式写法li:nth-child(3n) { margin-right: 0; } li:nth-child(3n1) { clear: both; }公式写法最灵活也最容易把初学者绕晕。它的本质是当n从0开始依次取1、2、3...时这个表达式的值就是选中的子元素序号。n一定是从0开始的自然数这一点是理解所有公式的钥匙。只要把握住这句“咒语”什么4n2、5n-1都能推算出来。2.2anb公式的数学本质别再死记硬背我见过大量“背公式”的教程今天我不想让你背。我们来推一遍。公式是anb其中a是步长每隔几个出现一次b是偏移量从第几个开始命中。先看最常见的一组/* n从0开始0、1、2、3... */ :nth-child(n) /* 011、112、213... 即全部元素 */ :nth-child(2n) /* 000注意序号从1开始0是无效的所以实际是2、4、6... */ :nth-child(2n1) /* 1、3、5... */ :nth-child(3n) /* 3、6、9... */ :nth-child(3n1) /* 1、4、7... */ :nth-child(3n2) /* 2、5、8... */当你把n代入0、1、2逐个算一下的时候就会发现根本没有“魔法”。2n是“每2个取第2个”2n1是“每2个取第1个”。3n1就是“每3个一组取每组第1个”3n2是“每组第2个”。看到这里你应该能总结出一个通用套路a 决定组的大小b 决定组内的位置。如果你想实现“每4个一组让每组第4个没有右边距”那就是li:nth-child(4n) { margin-right: 0; }如果你想实现“每4个一组每组第3个换个颜色”那就是li:nth-child(4n3) { background: yellow; }我不建议你像我以前一样在脑子里跑一堆数字。最实用的做法是先写一个小组n0,1,2,3,4代入看看命中了哪个位置然后再根据“几个一组、要第几个”反推公式。熟练之后基本一眼就能看出来。2.3 从尾部开始选nth-last-child与负数偏移实际项目里有一种需求特别常见我想选“最后三个”或者“倒数第二个”。正着数当然也可以但名单长度不固定正着数要经过计算。这时用:nth-last-child()直接翻牌li:nth-last-child(1) { background: orange; } li:nth-last-child(-n3) { background: orange; }:nth-last-child(1)就是倒数第一个等价于:last-child。而-n3这个公式代入n0,1,2,...得到3、2、1。注意序列是从3开始的接下来是2、1再往后是0、负数所有非正序号都会被忽略。所以它实际命中的是倒数第3、第2、第1个元素也就是“最后三个”。这是我在“最新N条动态高亮”“底部操作栏最后三个按钮紧凑排列”这类需求里用得非常多的写法。别忘了它同样有:nth-last-of-type()的变体逻辑一样只是先把同类型的元素筛出来再倒着数。这里有一个容易踩的坑-n3不能写成3-n。虽然数学上它们等价但CSS的anb语法要求a在前、b在后3-n不符合函数式语法整个选择器会失效。每当我看到有人写nth-child(3-n)时都知道他踩了这个语法坑。2.4 常见anb模式速查表我把自己平时常用的模式整理成一张表你直接对照选场景就行不用每次从头推算。需求场景推荐写法实际效果奇数行:nth-child(odd)1、3、5...偶数行:nth-child(even)2、4、6...每3个一组选组内第2个:nth-child(3n2)2、5、8...每4个一组选组内第4个:nth-child(4n)4、8、12...选第2个到第4个:nth-child(n2):nth-child(-n4)2、3、4选前3个:nth-child(-n3)1、2、3选第1个到第6个:nth-child(n1):nth-child(-n6)1~6选第3个之后的所有:nth-child(n3)3、4、5...只选第5个:nth-child(5)5选倒数第2个到第4个:nth-last-child(n2):nth-last-child(-n4)倒数第4、3、2个“选第2个到第4个”这种区间写法本质上是两个:nth-child()选择器做交集通过两个选择器连写实现AND逻辑。只有同时满足“从第2个开始”和“到第4个为止”两个条件的元素才会被选中。这种“区间限定法”非常实用尤其是做复杂表格的头部样式时比单独加类名省事多了。注意:nth-child(n2)的理论命中范围是2、3、4...无限往后:nth-child(-n4)是4、3、2、1...两组交集后只剩2、3、4。这个思路可以用到任何“指定区间”的场景。3. 实操过程与核心环节实现3.1 经典案例1列表自动斑马纹与首尾特殊样式我们先做一个最经典的“新闻列表”页面要求是这样的每行新闻默认白底偶数行浅灰底第一行标题加粗最后一行底部加分隔线鼠标悬停时整行高亮。全程用纯CSS实现不额外加类名。HTML结构ul classnews-list li新闻标题一/li li新闻标题二/li li新闻标题三/li li新闻标题四/li li新闻标题五/li li新闻标题六/li /ulCSS写法.news-list { list-style: none; margin: 0; padding: 0; } .news-list li { padding: 12px 16px; border-bottom: 1px solid #eee; transition: background 0.2s ease; } /* 偶数行浅灰 */ .news-list li:nth-child(even) { background: #f8f9fa; } /* 第一行标题加粗 */ .news-list li:first-child { font-weight: 700; font-size: 18px; } /* 最后一行底部加分隔线 */ .news-list li:last-child { border-bottom: 2px solid #333; } /* 悬停高亮 */ .news-list li:hover { background: #e7f3ff; }这段代码写在真实项目里可以直接跑。我想特别强调transition那一行加在li上之后悬停高亮会有一个轻微的淡入过渡而不是突然变色。整体视觉上会舒服很多也不会影响性能。这种写法的优势在于不管后端渲染出来是6条还是60条新闻样式都会自动生效。你不用在模板里写“第2条加个类名”这种脏代码。3.2 经典案例2网格布局中“每组最后一个”的处理现在做个商品卡片墙每行放4个商品卡片间距12px。常规做法是让每个卡片都有margin-right: 12px然后第4个、第8个、第12个...要清掉右边距否则一排只能塞下3个。HTML结构实际项目可能是JS循环生成但结构一样div classgrid div classcard商品1/div div classcard商品2/div div classcard商品3/div div classcard商品4/div div classcard商品5/div div classcard商品6/div div classcard商品7/div div classcard商品8/div /divCSS写法.grid { display: flex; flex-wrap: wrap; gap: 12px; /* 现代浏览器直接用gap省心 */ } .card { width: calc((100% - 36px) / 4); background: #fff; border: 1px solid #e0e0e0; border-radius: 8px; }当flex配合gap使用时其实根本不需要:nth-child()去清边距因为gap会自动控制间距每一行第4个元素天然没有多余的右边距。但是如果项目需要兼容旧浏览器或者你用的是float或者inline-block布局那么4n这个公式就派上用场了。我在老项目里见过不少这种代码.card { float: left; width: calc((100% - 36px) / 4); margin-right: 12px; } .card:nth-child(4n) { margin-right: 0; } /* 或者配合清除浮动 */ .grid::after { content: ; display: block; clear: both; }这里4n选中的是第4、8、12个元素每行最后一个清掉它的margin-right。这个方案在旧布局里非常经典。但我要额外提醒一点如果这个.grid下还有别的子元素比如标题、加载更多按钮:nth-child(4n)是按所有子元素的排行来数的而不是只看.card。所以最安全的做法是让.grid只包含同一类卡片然后把额外元素放到.grid外面的结构层。否则一旦插入了别的节点所有4n的位置全部错乱。这个坑我在第4部分会专门展开。3.3 经典案例3CSS动态相册与“涟漪光圈扩散”效果结合最近“CSS涟漪光圈扩散”和“CSS动态相册纯代码”这类玩法挺火。本质都是用CSS动画配合选择器做出从中心向外扩散的光圈。:nth-child()在这里的价值是可以让每一张相册封面的动画产生“肉眼可见的依次延迟”形成波浪感。思路很简单同一组图片都绑定同一个keyframes动画但通过animation-delay错开时间。因为n是自然数正好可以直接写进animation-delay的值里.album-item { animation: ripple 1.2s ease-out infinite; animation-delay: calc(var(--index) * 0.15s); }不过上面这个var(--index)需要行内样式配合。如果不想在模板里算--index可以直接用:nth-child()一条条写或者利用CSS变量配合nth-child给变量赋值.album-item:nth-child(1) { --index: 0; } .album-item:nth-child(2) { --index: 1; } .album-item:nth-child(3) { --index: 2; } .album-item:nth-child(4) { --index: 3; } /* ... */这样每张图片的涟漪光圈都会错开0.15秒出现视觉上就是从第一张“荡”到最后一张。注意calc(var(--index) * 0.15s)里var(--index)解析出来的值是数字所以能和s相乘这是CSS变量的一个常见但容易踩坑的小细节。核心动画本身不复杂keyframes ripple { 0% { box-shadow: 0 0 0 0 rgba(66, 133, 244, 0.4); transform: scale(1); } 100% { box-shadow: 0 0 0 20px rgba(66, 133, 244, 0); transform: scale(1.05); } }这个box-shadow从“影子的外扩距离0、颜色不透明”逐渐变到“外扩距离20px、颜色完全透明”视觉上就是一个向外消散的光圈。:nth-child()负责的是让这些圈圈依次登场制造动态相册的节奏感。3.4 进阶案例43D旋转卡片中rotateY(60deg) translateZ(300px)到底长什么样这里要结合“CSS 3D旋转”和:nth-child()的核心规则来聊。你可能在热词里看到过transform: rotateY(60deg) translateZ(300px)这种写法乍一看很像魔法其实它组合起来的效果是先把元素绕Y轴旋转60度再沿着它旋转后的局部Z轴方向平移300px。先看最关键的顺序问题transform里的函数是从左到右依次应用的。当你写rotateY(60deg) translateZ(300px)先发生的是Y轴旋转元素的正脸已经朝右前方了然后沿着这个新的朝向“往前走300px”。所以多个元素用不同的旋转角度配合translateZ排列时会呈现一个环形的3D空间效果。:nth-child()在这里最常见的用途是生成“一圈均匀分布”的卡片。如果想让8张卡片围成一圈那么每张卡片需要绕Y轴旋转的角度增量是360 / 8 45度。纯CSS无法直接做乘法所以通常结合CSS变量.scene { perspective: 1000px; } .card { position: absolute; left: 50%; top: 50%; transform-style: preserve-3d; } .card:nth-child(1) { --angle: 0deg; transform: rotateY(var(--angle)) translateZ(300px); } .card:nth-child(2) { --angle: 45deg; transform: rotateY(var(--angle)) translateZ(300px); } .card:nth-child(3) { --angle: 90deg; transform: rotateY(var(--angle)) translateZ(300px); } .card:nth-child(4) { --angle: 135deg; transform: rotateY(var(--angle)) translateZ(300px); } .card:nth-child(5) { --angle: 180deg; transform: rotateY(var(--angle)) translateZ(300px); } .card:nth-child(6) { --angle: 225deg; transform: rotateY(var(--angle)) translateZ(300px); } .card:nth-child(7) { --angle: 270deg; transform: rotateY(var(--angle)) translateZ(300px); } .card:nth-child(8) { --angle: 315deg; transform: rotateY(var(--angle)) translateZ(300px); }最终效果就是8张卡片均匀分布在一个半径为300px的圆环上你旋转整个场景卡片就像旋转木马一样转动。这里:nth-child()的价值在于给每张卡片分配不同的角度变量配合同一个translateZ形成规律的空间排布。关于“3D旋转正负判断核心规则”CSS中旋转角度的正负是按照“从坐标轴正方向看过去顺时针为正”来定的。绕Y轴旋转时正角度会让元素的右边朝屏幕外转过来负角度则是左边朝屏幕外。判断实际效果时不要死记“左转右转”直接在浏览器里改一下deg数值前后对比最快。这也是我的习惯3D变换的代码先在DevTools里实时调角度确认锚点方向后再写进样式表。3.5 与:nth-of-type()的对比及混用技巧:nth-child()和:nth-of-type()的选择逻辑经常让人混。我再举一个非常具体的对比例子div classcontainer h2标题/h2 p第一段/p p第二段/p span小标签/span p第三段/p /div:nth-child(2)选中的是第一个p因为它是父容器里的第2个子元素。:nth-of-type(2)选中的是第二个p内容为“第二段”因为它先筛出所有p再数p里的第2个。如果我想选“标题后面的所有段落”最稳的写法是.container h2 ~ p { color: #333; }这里用的是一般兄弟选择器不属于:nth-child()的范畴但它能避免:nth-child()把span之类插入元素也卷进来。再看看混用场景一个卡片区域既有标题又有列表我只想对列表里的偶数项做背景色有两种写法。写法A直接在列表上写.list li:nth-child(even) { background: #fafafa; }写法B在整个容器里用:nth-of-type单独筛选li.container li:nth-of-type(even) { background: #fafafa; }这两种写法如果容器里只有li和标题结果一样。但如果容器里还有其他标签穿插在li之间写法A只数li在list父元素内部的排行写法B是在容器所有子元素里数但先筛出li类型再数。具体用哪个取决于你的HTML结构是否干净。关键经验如果列表结构“纯”全用:nth-child()如果结构里混入了大量非目标元素优先用:nth-of-type()或:nth-child()配合父子选择器一起使用。这样能最大限度地避免“数错人”。4. 常见问题与排查技巧实录4.1 为什么我写了:nth-child(2)却选中了奇怪的东西这是最常见的翻车现场。典型HTMLdiv classbox img srccover.jpg alt封面 p描述文字/p /div如果你写.box p:nth-child(2)它选中的确实是p因为p在.box里排行第2。但如果你写.box p:nth-child(1)就会什么都选不中。原因很简单p不是第1个子元素第1个是img。:nth-child()的序号是所有子元素共同排行而不是“同类元素排行”。很多人把:nth-child(1)理解成“第一个p标签”所以总出问题。正确的意图应该写成.box p:nth-of-type(1)这样才会在p类型里找第一个。排查办法也简单在浏览器的开发者工具里点中那个目标元素看它在父节点里的实际位置对照HTML源码数一下前几个是什么。如果前面藏着img、span、input这种“看不见但占据排行”的元素:nth-child()的序号就会跟着偏移。4.2 动态列表里插入了一个非列表元素所有斑马纹全乱我之前帮朋友调过一个后台管理系统左侧菜单是JS动态生成的结构长这样nav a首页/a a用户管理/a a订单管理/a span classdivider/span a系统设置/a /nav然后CSS写的是nav a:nth-child(even) { background: #f2f2f2; }结果运行时发现排序彻底乱套第2个菜单“用户管理”本来应该高亮实际高亮的是“订单管理”。原因就是中间那个span classdivider把排行挤了even命中了不同的元素。这种问题的根源是动态渲染时组件库或业务逻辑可能会在列表中间插入分割线、加载占位、空状态节点等而这些节点不是列表数据的一部分。:nth-child()不关心节点是否“有内容”它只数排行。所以动态列表的斑马纹我不建议直接使用:nth-child()更稳的是用:nth-of-type()nav a:nth-of-type(even) { background: #f2f2f2; }:nth-of-type(even)只在所有a标签内部数偶数位中间的span不会影响计数。虽然视觉上可能还是会有“分割线打断了偶数连续性”的问题但至少高亮的元素不会错位。4.3n从0开始还是从1开始为什么我的公式总差一位公式anb中的n从0开始这是一个容易绕弯的点。如果你按“第1个、第2个”去理解n很容易把3n1误认为是从第1个开始每隔3个取一个结果算出来却是1、4、7...反而不知道哪里错了。我建议你把n看作“分组次数”或“轮次”。比如3n2n0时是第2个n1时是第5个n2时是第8个。它表述的是“每3个一组永远取组内第2个”而不是“从第2个开始数第3个”。一旦你这样理解公式就不会再差一位。另外还有一个实际调试技巧在DevTools的Elements面板里选中父元素然后在Console里运行document.querySelectorAll(li:nth-child(3n2))直接看选中的结果对不对比一遍遍刷新看样式快得多。如果发现选多了或选少了把n的值代入公式手写两三个数字验证基本就能定位问题。4.4 表格隔行变色时表头和分组行总是干扰表格场景特别容易把:nth-child()用崩因为table里的tr不是永远整齐排列的。比如table thead trth名称/thth数值/th/tr /thead tbody tr classgrouptd colspan2分组A/td/tr trtd项目1/tdtd10/td/tr trtd项目2/tdtd20/td/tr tr classgrouptd colspan2分组B/td/tr trtd项目3/tdtd30/td/tr /tbody /table如果直接给tbody tr:nth-child(even)加背景色那“分组A”“分组B”这两行也会被算进去导致下面数据行的奇偶规律全乱。更稳妥的做法是让选择器排除掉.group再把偶数背景只作用到普通行上tbody tr:not(.group):nth-child(even) { background: #fafafa; }注意这里的:nth-child(even)依然按所有tr的绝对排行来数但:not(.group)会把分组行过滤掉。这只解决“视觉上不让分组行变色”的问题但如果你希望数据行内部连续地按奇偶交替还是改数据结构更好——在模板里给每个分组单独拆一个tbody然后对每个tbody内的tr重新编号。这也是为什么我强调“:nth-child()很依赖DOM树结构”结构不干净选择器就会跟着不干净。4.5 和“清除浮动”“CSS换行省略”一起用的时候要注意什么“清除浮动”本身和:nth-child()没有直接关系但它们经常出现在同一个列表布局场景里。比如说你需要给最后一组卡片清除浮动带来的父容器高度塌陷.grid::after { content: ; display: table; clear: both; }:nth-child()不会影响浮动的计算但浮动元素在父容器里的“排行”依然存在。如果你在浮动布局里用:nth-child(4n)清边距同时又给.grid设置了::after这个::after是最后一个子元素它会占用一个排行位置。也就是说.grid::after会变成当前父容器的最后一个孩子如果某个选择器写的是.grid :nth-last-child(1)可能会误选到这个看不见的伪元素。这算是CSS的隐藏坑伪元素也会参与子元素计数。排查的时候如果发现“最后一个卡片样式没生效空白却变了”先看看是不是::before、::after占据了序号。另外“CSS换行省略”通常用在卡片标题上.card-title { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }它和:nth-child()的冲突概率不大但我提醒一下:nth-child()只影响元素的选择不会改变元素内部的文本布局。如果卡片标题太长第二行卡片样式错位往往是布局问题不是选择器问题。你在排错时要分清“没选中”和“选中了但长这样”的区别。4.6 一个小技巧用:nth-child()实现响应式断点下的自动重置这个技巧我用了很多年。比如网格在手机上是2列平板上是3列桌面上是4列。每一行的“最后一个”需要清掉右边距但是列数一变“最后一个”的位置也跟着变。以前写响应式可能要为每个断点重写一遍类名或者选择器。:nth-child()可以直接按断点覆盖.card { width: 50%; float: left; } /* 2列布局第2n个清右边距 */ .card:nth-child(2n) { margin-right: 0; } media (min-width: 768px) { .card { width: 33.3333%; } /* 3列布局第3n个清右边距 */ .card:nth-child(3n) { margin-right: 0; } } media (min-width: 1200px) { .card { width: 25%; } .card:nth-child(4n) { margin-right: 0; } }写这段代码时容易忽略一个点大断点覆盖小断点时上一步的:nth-child(2n)还在生效。因为它没有被覆盖会在新布局中继续清掉部分卡片的右边距。所以正确做法是每个断点里把“该清的都清掉”或者把清边距的规则统一交给当前断点的公式同时把别的断点规则显式重置。最省心的方案是尽量使用flex gap:nth-child()只在兼容老布局时用。4.7 快速排查建议当你不确定一条:nth-child()规则到底选中了哪些元素时最快的办法是直接在浏览器Console里跑一行JSdocument.querySelectorAll(.grid .card:nth-child(4n))然后看返回的数组长度和具体元素。如果数组结果符合预期但样式没生效多半是优先级或层叠问题如果数组结果都不对那就是公式本身有问题。这个方法比反复刷新页面、“人肉数DOM”要可靠得多我几乎每写一条不常见的nth-child公式都会先跑一遍验证。另外如果你用的是Chrome可以在Elements面板里选中父元素右键选择“Copy Copy outerHTML”丢到一个结构可视化工具里数一下子元素的实际顺序。代码不熟的时候“把DOM画出来数”远比心算稳妥。我的一点体会我用:nth-child()写了这么多年样式最大的感受是它和class是两种思路。class是在给元素“贴标签”而:nth-child()是在“按排行认位置”。很多刚入行的朋友习惯给所有东西都加类名倒也没错但一旦遇到动态渲染、列表长度不定、需要按奇偶或周期变化样式的场景:nth-child()提供的这套“函数式选法”会让代码干净得多维护起来也轻松得多。最后分享一个压箱底的小技巧在大项目里我一般会在公共样式文件里写好一组通用的“周期工具类”比如.list-2n-margin-0、.row-even-bg然后在组件里直接复用。表面上看起来它还是类名但底层其实就是在用:nth-child()规则。这样既能享受到这个选择器的强大又不至于让每个组件散落一堆重复的nth-child代码。个人建议是页面结构越规律越应该优先用:nth-child()结构越杂乱越要先理清DOM层级再下手。别怕在DevTools里多验证几次用得多了你自然就能一眼看出“这句选择器会命中谁”。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑