skip to Main Content

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.

Below is the screenshot:
enter image description here

: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


  1. Looks to me that all you need to do is comment out or remove this CSS:

    /* .stepper-item.active:is(:first-child):after {
      background-color: red;
      opacity: 1;
    } */
    

    Full snippet demonstrating that this solves the problem is below.

    :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" data-step="2">
          <h3 class="stepper-title">Step 2</h3>
          <p class="stepper-desc">Authentication successful</p>
        </li>
        <li class="stepper-item" 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>
    Login or Signup to reply.
  2. First of all, you’ve mixed CSS and SASS in your code example. &::before, &:not(:last-child) and &::after are SASS 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".

    .stepper-item:first-child.active::after {
      background-color: #448b62;
      opacity: 0.5;
    }
    
    :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;
    }
    .stepper-item::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;
    }
    .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;
         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;
    }
    
    /* Special case for the first position - if it's the only active item */
    .stepper-item:first-child.active::after {
      background-color: #448b62;
      opacity: 0.5;
    }
    <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" data-step="2">
          <h3 class="stepper-title">Step 2</h3>
          <p class="stepper-desc">Authentication successful</p>
        </li>
        <li class="stepper-item" 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>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search