Search code examples
htmlcssflexboxcss-grid

Aligning grid elements with each other


A problem arises when it is necessary to align grid containers with different content inside. If you set the grid-auto-rows: 1fr property, then the grids are aligned, but then there is an empty space between the elements inside the grids. Is it possible to implement alignment without explicitly specifying the height of each element within the grid? How can you get rid of unfilled space?

.list {
  padding: 0;
  margin: 0;
  list-style: none;
  display: flex;
  justify-content: center;
  gap: 31px;
}

.list .item {
    width: 100%;
    display: grid;
    grid-template-columns: 100%;
    grid-template-areas:
      'time'
      'specialty'
      'timeline'
      'university'
      'description';
  }

.time {
  grid-area: time;
}

.specialty {
  grid-area: specialty;
}

.timeline {
  grid-area: timeline;
}

.university {
  grid-area: university;
}

.description {
  grid-area: description;
}
<ul class="list">
  <li class="item">
    <p class="time">2012 - 2016</p>
    <p class="specialty">Programming Language</p>
    <div class="line">
      <div class="line__dot"></div>
      <hr class="line__hr">
    </div>
    <p class="university">Cambridge University
    </p>
    <p class="description">Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.</p>
  </li>
    <li class="item">
    <p class="time">2012 - 2016</p>
    <p class="specialty">Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s</p>
    <div class="line">
      <div class="line__dot"></div>
      <hr class="line__hr">
    </div>
    <p class="university">Cambridge University
    </p>
    <p class="description">Lorem Ipsum is simply dummy text of the printing</p>
  </li>
</ul>


Solution

  • I don't think it's possible to achieve the effect you want using CSS grid. This is because each grid item is not aware of the height taken up by the top portion of the other grid items.

    Here's a solution which requires JavaScript:

    • The top portion of each item (html elements before horizontal line) needs to be wrapped in a container wrapper.
    • No need for CSS grid for item.
    • The setWrapperHeight() function will calculate the height taken up by each wrapper and then set all wrapper heights to a constant value.

    function setWrapperHeight() {
      const wrappers = document.querySelectorAll(".item .wrapper");
    
      // get max height of wrappers
      const maxHeight = [...wrappers].reduce(
        (max, w) => Math.max(w.offsetHeight, max), -1
      );
    
      // set same height to each wrapper
      wrappers.forEach((w) => (w.style.height = `${parseInt(maxHeight)}px`));
    }
    setWrapperHeight();
    .list {
      padding: 0;
      margin: 0;
      list-style: none;
      display: flex;
      justify-content: center;
      gap: 31px;
    }
    
    .list .item {
      outline: 1px solid;
      width: 100%;
    }
    <ul class="list">
      <li class="item">
        <div class="wrapper">
          <p class="time">2012 - 2016</p>
          <p class="specialty">Programming Language</p>
        </div>
        <div class="line">
          <div class="line__dot"></div>
          <hr class="line__hr">
        </div>
        <p class="university">Cambridge University
        </p>
        <p class="description">Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.</p>
      </li>
      <li class="item">
        <div class="wrapper">
          <p class="time">2012 - 2016</p>
          <p class="specialty">Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s</p>
        </div>
        <div class="line">
          <div class="line__dot"></div>
          <hr class="line__hr">
        </div>
        <p class="university">Cambridge University
        </p>
        <p class="description">Lorem Ipsum is simply dummy text of the printing</p>
      </li>
    
    </ul>

    If you want to use CSS grid to position the remaining items in item, wrap the html elements not found in wrapper in another container wrapper2. Apply CSS grid to wrapper2.