Create css circles connected by line

Viewed 394

I need to do this kind of slider that is just three circles connected by a line and with a description below each circle:

enter image description here

But at the moment I just have this:

enter image description here

And this is the code I used to make that:

            <div
              class="
                text-center
                my-5
                px-5
                d-flex
                align-items-center
                justify-content-between
                slider-container
              "
            >
              <div class="slider-item">
                <i
                  class="
                    icon-circle
                    fs-16 fs-md-20
                    d-inline-block
                    text-gray-300
                  "
                ></i>
                <p class="m-0 font-RobotoBold1 fs-10 fs-md-12 mt-2">
                  Selecciona <br />
                  cantidad
                </p>
              </div>
              <div>
                <i
                  class="
                    icon-circle
                    fs-16 fs-md-20
                    d-inline-block
                    text-gray-300
                  "
                ></i>
                <p class="m-0 font-RobotoBold1 fs-10 fs-md-12 mt-2">
                  Selecciona <br />
                  destino
                </p>
              </div>
              <div>
                <i
                  class="
                    icon-circle
                    fs-16 fs-md-20
                    d-inline-block
                    text-gray-300
                  "
                ></i>
                <p class="m-0 font-RobotoBold1 fs-10 fs-md-12 mt-2">
                  Confirma <br />
                  transferencia
                </p>
              </div>
            </div>

This is the css code:

.slider-container {
  position: relative;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 1em;
  overflow: hidden;
}

.slider-container::before {
  position: absolute;
  top: calc(50% - 20px);
  right: 0;
  left: 0;
  Content: "";
  Background-color: grey;
  height: 1px;
  z-index: -1;
}

Anyone knows how to make that line behind the circles and that doesn't exceed them?

2 Answers

Sidenote: This is why I would never use tailwindcss or the likes. You don't need it, and it totally ruins the HTML.

Now compare the markup you have with the markup below - which is a) much, much more concise, b) using only a single CSS class and c) using the proper semantic elements for the job.

It also works for 2 or 4 or 7 items. Sure it needs some refinement regarding size and color of the active circle, but that should be an easy adjustment for you.

The only restriction of this solution is that your page background-color needs to be solid and be matched by the background-color of the ::after elements.

document.querySelectorAll('.steplist').forEach(steplist => {
  steplist.addEventListener('click', function(event) {
    if (event.target.nodeName !== 'LI') return;
    const items = event.target.closest('.steplist').querySelectorAll('li');
    for (const item of items) {
      item.classList.toggle('active', item === event.target);
    }
  });
});
*, ::after, ::before { box-sizing: border-box; }

.steplist {
  border-top: 2px solid #ccc;
  display: inline-flex;
  font-family: 'Gill Sans', 'Gill Sans MT', Calibri, 'Trebuchet MS', sans-serif;
  list-style-type: none;
  gap: 7em;
  margin: 0;
  padding: 0;
  --circle-radius: 8px;
}

.steplist li {
  color: #999;
  cursor: pointer;
  padding: calc(5px + var(--circle-radius)) 0 0;
  margin: 0;
  position: relative;
  text-align: center;
}

.steplist li::before {
  background-color: #ccc;
  border-radius: 50%;
  content: '';
  position: absolute;
  height: calc(2 * var(--circle-radius));
  width: calc(2 * var(--circle-radius));
  top: 0;
  left: 50%;
  transform: translate(-50%, -50%);
  transition: all 0.3s ease;
}

.steplist .active {
  color: black;
}

.steplist .active::before {
  background-color: green;
  box-shadow: 0 0 0 3px rgba(0,255,0,.25);
}

.steplist li:first-child::after {
  background-color: white;
  content: '';
  position: absolute;
  height: 2px;
  width: 100%;
  top: -2px;
  left: calc(-50% - var(--circle-radius));
}

.steplist li:last-child::after {
  background-color: white;
  content: '';
  position: absolute;
  height: 2px;
  width: 100%;
  top: -2px;
  left: calc(50% + var(--circle-radius));
}

