html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>步骤条</title>
<link rel="stylesheet" href="./index.css">
</head>
<body>
<div class="container">
<div class="steps_wrapper ">
<div class="step step_active">1</div>
<div class="step">2</div>
<div class="step">3</div>
<div class="step">4</div>
<div class="line transition400" id="line"></div>
</div>
<div class="btn_wrapper transition400">
<button class="btn " disabled id="pre">上一步</button>
<button class="btn " id="next">下一步</button>
</div>
</div>
<script src="./index.js"></script>
</body>
</html>
css
$primary: #24acf2;
@mixin center {
display: flex;
align-items: center;
justify-content: center;
}
.transition400 {
transition: all 400ms ease;
}
.transition500 {
transition: all 500ms ease;
}
.container {
@include center();
flex-direction: column;
height: 100vh;
.steps_wrapper {
display: flex;
gap: 50px;
position: relative;
&::after,
.line {
content: '';
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
width: 100%;
height: 3px;
background-color: #eee;
z-index: -2;
}
.line {
width: 0;
background-color: $primary;
z-index: -1;
}
.step {
border-radius: 50%;
border: 2px solid #e0e0e0;
box-sizing: border-box;
@include center();
width: 30px;
height: 30px;
font-size: 14px;
color: #999;
background-color: #fff;
}
.step_active {
background-color: $primary;
color: #fff;
border-color: $primary;
transition: 0.4s 0.2s all ease;
}
}
.btn_wrapper {
display: flex;
gap: 20px;
margin-top: 36px;
.btn {
width: 90px;
height: 32px;
background-color: $primary;
border: 1px solid $primary;
border-radius: 8px;
color: #fff;
cursor: pointer;
}
.btn:active {
transform: scale(0.98);
opacity: 0.9;
}
.btn:disabled {
cursor: not-allowed;
background-color: #eee;
border-color: #eee;
}
}
}
js
const state = {
pre: document.getElementById('pre'),
next: document.getElementById('next'),
line: document.getElementById('line'),
steps: document.querySelectorAll(`.step`),
len: 4,
cur: 0,
process: {
pre: () => {
if (state.cur > 0) {
state.cur--;
}
},
next: () => {
if (state.cur < state.len) {
state.cur++;
}
}
}
}
state.pre.onclick = () => update('pre')
state.next.onclick = () => update('next')
function update(type) {
// 增减操作
state.process[type]()
// 禁用上一步,下一步
state.pre.disabled = false;
state.next.disabled = false;
if (state.cur == 0) {
state.pre.disabled = true
}
if (state.cur + 1 == state.len) {
state.next.disabled = true
}
// 设置样式
setStyle()
}
function setStyle() {
const step_actives = document.querySelectorAll('.step_active');
step_actives.forEach(item => item.classList.remove('step_active'));
state.line.style.width = `${(state.cur) * 33}%`;
state.steps.forEach((item, i) => {
if (i <= state.cur) {
item.classList.add('step_active');
}
})
}