Ivan Debono
Ivan Debono

Reputation: 969

How to properly draw lines between li elements?

I'm building a stepper component to display steps using the ul element in a horizontal way and I have the following code:

body {
  margin: 0;
}

.page-content {
  width: 100%;
  margin: 0 auto;
  display: flex;
  justify-content: center;
  align-items: center;
  background-repeat: no-repeat;
  background-position: center center;
  background-size: cover;
}

.wizard-v4-content {
  background: #fff;
  width: 80%;
  margin: 40px 20px;
  font-family: 'Roboto', sans-serif;
  position: relative;
  display: flex;
  display: -webkit-flex;
}

.wizard-v4-content .wizard-v4-form {
  width: 100%;
  padding-right: 20px;
  padding-left: 20px;
  padding-bottom: 20px;
}

.wizard-v4-form .wizard-v4-header {
  text-align: left;
  padding: 10px 0 5px;
}

.wizard-v4-form .wizard-v4-header .heading {
  margin: 0;
  padding: 20px 0 20px;
}

.wizard-v4-form .wizard-v4-header p {
  margin: 0;
}

.wizard-v4-container {
  width: 100%;
  z-index: -1;
}

.wizard-v4-progressbar {
  width: 90%;
  padding: 0;
  margin: 0 auto;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.wizard-v4-progressbar li {
  list-style-type: none;
  width: 10%;
  float: left;
  font-size: 12px;
  position: relative;
  text-align: center;
  color: darkgray;
}

.wizard-v4-progressbar li:after {
  width: calc(100% - 24px);
  height: 2px;
  content: "";
  position: absolute;
  background-color: darkgray;
  top: 11px;
  left: -50%;
  display: block;
  z-index: 1;
}

.wizard-v4-progressbar li:before {
  width: 24px;
  height: 24px;
  content: "";
  line-height: 30px;
  border: 2px solid darkgray;
  display: block;
  text-align: center;
  margin: 0 auto 10px auto;
  border-radius: 50%;
  background-color: white;
  z-index: 2;
}

.wizard-v4-progressbar li:first-child:after {
  content: none;
}

.wizard-v4-progressbar li.wizard-v4-active {
  font-size: 90%;
  font-weight: bold;
  color: black;
}

.wizard-v4-progressbar li.wizard-v4-active:before {
  width: 28px;
  height: 28px;
  color: green;
  border-color: green;
  background-color: green;
  margin-top: -2px;
}

.wizard-v4-progressbar li.wizard-v4-checked {
  color: black;
}

.wizard-v4-progressbar li.wizard-v4-checked::before {
  font-family: "Font Awesome 5 Free";
  font-weight: bold;
  content: "\f058";
  color: green;
  font-size: 24px;
  display: flex;
  justify-content: center;
  align-items: center;
  border: none;
}

.wizard-v4-progressbar li.wizard-v4-active+li:after {
  background-color: darkgray;
}


/* Responsive */
@media screen and (max-width: 1200px) {}

@media screen and (max-width: 992px) {}

@media screen and (max-width: 768px) {}

@media screen and (max-width: 576px) {}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-xOolHFLEh07PJGoPkLv1IbcEPTNtaed2xpHsD9ESMhqIYd0nLMwNLD69Npy4HI+N" crossorigin="anonymous">

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css" integrity="sha512-Evv84Mr4kqVGRNSgIGL/F/aIDqQb7xQ2vcrdIwxfjThSH8CSR7PBEakCr51Ck+w+/U6swU2Im1vVX0SVk9ABhg==" crossorigin="anonymous" referrerpolicy="no-referrer" />

<div class="page-content">
  <div class="wizard-v4-content">
    <div class="wizard-v4-form">
      <div class="row justify-content-center">
        <div class="col-12">
          <div class="wizard-v4-container">
            <ul class="wizard-v4-progressbar">
              <li class="wizard-v4-checked">Step 1</li>
              <li class="wizard-v4-active">Step 2</li>
              <li>Step 3</li>
              <li>Step 4</li>
              <li>Step 5</li>
            </ul>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

However I have 2 problems:

  1. In this sample, the lines are displayed but they do not connect to the li elements
  2. In the actual project, the lines are not being displayed.

How can I solve this problem?

Upvotes: 1

Views: 112

Answers (2)

Ori Drori
Ori Drori

Reputation: 192607

Here is a solution that uses a grid (ul), and subgrids (the li) to position everything dynamically without spaces:

body {
  height: 100dvh;
  margin: 0;
  align-content: center;
}

.wizard-v4-progressbar {
  display: grid;
  grid-template-columns: 24px;
  grid-auto-flow: column;
  grid-auto-columns: 1fr 24px;
  width: 90%;
  padding: 0;
  margin: 0 auto;
}

.wizard-v4-progressbar li {
  display: grid;
  grid-template-rows: auto auto;
  grid-template-columns: subgrid;
  list-style-type: none;
  font-size: 12px;
  text-align: center;
  color: darkgray;
  
  &:not(:first-child) {
    grid-column: span 2;
  }
}

.wizard-v4-progressbar li span {
  grid-row: 2;
  grid-column: 2;
  white-space: nowrap;
  width: fit-content;
  translate: -50% 0;
  margin-left: 50%;
}

.wizard-v4-progressbar li:not(:first-child):before {
  align-self: center;
  height: 2px;
  content: "";
  background-color: darkgray;
}

.wizard-v4-progressbar li:after {
  width: 24px;
  height: 24px;
  content: "";
  border: 2px solid darkgray;
  text-align: center;
  border-radius: 50%;
  background-color: white;
  z-index: 1;
}

.wizard-v4-progressbar li.wizard-v4-active {
  font-size: 90%;
  font-weight: bold;
  color: black;
}

.wizard-v4-progressbar li.wizard-v4-active:after {
  width: 28px;
  height: 28px;
  color: green;
  border-color: green;
  background-color: green;
  margin-top: -2px;
}

.wizard-v4-progressbar li.wizard-v4-active:before {
  background-color: green;
}

.wizard-v4-progressbar li.wizard-v4-checked {
  color: black;
}

.wizard-v4-progressbar li.wizard-v4-checked::after {
  font-family: "Font Awesome 5 Free";
  font-weight: bold;
  content: "\f058";
  color: green;
  font-size: 24px;
  border: none;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css" integrity="sha512-Evv84Mr4kqVGRNSgIGL/F/aIDqQb7xQ2vcrdIwxfjThSH8CSR7PBEakCr51Ck+w+/U6swU2Im1vVX0SVk9ABhg==" crossorigin="anonymous" referrerpolicy="no-referrer" />

<ul class="wizard-v4-progressbar">
  <li class="wizard-v4-checked"><span>Step 1</span></li>
  <li class="wizard-v4-active"><span>Step 2</span></li>
  <li><span>Step 3</span></li>
  <li><span>Step 4</span></li>
  <li><span>Step 5</span></li>
</ul>

Upvotes: 2

nishanji
nishanji

Reputation: 1

Solution according to your need (if you don't want any animation on the line). This is kind of a hack because we know the width and height of the circle. Most of the styles are same only change done is adding the lines to the <ul> element instead of <li> and using z-index and pseudo-element.

:root {
  --white: #fff;
  --dark-gray: darkgray;
}

body {
  margin: 0;
  background: var(--white);
}

.page-content {
  width: 100%;
  margin: 0 auto;
  display: flex;
  display: -webkit-flex;
  justify-content: center;
  -o-justify-content: center;
  -ms-justify-content: center;
  -moz-justify-content: center;
  -webkit-justify-content: center;
  align-items: center;
  -o-align-items: center;
  -ms-align-items: center;
  -moz-align-items: center;
  -webkit-align-items: center;
  background-repeat: no-repeat;
  background-position: center center;
  background-size: cover;
  -o-background-size: cover;
  -ms-background-size: cover;
  -moz-background-size: cover;
  -webkit-background-size: cover;
}

.wizard-v4-content {
  background: #fff;
  width: 80%;
  margin: 40px 20px;
  font-family: "Roboto", sans-serif;
  position: relative;
  display: flex;
  display: -webkit-flex;
}

.wizard-v4-content .wizard-v4-form {
  width: 100%;
  padding-right: 20px;
  padding-left: 20px;
  padding-bottom: 20px;
}

.wizard-v4-form .wizard-v4-header {
  text-align: left;
  padding: 10px 0 5px;
}

.wizard-v4-form .wizard-v4-header .heading {
  margin: 0;
  padding: 20px 0 20px;
}

.wizard-v4-form .wizard-v4-header p {
  margin: 0;
}

.wizard-v4-container {
  width: 100%;
}

.wizard-v4-progressbar {
  width: 90%;
  padding: 0;
  margin: 0 auto;
  display: flex;
  justify-content: space-between;
  align-items: center;
  position: relative;
  z-index: 1;
}

.wizard-v4-progressbar:after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  border: 2px solid var(--dark-gray);
  top: 50%;
  transform: translateY(-50%);
  z-index: -1;
  margin-top: -4px;
}

.wizard-v4-progressbar li {
  list-style-type: none;
  width: 10%;
  font-size: 12px;
  position: relative;
  text-align: center;
  color: darkgray;
  z-index: 1;
}

.wizard-v4-progressbar li p {
  position: absolute;
  left: 0;
  right: 0;
}

.wizard-v4-progressbar li:before {
  width: 24px;
  height: 24px;
  content: "";
  line-height: 30px;
  border: 2px solid var(--dark-gray);
  display: block;
  text-align: center;
  margin: 0 auto 10px auto;
  border-radius: 50%;
  background-color: white;
  z-index: 2;
}

.wizard-v4-progressbar li:first-child:after {
  content: "";
  position: absolute;
  inset: 0;
  right: 50%;
  background: var(--white);
  z-index: -1;
}

.wizard-v4-progressbar li:last-child:after {
  content: "";
  position: absolute;
  inset: 0;
  left: 50%;
  background: var(--white);
  z-index: -1;
}

.wizard-v4-progressbar li.wizard-v4-active {
  font-size: 90%;
  font-weight: bold;
  color: black;
}

.wizard-v4-progressbar li.wizard-v4-active:before {
  width: 28px;
  height: 28px;
  color: green;
  border-color: green;
  background-color: green;
  margin-top: -2px;
}

.wizard-v4-progressbar li.wizard-v4-checked {
  color: black;
}

.wizard-v4-progressbar li.wizard-v4-checked::before {
  font-family: "Font Awesome 5 Free";
  font-weight: bold;
  content: "\f058";
  color: green;
  font-size: 24px;
  display: flex;
  justify-content: center;
  align-items: center;
  border: none;
}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-xOolHFLEh07PJGoPkLv1IbcEPTNtaed2xpHsD9ESMhqIYd0nLMwNLD69Npy4HI+N" crossorigin="anonymous">

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css" integrity="sha512-Evv84Mr4kqVGRNSgIGL/F/aIDqQb7xQ2vcrdIwxfjThSH8CSR7PBEakCr51Ck+w+/U6swU2Im1vVX0SVk9ABhg==" crossorigin="anonymous" referrerpolicy="no-referrer" />

<div class="page-content">
  <div class="wizard-v4-content">
    <div class="wizard-v4-form">
      <div class="row justify-content-center">
        <div class="col-12">
          <div class="wizard-v4-container">
            <ul class="wizard-v4-progressbar">
              <li class="wizard-v4-checked">
                <p>Step 1</p>
              </li>
              <li class="wizard-v4-active">
                <p>Step 2</p>
              </li>
              <li>
                <p>Step 3</p>
              </li>
              <li>
                <p>Step 4</p>
              </li>
              <li>
                <p>Step 5</p>
              </li>
            </ul>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

Upvotes: 0

Related Questions