Stepper
介绍
多步流程指示:连接线按进度填充,完成的步骤变成对勾,当前步骤有呼吸光圈。附上一步 / 下一步。
纯 HTML、CSS 与少量原生 JS,没有框架依赖。复制提示词交给 Claude Code、Cursor、Trae 或 Codex,模型会把 Stepper 加进你的项目并换成你的配色。
适用场景
官网顶部导航、标签切换、分段控制、侧边导航和页脚。
安装
订阅 Builder 后,用 8pt CLI 装进项目,或在已接入 8pt MCP 的编辑器里直接调用。
$ npm i -g @8pt-dev/cli && 8pt add stepper
mcp › 使用 8pt MCP 调用 get_component("stepper")
代码
Stepper 的源码,动效只用 transform 与 opacity,并尊重减少动态效果设置。
<div class="x-step">
<ol class="x-step__list">
<li class="on"><i>1</i><span>账户</span></li>
<li><i>2</i><span>团队</span></li>
<li><i>3</i><span>主题</span></li>
<li><i>4</i><span>完成</span></li>
</ol>
<div class="x-step__track" aria-hidden="true"><span></span></div>
<div class="x-step__ctl"><button type="button" data-d="-1" disabled>上一步</button><button type="button" data-d="1" class="pri">下一步</button></div>
</div>.x-step{position:relative;width:min(340px,100%);color:var(--d-fg,#fff)}
.x-step__list{position:relative;z-index:1;display:grid;grid-template-columns:repeat(4,1fr);margin:0;padding:0;list-style:none}
.x-step__list li{display:grid;justify-items:center;gap:8px;font:500 12px/1 var(--d-font,system-ui,sans-serif);color:var(--d-muted,#9b9ba8);transition:color .3s}
.x-step__list i{position:relative;display:grid;place-items:center;width:30px;height:30px;border-radius:50%;font:700 12px/1 var(--d-font,system-ui,sans-serif);font-style:normal;background:var(--d-card,#14141c);border:1.5px solid var(--d-line,rgba(255,255,255,.16));transition:background-color .3s,border-color .3s,color .3s}
.x-step__list li.on,.x-step__list li.done{color:var(--d-fg,#fff)}
.x-step__list li.on i{border-color:var(--d-accent,#4D74FF);color:var(--d-accent,#4D74FF)}
.x-step__list li.on i::after{content:"";position:absolute;inset:-6px;border-radius:50%;border:1.5px solid var(--d-accent,#4D74FF);opacity:0;animation:x-step-pulse 1.8s ease-out infinite}
@keyframes x-step-pulse{0%{transform:scale(.8);opacity:.7}100%{transform:scale(1.25);opacity:0}}
.x-step__list li.done i{background:var(--d-accent,#4D74FF);border-color:var(--d-accent,#4D74FF);color:#fff;font-size:0}
.x-step__list li.done i::before{content:"✓";font-size:14px}
.x-step__track{position:absolute;left:12.5%;right:12.5%;top:14px;height:2px;border-radius:2px;background:var(--d-line,rgba(255,255,255,.14));overflow:hidden}
.x-step__track span{display:block;height:100%;background:var(--d-accent,#4D74FF);transform-origin:left;transform:scaleX(0);transition:transform .55s cubic-bezier(.65,0,.35,1)}
…const init = (root) => {
const items = [...root.querySelectorAll('.x-step__list li')], bar = root.querySelector('.x-step__track span');
const [prev, next] = root.querySelectorAll('.x-step__ctl button');
let cur = 0;
const draw = () => {
items.forEach((li, i) => { li.classList.toggle('done', i < cur); li.classList.toggle('on', i === cur); });
bar.style.transform = `scaleX(${cur / (items.length - 1)})`;
prev.disabled = cur === 0; next.textContent = cur === items.length - 1 ? '重新开始' : '下一步';
};
prev.addEventListener('click', () => { cur = Math.max(0, cur - 1); draw(); });
next.addEventListener('click', () => { cur = cur === items.length - 1 ? 0 : cur + 1; draw(); });
draw();
…订阅 Builder 查看完整源码。查看价格