如何用CSS伪元素和Border-left打造长尾词式垂直步骤条?
- 内容介绍
- 文章标签
- 相关推荐
本文共计1172个文字,预计阅读时间需要5分钟。
使用是稳定的语义化起点,不建议使用堆砌。每个代表一个步骤节点,容器设置为flex-direction: column或绝对定位,但必须保证子项垂直排列且上下关系明确。
关键点在于:步骤圆点(.step-circle)和连接线(.step-line)要分离控制。圆点用绝对定位居中在左侧,连接线用伪元素或额外元素画在圆点右侧——但更轻量的做法是让 ::before 画竖线,::after 画圆点,这样 DOM 更干净。
- 避免给
li设固定高度,用padding-bottom控制间距更灵活 - 连接线高度不能写死,应由 JS 动态计算或用
height: 100%配合父容器position: relative - 最后一个步骤的连接线必须隐藏,否则会多出一截:用
.step:last-child .step-line { display: none; }
用 ::before 画竖线时 border-left 怎么配
竖线本质是一条细长矩形,border-left 最省事,但要注意它依赖父元素的 height 和 position。常见错误是直接在 li 上写 border-left: 2px solid #ddd —— 这会让所有步骤都带左边框,破坏单一线条效果。
正确做法是把竖线抽成独立伪元素,锚定在第一个步骤之后:
立即学习“前端免费学习笔记(深入)”;
.step::before { content: ''; position: absolute; top: 0; left: 20px; /* 圆点中心横坐标 */ height: 100%; width: 2px; background-color: #ddd; z-index: -1; } <p>.step:first-child::before { display: none; }
-
z-index: -1确保线条在圆点下方,不遮挡内容 - 如果步骤高度不均,
height: 100%可能失效,此时改用inset: 0 0 0 20px+height: auto更可靠 - 别用
border-left模拟竖线,它无法脱离元素盒模型边界,缩放或动画时易错位
圆点用 ::after 实现时为什么总偏移
圆点定位依赖两个值:水平位置(left)和垂直居中(transform: translateY(-50%))。最容易被忽略的是父容器没设 position: relative,导致 absolute 定位向上冒泡到 body,圆点全飘走。
典型修复写法:
.step { position: relative; padding-left: 70px; /* 为圆点和线留出左侧空间 */ } <p>.step::after { content: ''; position: absolute; left: 0; top: 50%; transform: translateY(-50%); width: 40px; height: 40px; border-radius: 50%; background-color: #ddd; text-align: center; line-height: 40px; }
- 圆点文字编号建议用单独
span而非content,方便动态更新和屏幕阅读器识别 -
line-height必须等于height才能真正垂直居中,仅靠transform在某些 zoom 场景下会失准 - 移动端需加
@media (max-width: 768px)重设left和width,否则圆点挤出视口
状态切换(active / done)时颜色和连线怎么联动
激活态不只是改圆点背景色,连接线也要同步变色——但不能简单写 .step.active::before { background: #ca8a04; },因为 ::before 是所有步骤共用的伪元素,会导致整条线变色。
真正可控的方式是:每段连接线属于上一个步骤,即第 n 步的 ::before 控制第 n−1 到第 n 的连线。所以激活第 3 步时,要同时影响第 2 步的线和第 3 步的圆点:
.step:nth-child(2).active ~ .step:nth-child(3)::before, .step:nth-child(3).active::before { background-color: #ca8a04; } <p>.step.active::after { background-color: #ca8a04; color: #fff; }
- CSS 选择器层级容易失控,建议用 BEM 命名如
.step--active避免嵌套过深 - 若步骤数动态变化(如 Vue v-for),纯 CSS 无法精确控制“上一段线”,此时必须用 class 绑定或 JS 注入样式
- 过渡动画只加在
background-color和transform上,避免height或top动画引发重排
实际项目里最常漏掉的是焦点管理与键盘导航支持——圆点没加 tabindex="0",Enter 键无法触发步骤跳转,这对可访问性是硬伤。伪元素本身不可聚焦,必须把交互逻辑落在 li 或内部 button 上。
本文共计1172个文字,预计阅读时间需要5分钟。
使用是稳定的语义化起点,不建议使用堆砌。每个代表一个步骤节点,容器设置为flex-direction: column或绝对定位,但必须保证子项垂直排列且上下关系明确。
关键点在于:步骤圆点(.step-circle)和连接线(.step-line)要分离控制。圆点用绝对定位居中在左侧,连接线用伪元素或额外元素画在圆点右侧——但更轻量的做法是让 ::before 画竖线,::after 画圆点,这样 DOM 更干净。
- 避免给
li设固定高度,用padding-bottom控制间距更灵活 - 连接线高度不能写死,应由 JS 动态计算或用
height: 100%配合父容器position: relative - 最后一个步骤的连接线必须隐藏,否则会多出一截:用
.step:last-child .step-line { display: none; }
用 ::before 画竖线时 border-left 怎么配
竖线本质是一条细长矩形,border-left 最省事,但要注意它依赖父元素的 height 和 position。常见错误是直接在 li 上写 border-left: 2px solid #ddd —— 这会让所有步骤都带左边框,破坏单一线条效果。
正确做法是把竖线抽成独立伪元素,锚定在第一个步骤之后:
立即学习“前端免费学习笔记(深入)”;
.step::before { content: ''; position: absolute; top: 0; left: 20px; /* 圆点中心横坐标 */ height: 100%; width: 2px; background-color: #ddd; z-index: -1; } <p>.step:first-child::before { display: none; }
-
z-index: -1确保线条在圆点下方,不遮挡内容 - 如果步骤高度不均,
height: 100%可能失效,此时改用inset: 0 0 0 20px+height: auto更可靠 - 别用
border-left模拟竖线,它无法脱离元素盒模型边界,缩放或动画时易错位
圆点用 ::after 实现时为什么总偏移
圆点定位依赖两个值:水平位置(left)和垂直居中(transform: translateY(-50%))。最容易被忽略的是父容器没设 position: relative,导致 absolute 定位向上冒泡到 body,圆点全飘走。
典型修复写法:
.step { position: relative; padding-left: 70px; /* 为圆点和线留出左侧空间 */ } <p>.step::after { content: ''; position: absolute; left: 0; top: 50%; transform: translateY(-50%); width: 40px; height: 40px; border-radius: 50%; background-color: #ddd; text-align: center; line-height: 40px; }
- 圆点文字编号建议用单独
span而非content,方便动态更新和屏幕阅读器识别 -
line-height必须等于height才能真正垂直居中,仅靠transform在某些 zoom 场景下会失准 - 移动端需加
@media (max-width: 768px)重设left和width,否则圆点挤出视口
状态切换(active / done)时颜色和连线怎么联动
激活态不只是改圆点背景色,连接线也要同步变色——但不能简单写 .step.active::before { background: #ca8a04; },因为 ::before 是所有步骤共用的伪元素,会导致整条线变色。
真正可控的方式是:每段连接线属于上一个步骤,即第 n 步的 ::before 控制第 n−1 到第 n 的连线。所以激活第 3 步时,要同时影响第 2 步的线和第 3 步的圆点:
.step:nth-child(2).active ~ .step:nth-child(3)::before, .step:nth-child(3).active::before { background-color: #ca8a04; } <p>.step.active::after { background-color: #ca8a04; color: #fff; }
- CSS 选择器层级容易失控,建议用 BEM 命名如
.step--active避免嵌套过深 - 若步骤数动态变化(如 Vue v-for),纯 CSS 无法精确控制“上一段线”,此时必须用 class 绑定或 JS 注入样式
- 过渡动画只加在
background-color和transform上,避免height或top动画引发重排
实际项目里最常漏掉的是焦点管理与键盘导航支持——圆点没加 tabindex="0",Enter 键无法触发步骤跳转,这对可访问性是硬伤。伪元素本身不可聚焦,必须把交互逻辑落在 li 或内部 button 上。

