写过前端的都踩过这个坑——Grid 和 Flex 的分隔线以前只能靠 border 硬撑,今天 CSS 把这件事彻底原生化了

写过前端的都踩过这个坑——Grid 和 Flex 的分隔线以前只能靠 border 硬撑,今天 CSS 把这件事彻底原生化了


做 Grid 或 Flex 布局的时候,分隔线是刚需。卡片之间要一根线、导航项之间要一根竖线、数据表格要横竖都有——但以前 CSS 没有原生属性来处理这个,大家都是用 border hack 凑合。

具体怎么凑合?每个子元素加 border-inline-end: 1px solid #ddd,再用 :nth-child 把每行最后一项的边框去掉。听起来简单,但改列数要改一堆选择器、flex 换行要重新算、响应式断点一来全要重写。

Chrome 149 开始,CSS Gap Decorations 把这件事彻底原生化了。

核心就两个属性column-rule(竖线)和 row-rule(横线),直接写在 Grid 或 Flex 容器上,线条就画在 gap 里面,不动子元素一根毫毛。

先看最基础的样子:

.card-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 24px;
  column-rule: 1px solid #e5e7eb;  /* 竖线:两列之间 */
  row-rule: 1px solid #e5e7eb;      /* 横线:两行之间 */
}

这就是以前 15 行 border + nth-child 选择器的全部内容,现在 5 行搞定。改列数的时候不需要动任何选择器,线条自动跟着 gap 走。

column-rule 以前就存在,只是不支持 Grid 和 Flex。多列布局(column-count)里 column-rule 早就有了,但同样的属性套到 Grid 或 Flex 容器上,Safari 和 Firefox 之前都是零反应。Chrome/Edge 149 把这个能力补上了,而且顺带加了 row-rule 来处理水平分隔线。

进阶控制:线条长短和交叉口

线条默认贯通整个 gap,但经常需要控制两端收进去多少。column-rule-insetrow-rule-inset 就是做这个的,支持固定长度值,也支持一个叫 overlap-join 的关键字——让竖线和横线在交叉口无缝拼接成一个完整的十字格。

.posts-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 2rem;
  rule: 2px solid #d1d5db;               /* 同时控制横竖线 */
  rule-inset: overlap-join;              /* 交叉口无缝拼接 */
}

还有更细的控制粒度:column-rule-inset-cap 控制线条在碰到容器边缘时的收进距离,column-rule-inset-junction 控制线条在穿过另一条线时的收进距离——这两个可以设不同的值,适合那种外框是粗线、内部交叉是细线的设计。

线条的叠放顺序

当横竖线同时存在时,总有一条会压另一条。rule-overlap 属性可以指定哪条在上:column-over-row 就是竖线压横线,让整列的视觉主导权在垂直线上。

.dashboard {
  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;
}

这个在后台管理界面和密集型链接目录里很实用——主导航竖线清晰,次级分割横线不抢视线。

进阶:不同 gap 不同线条

repeat() 函数也可以用在规则值里,让不同的 gap 呈现不同的线条粗细或样式,比如日历里整点用粗线、半点用虚线:

.calendar {
  row-rule-width: 2px, 1px;
  row-rule-style: solid, dashed;
  row-rule-color: #e8e4df, #f0ece7;
}

第一个值对应第一个 gap,第二个值对应第二个 gap,超出的部分从头循环。

和旧方式的对比

旧方式(border hack) Gap Decorations
代码量 15 行 + nth-child 5 行
改列数 要改 nth-child 不需要动
flex 换行 要重算最后一列 自动跟随
响应式 每个断点都要改 一个属性全适配
无障碍 额外 DOM 节点进 Accessibility Tree 不增加 DOM

浏览器支持现状

Chrome 和 Edge 从 149 版本开始支持,Firefox 和 Safari 还没有实现。因为是纯视觉效果,不支持的浏览器只是不画线,布局本身完全正常,所以可以渐进增强:用 @supports (column-rule: 1px solid) 做特性检测,没支持的地方显示干净的 gap 就好,等两家补上再撤掉旧代码。

什么时候值得用

现在最值的场景:卡片网格、数据表格、仪表盘、任何需要横竖分隔线的密集布局。以前光为了加根线就要在每个子元素上写 border 再用 nth-child 去掉边缘,现在直接两行属性搞定,改设计图的时候也不需要动组件结构。


总结一下:Grid 和 Flex 的分隔线终于不需要靠每个子元素撑 border 了。column-rule + row-rule 把线条的绘制权从子元素还给了容器,配合 rule-inset 做精细收进、rule-overlap 控制叠放顺序、repeat() 动态样式——这是近年来 CSS 布局上最实用的新能力之一。等 Firefox 和 Safari 补上之后,前端代码库里那堆 nth-child 分隔线 hack 就可以逐步退休了。

评论区

0 条评论

登录后可评论。