写过 grid/flex 的人都踩过这个坑——每次加分隔线都要靠 border 和 nth-child 补丁,今天 row-rule 把这件事彻底原生化了

写过 grid 或 flex 列表的人都踩过这个坑:要在子元素之间加一条竖线,标准的做法是给每个子元素写 border-right,然后再用 nth-child 把每行最后一个元素的边框去掉。响应式一改列数,那堆 nth-child 全得跟着改。flex 换行之后尾部那一行多出来的竖线也得单独处理。

这类需求在后台管理页面、数据表格、定价卡片里极其常见。过去十年,前端圈对这个问题积累了一整套 border + nth-child 的补丁方案。2026 年 Chrome 149 + Edge 149,CSS Gap Decorations 终于把这件事原生化了——直接在容器的 gap 上画线,零 nth-child,零伪元素。


三行代码,告别 nth-child 补丁

Gap Decorations 的核心是两个属性:column-rule(列方向分隔线)和 row-rule(行方向分隔线)。用法和 border 一模一样,但画在容器的 gap 上,不在子元素上:

.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
  column-rule: 1px solid #e5e7eb;  /* 竖线 */
  row-rule: 1px solid #e5e7eb;      /* 横线 */
}

这五行代码画出来的分隔线会精确卡在每个 gap 的中间,列数变化时自动跟着走,尾部多余边框的问题自然消失。

flex 同样适用,flex-wrap 换行之后规则依然生效:

.flex-list {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  column-rule: 1px dashed #d1d5db;
  row-rule: 1px solid #e5e7eb;
}

进阶控制:交点、边缘、空白区

Gap Decorations 的设计远比 border 灵活。以下几个场景是 border 完全做不了、nth-child 补丁写到手断的:

1. 交点处谁压谁——rule-overlap

横线和竖线交叉的地方,rule-overlap 可以决定谁画在上面:

.card-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1.5rem;
  row-rule: 1px solid #c9a96a;
  column-rule: 3px solid #6a707a;
  rule-overlap: column-over-row;  /* 竖线压横线,十字交叉处竖线连续 */
  column-rule-inset-cap: 1.75rem; /* 竖线两端往里缩,横线贯通 */
}

2. 奇偶行样式交替——repeat() 语法

每一行的分隔线样式可以交替变化,用法和 grid-template-columns 完全一致:

.sudoku {
  display: grid;
  grid-template-columns: repeat(9, 48px);
  gap: 8px;
  row-rule-width: repeat(3, 1px), 3px;  /* 每3行粗线循环 */
  row-rule-style: solid, solid;
  row-rule-color: #999, #333;           /* 细线/粗线交替颜色 */
}

3. 空单元格不画线——rule-visibility-items

隐式 grid track 产生的空白区域,默认也会画线。用 rule-visibility-items: around 可以让线只围绕有内容的元素:

.posts {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 2rem;
  rule: 2px solid #999;
  rule-visibility-items: around; /* 空白区域不画线 */
  rule-inset: overlap-join;
}

三个坑

坑一:浏览器支持率约 40%,Safari 和 Firefox 暂无

Chrome 149 + Edge 149 是目前唯二支持的引擎,占全球约 40% 覆盖率。Safari 和 Firefox 还在实现中,暂无明确时间线。用 @supports 做渐进增强是标准做法:

.card-grid {
  /* 回退方案:用 border 伪元素 */
  > .card:not(:last-child)::after {
    content: ;
    position: absolute;
    right: 0; top: 0; bottom: 0;
    width: 1px; background: #e5e7eb;
  }
}

@supports (column-rule: 1px solid #000) {
  .card-grid {
    position: static;
    column-rule: 1px solid #e5e7eb;
    > .card::after { content: none; }
  }
}

坑二:线宽和颜色不能做 gradient

和 border 一样,column-rule/row-rule 目前只接受固定颜色和宽度,不支持渐变或圆角。需要这类效果还是得靠伪元素。

坑三:改版前记得测试响应式断点

当列数在媒体查询里变化时,gap 间距和规则宽度是否还匹配,最好在每个断点都过一遍。尤其是用了 column-rule-inset 的场景,断点切换时边缘缩进是否好看需要实际看效果。


三步下一步

  1. 找一个有分隔线的 grid/flex 页面(后台列表、定价卡片、产品卡片),把现有 border + nth-child 方案用 column-rule / row-rule 替换,测量代码行数变化
  2. 跑一遍 caniuse.com/row-rule,记录 Safari/Firefox 用户的占比,决定是否需要保留回退方案
  3. 在 Chrome DevTools 里体验:打开 Chrome 149+,对任何 flex 容器 F12,在 Elements 面板里临时加一条 column-rule: 1px solid,感受「零破坏性修改」带来的维护成本下降

Gap Decorations 是 2026 年「用容器属性替代子元素补丁」趋势的又一个例子。之前 CSS 解决过 sticky 阴影、列表编号、颜色派生的问题,现在轮到分隔线了。如果你现在写的代码里有任何 ::after { border-right ... } 配合 nth-child 的组合,90% 可以用一行 column-rule 替代——剩下的 10% 等 Safari 跟进就行。

评论区

0 条评论

登录后可评论。