.circle-big {
  --circle-radius: 12px;
}
<ol class="steplist">
  <li>Point 1<br>whatever</li>
  <li>Point 2<br>whatever</li>
  <li>Point 3<br>whatever</li>
</ol>

<br><br><br>

<ol class="steplist circle-big">
  <li>Point 1<br>whatever</li>
  <li>Point 2<br>whatever</li>
  <li>Point 3<br>whatever</li>
  <li>Point 4<br>whatever</li>
</ol>

Finally I solve the case with this code, I added the custom classes so you can understand what are those, and in the slider-container:before, the formula 'top: calc(50% - 22px)', the px can change depending of the size of the screen. :

/* slider css code */

.slider-container {
  position: relative;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 1em;
  overflow: hidden;
}

.slider-container::before {
  position: absolute;
  top: calc(50% - 22px);
  right: 65px;
  left: 65px;
  content: "";
  background-color: #d8d8d8;
  height: 1px;
  z-index: -1;
}

@media (max-width: 768px) {
  .slider-container::before {
    top: calc(50% - 22px);
    right: 60px;
    left: 60px;
  }
}


/* this are custom css classes we use at work */

.wi-12 {
  width: 12px;
}

.he-12 {
  height: 12px;
}

.wi-24 {
  width: 24px;
}

.he-24 {
  height: 24px;
}

@media (min-width: 768px) {
  .wi-md-20 {
    width: 20px;
  }
  .he-md-20 {
    height: 20px;
  }
  .wi-md-30 {
    width: 30px;
  }
  .he-md-30 {
    height: 30px;
  }
  .wi-md-100 {
    width: 100px;
  }
}

.wi-70 {
  width: 70px;
}

.bg-green-700 {
  background-color: #00bf79;
}

.bg-gray-300 {
  background-color: #bababa;
}

.bor-rounded-full {
  border-radius: 50%;
}

.font-Roboto {
  font-family: "Roboto";
}

.fs-10 {
  font-size: 10px;
}

.fs-md-12 {
  font-size: 12px;
}
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" />

<div class="
                text-center
                mt-md-4
                px-4
                d-flex
                align-items-center
                justify-content-between
                slider-container
                mb-md-3
              ">
  <div class="slider-item wi-70 wi-md-100">
    <div class="
                    wi-24
                    he-24
                    wi-md-30
                    he-md-30
                    bor-rounded-full
                    d-inline-flex
                    justify-content-center
                    align-items-center
                  " style="
                   background: rgba(0, 191, 121, 0.3);
                  ">
      <div class="wi-12 he-12 wi-md-20 he-md-20 bg-green-700 bor-rounded-full d-inline-block"></div>
    </div>
    <p class="m-0 font-Roboto fs-10 fs-md-12 mt-2">
      Selecciona <br /> cantidad
    </p>
  </div>
  <div class="slider-item wi-70 wi-md-100">
    <div class="
                    wi-24
                    he-24
                    wi-md-30
                    he-md-30
                    bor-rounded-full
                    d-inline-flex
                    justify-content-center
                    align-items-center
                  ">
      <div class="wi-12 he-12 wi-md-20 he-md-20 bg-gray-300 bor-rounded-full d-inline-block"></div>
    </div>
    <p class="m-0 font-Roboto fs-10 fs-md-12 mt-2">
      Selecciona <br /> destino
    </p>
  </div>
  <div class="slider-item wi-70 wi-md-100">
    <div class="
                    wi-24
                    he-24
                    wi-md-30
                    he-md-30
                    bor-rounded-full
                    d-inline-flex
                    justify-content-center
                    align-items-center
                  ">
      <div class="wi-12 he-12 wi-md-20 he-md-20 bg-gray-300 bor-rounded-full d-inline-block"></div>
    </div>
    <p class="m-0 font-Roboto fs-10 fs-md-12 mt-2">
      Confirma <br /> transferencia
    </p>
  </div>
</div>

Related