用::before/::after在Flex项间加分割线的正确做法是:每项设position:relative和min-width:0,用::after在right:0绘制1px线,:last-child::after隐藏,高DPI下用box-shadow或0.5px border替代background。

如何用 ::before 和 ::after 在 Flex 项之间插入分割线
直接在相邻 Flex 子项之间加 border 或 background 很难控制起止位置,容易溢出或重叠。伪元素才是干净解法:每个子项自己负责右侧(或左侧)的分割线,用 flex-grow 撑开空间,再用伪元素定位到边界。
关键点在于:分割线不是“加在两个元素之间”,而是“由后一个元素的左伪元素绘制,或前一个元素的右伪元素绘制”——推荐后者,逻辑更可控。
- 给每个 Flex 子项设置
position: relative - 用
::after绘制一条垂直线,right: 0+top: 25%+height: 50%居中截断 - 最后一个子项用
:last-child::after { display: none }隐藏多余线 - 避免用
border-right,它会参与盒模型计算,干扰flex-grow的实际占比
为什么 flex-grow 必须配合 min-width: 0 才能撑开伪元素空间
Flex 子项默认有 min-width: auto,会阻止宽度收缩——哪怕你设了 flex-grow: 1,伪元素的 right: 0 也可能因父容器未显式收缩而失效,导致分割线错位或消失。
- 必须为每个 Flex 子项添加
min-width: 0(或min-width: 0px) - 如果子项内含长文本或图片,还需加
overflow: hidden防止内容撑破布局 - 不写
min-width: 0是线上最常被忽略的兼容性坑,尤其在 Safari 和旧版 Chrome 中表现明显
::after 分割线高度动态适配内容高度的写法
固定 height: 50% 只在子项高度一致时可靠。若列表项高度不一(比如含多行文字),需让分割线随内容自适应。
立即学习“前端免费学习笔记(深入)”;
- 去掉
height和top,改用inset: 25% 0(等价于top: 25%; bottom: 25%) - 或更稳妥:用
inset: 0 0 0 auto+width: 1px+margin: auto 0实现垂直居中拉伸 - 不要依赖
line-height计算高度,它对多行、padding、border 不稳定 - 示例:
item::after { content: ""; position: absolute; right: 0; top: 0; bottom: 0; width: 1px; background: #e0e0e0; margin: auto 0; }
移动端适配时分割线被缩放或模糊的修复方式
在 DPR > 1 的设备(如 iPhone)上,1px 的 background 线会被渲染成 2px,显得粗重;用 transform: scaleY(0.5) 又可能引起 subpixel 模糊。
- 优先用
box-shadow: 1px 0 0 #e0e0e0替代background,它在高 DPI 下更锐利 - 或使用媒体查询 +
transform: scaleY(calc(1 / device-pixel-ratio)),但需 JS 注入device-pixel-ratio值才可靠 - 更简单:直接用
border-right: 0.5px solid #e0e0e0(现代浏览器已支持小数 px) - 注意:Safari 对小数 border 的支持从 iOS 16.4 / macOS 13.3 才开始稳定,老版本仍需降级方案
min-width: 0、DPR 处理、:last-child 边界控制这三点,漏掉任一个都会让分割线在某个环境里突然消失或错位。


















