The very first thing we need is the HTML structure.
index.html
<div class="stepper-wrapper">
<div class="stepper-item completed">
<div class="step-counter">1</div>
<div class="step-name">First</div>
</div>
<div class="stepper-item completed">
<div class="step-counter">2</div>
<div class="step-name">Second</div>
</div>
<div class="stepper-item active">
<div class="step-counter">3</div>
<div class="step-name">Third</div>
</div>
<div class="stepper-item">
<div class="step-counter">4</div>
<div class="step-name">Forth</div>
</div>
</div>
We have a wrapper that contains all of the steps. And each step consist of a pair of <div>s: one for the number and the other for the description.
As you can see, each step can have states: completed or active. Now let’s take a look at the CSS:
styles.css
.stepper-wrapper {
font-family: Arial;
margin-top: 50px;
display: flex;
justify-content: space-between;
margin-bottom: 20px;
}
.stepper-item {
position: relative;
display: flex;
flex-direction: column;
align-items: center;
flex: 1;
@media (max-width: 768px) {
font-size: 12px;
}
}
.stepper-item::before {
position: absolute;
content: "";
border-bottom: 2px solid #ccc;
width: 100%;
top: 20px;
left: -50%;
z-index: 2;
}
.stepper-item::after {
position: absolute;
content: "";
border-bottom: 2px solid #ccc;
width: 100%;
top: 20px;
left: 50%;
z-index: 2;
}
.stepper-item .step-counter {
position: relative;
z-index: 5;
display: flex;
justify-content: center;
align-items: center;
width: 40px;
height: 40px;
border-radius: 50%;
background: #ccc;
margin-bottom: 6px;
}
.stepper-item.active {
font-weight: bold;
}
.stepper-item.completed .step-counter {
background-color: #4bb543;
}
.stepper-item.completed::after {
position: absolute;
content: "";
border-bottom: 2px solid #4bb543;
width: 100%;
top: 20px;
left: 50%;
z-index: 3;
}
.stepper-item:first-child::before {
content: none;
}
.stepper-item:last-child::after {
content: none;
}
While a little verbose, the code above is easy to read.
output.html
<div class="mt-auto flex w-full justify-between">
<!-- first step -->
<div class="before:content-[''] after:content-[''] relative flex flex-1 flex-col items-center before:absolute before:-left-1/2 before:top-4 before:z-[2] before:w-full before:border-b-2 before:border-blue-500 after:absolute after:left-1/2 after:top-4 after:z-[2] after:w-full after:border-b-2 first:before:content-none last:after:content-none">
<div class="relative z-[5] mb-[6px] flex h-8 w-8 items-center justify-center rounded-full bg-blue-500 text-white">
1
</div>
<div class="text-sm text-black">
Step 1
</div>
</div>
<!-- second step -->
<div class="before:content-[''] after:content-[''] relative flex flex-1 flex-col items-center before:absolute before:-left-1/2 before:top-4 before:z-[2] before:w-full before:border-b-2 before:border-dashed before:border-gray-300 after:absolute after:left-1/2 after:top-4 after:z-[2] after:w-full after:border-b-2 first:before:content-none last:after:content-none">
<div class="relative z-[5] mb-[6px] flex h-8 w-8 items-center justify-center rounded-full bg-gray-100 border border-gray-300">
2
</div>
</div>
<!-- third step -->
<div class="before:content-[''] after:content-[''] relative flex flex-1 flex-col items-center before:absolute before:-left-1/2 before:top-4 before:z-[2] before:w-full before:border-b-2 before:border-dashed before:border-gray-300 after:absolute after:left-1/2 after:top-4 after:z-[2] after:w-full after:border-b-2 first:before:content-none last:after:content-none">
<div class="relative z-[5] mb-[6px] flex h-8 w-8 items-center justify-center rounded-full bg-gray-100 border border-gray-300">
3
</div>
</div>
</div>