htmlcsscss-grid

How to stretch an element to the available width?


There can be a maximum of three columns in one row, and then when adding a new list item, there is a transfer to a new line and the element must occupy the entire available width of the line, and if there are two new elements, then they divide the width between themselves. Like setting flex: 1 0 315px to elements. Our content will be dynamically added and subtracted. Is it possible to achieve this behavior without display flex?

* {
  box-sizing: border-box;
}

.content {
  display: grid;
  width: 1024px;
  grid-template-columns: 315px 1fr;
  gap: 20px;
}

.content__list {
  grid-row: 2;
  grid-column: 1 / -1;
  display: grid;
  gap: 15px;
  grid-template-columns: repeat(auto-fit, minmax(315px, 1fr));
}
<div class="content">
  <h2 class="content__title">TITLE</h2>
  <ul class="content__list">
    <li class="content__list-item">
      <h3 class="content__list-title">
        Lorem
      </h3>
      <p class="content__list-text">
        Lorem ipsum dolor sit amet consectetur adipisicing elit. Praesentium at dolorum blanditiis minus. Quae facere consequuntur dolorum laborum ipsum nam natus, laboriosam, ab ipsam corrupti eaque sed aperiam quibusdam blanditiis neque nobis omnis saepe ducimus
        voluptas eius eum! Sunt assumenda explicabo fugit molestiae ut, odit quia blanditiis mollitia earum velit.
      </p>
    </li>
    <li class="content__list-item">
      <h3 class="content__list-title">
        Lorem
      </h3>
      <p class="content__list-text">
        Lorem ipsum dolor sit amet consectetur adipisicing elit. Praesentium at dolorum blanditiis minus. Quae facere consequuntur dolorum laborum ipsum nam natus, laboriosam, ab ipsam corrupti eaque sed aperiam quibusdam blanditiis neque nobis omnis saepe ducimus
        voluptas eius eum! Sunt assumenda explicabo fugit molestiae ut, odit quia blanditiis mollitia earum velit.
      </p>
    </li>
    <li class="content__list-item">
      <h3 class="content__list-title">
        Lorem
      </h3>
      <p class="content__list-text">
        Lorem ipsum dolor sit amet consectetur adipisicing elit. Praesentium at dolorum blanditiis minus. Quae facere consequuntur dolorum laborum ipsum nam natus, laboriosam, ab ipsam corrupti eaque sed aperiam quibusdam blanditiis neque nobis omnis saepe ducimus
        voluptas eius eum! Sunt assumenda explicabo fugit molestiae ut, odit quia blanditiis mollitia earum velit.
      </p>
    </li>
    <li class="content__list-item">
      <h3 class="content__list-title">
        Lorem
      </h3>
      <p class="content__list-text">
        Lorem ipsum dolor sit amet consectetur adipisicing elit. Praesentium at dolorum blanditiis minus. Quae facere consequuntur dolorum laborum ipsum nam natus, laboriosam, ab ipsam corrupti eaque sed aperiam quibusdam blanditiis neque nobis omnis saepe ducimus
        voluptas eius eum! Sunt assumenda explicabo fugit molestiae ut, odit quia blanditiis mollitia earum velit.
      </p>
    </li>
  </ul>
</div>


Solution

  • This is possible with CSS-Grid, using a six column grid and using combinations of nth-child and nth-last-child to manage the various grid column spans.

    Frankly it's probably too brittle and complex (there is probably a simple method) for production but I leave it here for reference.

    * {
      box-sizing: border-box;
    }
    
    .content {
      display: grid;
      grid-template-columns: repeat(6, 1fr);
      column-gap: 10px;
      row-gap: 10px;
      outline: 1px solid blue;
      margin-bottom: 10px;
      background: lightgreen;
    }
    
    .item {
      grid-column: span 2;
      height: 50px;
      background: lightblue;
      outline: 1px solid green;
      display: grid;
      place-items: center;
    }
    
    .item:only-child {
      grid-column: span 6;
    }
    
    .item:first-child:nth-last-child(2),
    .item:nth-child(2):last-child {
      grid-column: span 3;
    }
    
    .item:nth-child(3n + 4):last-child {
      grid-column: span 6;
    }
    
    .item:nth-child(3n + 4):nth-last-child(2),
    .item:nth-child(3n + 5):last-child {
      grid-column: span 3;
    }
    <div class="content">
      <div class="item">1 of 1</div>
    </div>
    
    <div class="content">
      <div class="item">1 of 2</div>
      <div class="item">2 of 2</div>
    </div>
    
    <div class="content">
      <div class="item">1 of 3</div>
      <div class="item">2 of 3</div>
      <div class="item">3 of 3</div>
    </div>
    
    <div class="content">
      <div class="item">1 of 4</div>
      <div class="item">2 of 4</div>
      <div class="item">3 of 4</div>
      <div class="item">4 of 4</div>
    </div>
    
    <div class="content">
      <div class="item">1 of 5</div>
      <div class="item">2 of 5</div>
      <div class="item">3 of 5</div>
      <div class="item">4 of 5</div>
      <div class="item">5 of 5</div>
    </div>
    
    <div class="content">
      <div class="item">1 of 7</div>
      <div class="item">2 of 7</div>
      <div class="item">3 of 7</div>
      <div class="item">4 of 7</div>
      <div class="item">5 of 7</div>
      <div class="item">6 of 7</div>
      <div class="item">7 of 7</div>
    </div>
    
    <div class="content">
      <div class="item">1 of 7</div>
      <div class="item">2 of 7</div>
      <div class="item">3 of 7</div>
      <div class="item">4 of 7</div>
      <div class="item">5 of 7</div>
      <div class="item">6 of 7</div>
      <div class="item">7 of 7</div>
      <div class="item">8 of 8</div>
    </div>