配了八年 CSS Grid,每次给产品网格加分隔线都要写一堆 nth-child 选择器——今天 Chrome 149 把这件事用一个属性彻底原生化了

写过八年 CSS Grid,每次给产品网格加分隔线都要写 15 行 nth-child——今天 Chrome 149 把这件事用一个属性彻底原生化了


每次用 Grid 做个产品网格,都要写一堆 nth-child 去掉最后一行/列的边框——这个痛大家都知道,但从来没人觉得 CSS 能解决这个问题。直到 Chrome 149 引入了 row-rule 和 column-rule,让容器自己画装饰线。

这个坑,你一定踩过

做产品卡片网格,老板说要加「分隔线」。你熟练地写:

.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 24px;
}
.grid > * {
  border-inline-end: 1px solid #ddd;
  border-block-end: 1px solid #ddd;
}
.grid > :nth-child(3n) { border-inline-end: 0; }
.grid > :nth-last-child(-n+3) { border-block-end: 0; }

15 行。这还没完——老板说改成 4 列,你就要把所有 3n 改成 4n3 改成 4,多列少列每改一次都要重新数。

这就是传统方案的本质:把装饰线绑在每个子元素上,然后用 nth-child 把不该出现的线条去掉。列数一变,选择器全部重写。

row-rule / column-rule:让容器自己画线

Chrome 149(2026年6月)给 Grid 和 Flexbox 引入了 CSS Gap Decorations,让 gap 空间本身变成可绘制的画布。

.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 24px;
  column-rule: 1px solid #ddd;
  row-rule: 1px solid #ddd;
}

5行搞定。column-rule 在列间隙画竖线,row-rule 在行间隙画横线。线条绘制在 gap 空间里,不影响元素本身尺寸。

而且这次改列数完全不用动选择器:

.grid {
  /* 改成4列,只需要改这一行 */
  grid-template-columns: repeat(4, 1fr);
  /* row-rule/column-rule 不用动 */
}

因为规则是绘制在间隙里的,列数变了线条自动跟着变。

更精细的控制

Chrome 149 还给了一堆额外控制能力:

控制线条位置(inset):

.grid {
  column-rule: 1px solid #ddd;
  column-rule-inset: 8px; /* 线条两端各缩进8px,不贴元素边缘 */
}

组合写法:

/* rule 是 row-rule 和 column-rule 的组合简写 */
.grid {
  rule: 1px solid #ddd; /* 同时设置横竖线 */
  rule: 1px solid #ddd, 2px dashed #eee; /* 分别设置横竖 */
}

线条交汇处处理:

/* 控制哪根线压哪根 */
column-rule-overlap: top; /* 列线在上 */

只画有内容的地方:

/* 空格子不画线 */
row-rule-visibility-items: around;

hover 动画(线条可过渡):

.card:hover {
  row-rule-width: 3px; /* hover 时线条变粗,CSS 动画无需 JS */
}

三个坑

坑一:Firefox 和 Safari 还不支持

截至2026年9月,row-rule/column-rule 只有 Chrome 149+ 和 Edge 149+ 稳定支持。Firefox 和 Safari 完全没有。

但好消息是:不支持的浏览器只是看不到线条,不会影响布局或导致错误。所以可以渐进增强:

.grid {
  /* 降级:啥也不做,看不到线但布局正常 */
}
@supports (row-rule: 1px) {
  .grid {
    column-rule: 1px solid #ddd;
    row-rule: 1px solid #ddd;
  }
}

坑二:线条不占空间,只是纯视觉

gap decorations 是纯装饰,不影响布局计算。所以如果你需要线条「真的占空间」,还是要用 border hack。

坑三:inset 兼容性有限

column-rule-inset 等精细控制在某些版本里行为不一致,建议保守使用,或在 MDN 上查最新兼容性数据。

三步下一步

第一步:用一个简单网格上手

找一个现有项目里的产品网格,把 nth-child border 方案替换成 row-rule/column-rule,感受「改了列数不用动选择器」的爽感。

第二步:用 @supports 写降级

Firefox 用户仍然需要降级体验,先写 @supports (row-rule: 1px) 保护层,再上生产。

第三步:探索可交互场景

row-rule-width 可以动画,试试 hover 场景——卡片悬停时线条变宽或变颜色,不需要一行 JS。


gap decorations 解决的不只是「少写几行选择器」,而是把「谁负责画这条线」这个问题从子元素移到了容器——这是 CSS 布局思维的一次小型转变。容器对自己的间隙负责,而不是让每个子元素各自声明「我这条边要画什么」。Chrome 149+ 的同学现在就可以用起来了。

评论区

0 条评论

登录后可评论。