I have a pure html stepper. It works if the ‘active’ class is in the 2nd, 3rd and so on element. But I have a problem if the ‘active’ class is only in the 1st class.
How do I make it if the ‘active’ class is in the first class, then no line is colored? If only the first stepper has active, then no line should be changing color, only the color before the stepper with the active class should be colored.
:root {
--circle-size: clamp(1.5rem, 5vw, 3rem);
--spacing: clamp(0.25rem, 2vw, 0.5rem);
}
.stepper {
display: flex;
}
.stepper-item {
display: flex;
flex-direction: column;
flex: 1;
text-align: center;
&::before {
--size: 3rem;
content: "";
display: block;
width: var(--circle-size);
height: var(--circle-size);
border-radius: 50%;
border: 0.4rem solid green;
background-color: transparent;
opacity: 0.5;
margin: 0 auto 1rem;
}
&:not(:last-child) {
&::after {
content: "";
position: relative;
top: calc(var(--circle-size) / 2);
width: calc(100% - var(--circle-size) - calc(var(--spacing) * 2));
left: calc(50% + calc(var(--circle-size) / 2 + var(--spacing)));
height: 2px;
background-color: #448b62;
order: -1;
}
}
}
.stepper-title {
font-weight: bold;
font-size: clamp(1rem, 4vw, 1.25rem);
margin-bottom: 0.5rem;
color: #448b62;
}
.stepper-desc {
color: grey;
font-size: clamp(0.85rem, 2vw, 1rem);
padding-left: var(--spacing);
padding-right: var(--spacing);
}
/*** Non-demo CSS ***/
.wrapper {
max-width: 100%;
margin: 2rem auto 0;
}
*,
*:before,
*:after {
box-sizing: border-box;
}
.stepper-item::before {
--size: 3rem;
content: attr(data-step);
/* Use a custom attribute for step number */
display: flex;
align-items: center;
justify-content: center;
width: var(--circle-size);
height: var(--circle-size);
border-radius: 50%;
border: 4% solid rgb(0, 64, 255);
opacity: 0.5;
margin: 0 auto 1rem;
font-weight: bold;
font-size: 1.25rem;
color: #448b62;
/* Font customization */
font-family: 'Poppins', sans-serif;
/* Change to any desired font */
font-weight: 700;
/* Bold */
font-size: 1.5rem;
/* Adjust size */
letter-spacing: 0.05rem;
/* Optional spacing */
}
.stepper-item.active::before {
opacity: 1;
border: 0.4rem solid red;
color: red;
}
.stepper-item.active .stepper-title {
color: red;
}
.stepper-item.active:is(:first-child):after {
background-color: red;
opacity: 1;
}
/* Style the line between consecutive active items */
.stepper-item.active+.active:before {
opacity: 1;
}
.stepper-item:not(:last-child)::after {
content: "";
position: relative;
top: calc(var(--circle-size) / 2);
width: calc(100% - var(--circle-size) - calc(var(--spacing) * 2));
left: calc(50% + calc(var(--circle-size) / 2 + var(--spacing)));
height: 2px;
background-color: #448b62;
opacity: 0.5;
order: -1;
}
/* Color line red only when current item is active AND next item is active */
.stepper-item:not(:first-child).active:not(:last-child):has(+ .active)::after {
background-color: red;
opacity: 1;
}
/* Special case for first item - only color if next is active */
.stepper-item:first-child.active:has(+ .active)::after {
background-color: rgb(255, 0, 0);
opacity: 1;
}
<div class="wrapper">
<ol class="stepper">
<li class="stepper-item active" data-step="1">
<h3 class="stepper-title">Step 1</h3>
<p class="stepper-desc">Authentication started</p>
</li>
<li class="stepper-item active" data-step="2">
<h3 class="stepper-title">Step 2</h3>
<p class="stepper-desc">Authentication successful</p>
</li>
<li class="stepper-item active" data-step="3">
<h3 class="stepper-title">Step 3</h3>
<p class="stepper-desc">Authorization complete</p>
</li>
<li class="stepper-item" data-step="4">
<h3 class="stepper-title">Step 4</h3>
<p class="stepper-desc">Finalizing process</p>
</li>
<li class="stepper-item" data-step="5">
<h3 class="stepper-title">Step 5</h3>
<p class="stepper-desc">Process complete</p>
</li>
</ol>
</div>
2
Answers
Looks to me that all you need to do is comment out or remove this CSS:
Full snippet demonstrating that this solves the problem is below.
First of all, you’ve mixed
CSS
andSASS
in your code example.&::before
,&:not(:last-child)
and&::after
areSASS
syntax. This is not really relevant for solving the problem, but I wanted to mention it anyway, as it can lead to undesirable results later on (fixed in my example).To solve your actual problem, either do what @Blake Jones already suggested in his answer or if this is not possible for some reason you must define another "special case" in which the first line has no color (it remains green) if the first item is the only active element. For this just add the following at the end of your
CSS
rules, right after the other "special cases".