build a timeline using CSS

Viewed 56

I'm trying to achieve the following:

enter image description here

The problem I still have is the line before the first element and after the last element should be hidden.

The second issue is that the numbers are not vertically centered even when I use a flexbox with align-items and justify-content, if I zoom the picture a bit you can see that there is some difference:

enter image description here

The difference without zooming is about 2px~3px.

This is what I tried:

.container {
  margin-top: 60px;
  position: relative;
}
ol {
    counter-reset: section;
    list-style-type: none;
    border-top: 1px solid #D9DEEA;
    padding: 0;
    margin: 36px 0 210px 0;
  }
  li {
    float: left;
    width: 20%;
    padding-top: calc(58px / 2);
    position: relative;
    font-family: 'Antonio', sans-serif;
    font-weight: 700;
    display: flex;
    flex-direction: column;
    align-items: center;
  }
  li::before {
      counter-increment: section;
      content: counters(section, ".") " ";
      width: 56px;
      height: 56px;
      background: #fff;
      border: 2px dashed #D9DEEA;
      border-radius: 50%;
      box-shadow: 0 0 0 6px #fff;
      position: absolute;
      top: -30.5px;
      left: calc(50% - 30px);
      display: flex;
      justify-content: center;
      align-items: center;
      line-height: 34px;
      font-size: 24px;
    }
  .title {
      margin: 6px 0;
      line-height: 30px;
      letter-spacing: -0.77px;
      font-size: 25px;
      display: block;
      text-align: center;
    }
    .illustration {
      display: block;
      width: 165px;
      height: 140px;
      display: flex;
      align-items: center;
      justify-content: center;
      background-color: #E6E9F0;
    }
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=Antonio:wght@300;400;700&family=Roboto:wght@300;400;500;700&display=swap" rel="stylesheet">
  <section class="container">
    <ol>
      <li>
        <span class="title">Lorem.</span>
        <span class="illustration">
          <img src="" alt="">
        </span>
      </li>
      <li>
        <span class="title">Lorem, ipsum.</span>
        <span class="illustration">
          <img src="" alt="">
        </span>
      </li>
      <li>
        <span class="title">Lorem, ipsum dolor.</span>
        <span class="illustration">
          <img src="" alt="">
        </span>
      </li>
      <li>
        <span class="title">Lorem ipsum.</span>
        <span class="illustration">
          <img src="" alt="">
        </span>
      </li>
      <li>
        <span class="title">Lorem, ipsum dolor.</span>
        <span class="illustration">
          <img src="" alt="">
        </span>
      </li>
    </ol>
  </section>

2 Answers

I finally found a solution for the first issue.

The idea is to use a pseudo-element for ol that will act as a border with limited width.

.container {
  margin-top: 60px;
  position: relative;
}
ol {
    counter-reset: section;
    list-style-type: none;
    padding: 0;
    margin: 36px 0 0 0;
  }
  
ol::before {
  content: "";
  display: block;
  background: #D9DEEA;
  position: absolute;
  top: 0;
  left: 10%;
  height: 1px;
  width: 80%;
}
  li {
    float: left;
    width: 20%;
    padding-top: calc(58px / 2);
    position: relative;
    font-family: 'Antonio', sans-serif;
    font-weight: 700;
    display: flex;
    flex-direction: column;
    align-items: center;
  }
  li::before {
      counter-increment: section;
      content: counters(section, ".") " ";
      width: 56px;
      height: 56px;
      background: #fff;
      border: 2px dashed #D9DEEA;
      border-radius: 50%;
      box-shadow: 0 0 0 6px #fff;
      position: absolute;
      top: -30.5px;
      left: calc(50% - 30px);
      display: flex;
      justify-content: center;
      align-items: center;
      line-height: 34px;
      font-size: 24px;
    }
  .title {
      margin: 6px 0;
      line-height: 30px;
      letter-spacing: -0.77px;
      font-size: 25px;
      display: block;
      text-align: center;
    }
    .illustration {
      display: block;
      width: 165px;
      height: 140px;
      display: flex;
      align-items: center;
      justify-content: center;
      background-color: #E6E9F0;
    }
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=Antonio:wght@300;400;700&family=Roboto:wght@300;400;500;700&display=swap" rel="stylesheet">
  <section class="container">
    <ol>
      <li>
        <span class="title">Lorem.</span>
        <span class="illustration">
          <img src="" alt="">
        </span>
      </li>
      <li>
        <span class="title">Lorem, ipsum.</span>
        <span class="illustration">
          <img src="" alt="">
        </span>
      </li>
      <li>
        <span class="title">Lorem, ipsum dolor.</span>
        <span class="illustration">
          <img src="" alt="">
        </span>
      </li>
      <li>
        <span class="title">Lorem ipsum.</span>
        <span class="illustration">
          <img src="" alt="">
        </span>
      </li>
      <li>
        <span class="title">Lorem, ipsum dolor.</span>
        <span class="illustration">
          <img src="" alt="">
        </span>
      </li>
    </ol>
  </section>

I'm not sure how to fix your problem with the styling of the li::before element, but here is a solution for your timeline not extending past 1 or 5. Add a ::before element to the ol element.

Edit: Solution was sourced from Border length smaller than div width?

.container {
  margin-top: 60px;
  position: relative;
}

ol {
  counter-reset: section;
  list-style-type: none;
  padding: 0;
  margin: 36px 0 210px 0;
}

ol::before {
  content: "";
  height: 10px;
  width: 90%;
  position: absolute;
  top: -10px;
  left: 5%;
  /* or 100px */
  border-bottom: 1px solid magenta;
}

li {
  float: left;
  width: 20%;
  padding-top: calc(58px / 2);
  position: relative;
  font-family: 'Antonio', sans-serif;
  font-weight: 700;
  display: flex;
  flex-direction: column;
  align-items: center;
}

li::before {
  counter-increment: section;
  content: counters(section, ".") " ";
  width: 56px;
  height: 56px;
  background: #fff;
  border: 2px dashed #D9DEEA;
  border-radius: 50%;
  box-shadow: 0 0 0 6px #fff;
  position: absolute;
  top: -30.5px;
  left: calc(50% - 30px);
  display: flex;
  justify-content: center;
  align-items: center;
  line-height: 34px;
  font-size: 24px;
}

.title {
  margin: 6px 0;
  line-height: 30px;
  letter-spacing: -0.77px;
  font-size: 25px;
  display: block;
  text-align: center;
}

.illustration {
  display: block;
  width: 165px;
  height: 140px;
  background: url("../Images/API_EDI/catalog-bg.png") no-repeat center center;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: #E6E9F0;
}
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=Antonio:wght@300;400;700&family=Roboto:wght@300;400;500;700&display=swap" rel="stylesheet">
<section class="container">
  <ol>
    <li>
      <span class="title">Lorem.</span>
      <span class="illustration">
          <img src="" alt="">
        </span>
    </li>
    <li>
      <span class="title">Lorem, ipsum.</span>
      <span class="illustration">
          <img src="" alt="">
        </span>
    </li>
    <li>
      <span class="title">Lorem, ipsum dolor.</span>
      <span class="illustration">
          <img src="" alt="">
        </span>
    </li>
    <li>
      <span class="title">Lorem ipsum.</span>
      <span class="illustration">
          <img src="" alt="">
        </span>
    </li>
    <li>
      <span class="title">Lorem, ipsum dolor.</span>
      <span class="illustration">
          <img src="" alt="">
        </span>
    </li>
  </ol>
</section>

Related