CSS only solution to set MULTIPLE “same height” row sections on a responsive grid

左心房为你撑大大i 提交于 2019-11-26 23:03:48

Based on your own answer, where you grouped them by 4, you can do that with CSS Flexbox too.

To make them behave when there is less than 4, it might be possible to accomplish that using the nth-child selector, but it was simpler to use a last* class, so I went for the latter.

One might even be able to do this without the .group_of_4 wrapper, with some clever nth-child rules, but again, went for the simpler since it does not come with any obvious limitations

Fiddle demo

.items {
  display: flex;
  flex-direction: column;
  max-width: 1200px;
}

.items .group_of_4 {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;        /*  updated  */
}

.items .group_of_4 ~ .group_of_4 {
  margin-top: 24px;
}

.items .group_of_4 > div {
  width: calc(25% - 12px);                /*  updated  */
  box-sizing: border-box;
  padding: 12px;
}


.item__heading {
  background-color: #d4d0f5;
  padding: 10px;
  text-align: center;
  border: 1px solid #bbbbbb;
  order: 1;
}

.item__content {
  padding: 10px;
  border-left: 1px solid #bbbbbb;
  border-right: 1px solid #bbbbbb;
  order: 2;
}

.item__features {
  padding: 10px;
  border-left: 1px solid #bbbbbb;
  border-right: 1px solid #bbbbbb;
  background-color: #f7cbb1;
  order: 3;
}

.item__price {
  background-color: #e0f6d9;
  padding: 10px;
  text-align: center;
  border: 1px solid #bbbbbb;
  order: 4;
}

/* one item in a group */
.items .group_of_4 .last1 {
    margin-right: calc(75%  6px);        /*  updated  */
}
/* two items in a group */
.items .group_of_4 .last2 {
    margin-right: calc(50% + 6px);       /*  updated  */
}
/* three items in a group */
.items .group_of_4 .last3 {
    margin-right: calc(25% + 6px);       /*  updated  */
}

@media (max-width: 600px) {
  .items .group_of_4 > div:nth-child(8) ~ .item__heading {
    margin-top: 24px;
    order: 5;
  }
  .items .group_of_4 > div:nth-child(8) ~ .item__content {
    order: 6;
  }
  .items .group_of_4 > div:nth-child(8) ~ .item__features {
    order: 7;
  }
  .items .group_of_4 > div:nth-child(8) ~ .item__price {
    order: 8;
  }
  
  .items .group_of_4 > div {
    width: calc(50% - 12px);             /*  updated  */
  }

  /* one item in a group */
  /* three items in a group */
  .items .group_of_4 .last1,
  .items .group_of_4 .last3 {
    margin-right: 50%;
  }
  /* two items in a group */
  .items .group_of_4 .last2 {
    margin-right: 0%;
  }  
}
<div class="items">

  <div class="group_of_4">
    <div class="item__heading">
      Item 1
    </div>
    <div class="item__content">
      Some content that is not that long
    </div>
    <div class="item__features">
      <ul>
        <li>feature 1</li>
      </ul>
    </div>
    <div class="item__price">
      £99.99
    </div>

    <div class="item__heading">
      Item 2
    </div>
    <div class="item__content">
      Some content that is longer than other items on the same row and sets the height of this section as it spans many more lines than the rest of the other content sections on this row
    </div>
    <div class="item__features">
      <ul>
        <li>feature 1</li>
      </ul>
    </div>
    <div class="item__price">
      £69.99
    </div>

    <div class="item__heading">
      Item 3
    </div>
    <div class="item__content">
      Some content that is not that long
    </div>
    <div class="item__features">
      <ul>
        <li>feature 1</li>
        <li>feature 2</li>
        <li>feature 3</li>
      </ul>
    </div>
    <div class="item__price">
      £69.99
    </div>

    <div class="item__heading">
      Item 4
    </div>
    <div class="item__content">
      Some content that is not that long
    </div>
    <div class="item__features">
      <ul>
        <li>feature 1</li>
      </ul>
    </div>
    <div class="item__price">
      £109.99
    </div>
  </div>
  
  
  <div class="group_of_4">
    <div class="item__heading">
      Item 5
    </div>
    <div class="item__content">
      Some content that is a medium kind of length blah blah
    </div>
    <div class="item__features">
      <ul>
        <li>feature 1</li>
      </ul>
    </div>
    <div class="item__price">
      £29.99
    </div>

    <div class="item__heading last2">
      Item 6
    </div>
    <div class="item__content last2">
      Some content that is not that long
    </div>
    <div class="item__features last2">
      <ul>
        <li>feature 1</li>
      </ul>
    </div>
    <div class="item__price last2">
      £99.99
    </div> 

  </div>
</div>

I am providing an answer to my own question - but will hold off accepting it in case anyone else comes up with something better as this answer will no doubt break some accessibility rules and is bordering on the impossible to provide a graceful fallback for browsers that do not support CSS Grid but...

If you split the HTML content items up in to blocks of four you can achieve the desired outcome with the CSS Grid style rules, no JavaScript required

.items {
  max-width: 1200px;
}

.item__heading {
  margin-top: 30px;
  background-color: #d4d0f5;
  padding: 10px;
  text-align: center;
  border: 1px solid #bbbbbb;
}

.item__content {
  padding: 10px;
  border-left: 1px solid #bbbbbb;
  border-right: 1px solid #bbbbbb;
}

.item__features {
  padding: 10px;
  border-top: 1px solid #bbbbbb;
  border-left: 1px solid #bbbbbb;
  border-right: 1px solid #bbbbbb;
  background-color: #f7cbb1;
}

.item__price {
  background-color: #e0f6d9;
  padding: 10px;
  text-align: center;
  border: 1px solid #bbbbbb;
}

/* DESKTOP GRID */

/* DESKTOP COLUMN LAYOUT - 4 columns, one row */
.item-block-of-four {
  display: grid;
  grid-template-columns: 2% 22.5% 2% 22.5% 2% 22.5% 2% 22.5% 2%;
}
.item-1 {
  grid-column-start: 2;
  grid-column-end: 3;
}
.item-2 {
  grid-column-start: 4;
  grid-column-end: 5;
}
.item-3 {
  grid-column-start: 6;
  grid-column-end: 7;
}
.item-4 {
  grid-column-start: 8;
  grid-column-end: 9;
}

/* ROW LAYOUT - one row for all 4 items */
.item__heading {
  grid-row-start: 1;
  grid-row-end: 2;
}
.item__content {
  grid-row-start: 2;
  grid-row-end: 3;
}
.item__features {
  grid-row-start: 3;
  grid-row-end: 4;
}
.item__price {
  grid-row-start: 4;
  grid-row-end: 5;
}

/* MOBILE GRID */

@media (max-width: 600px) {
  /* MOBILE COLUMN LAYOUT - 2 columns 2 rows */
  .item-block-of-four {
    display: grid;
    grid-template-columns: 6% 41% 6% 41% 6%;
  }
  .item-1, .item-3 {
    grid-column-start: 2;
    grid-column-end: 3;
  }
  .item-2, .item-4 {
    grid-column-start: 4;
    grid-column-end: 5;
  }

  /* MOBILE ROW LAYOUT - two sets of rows */

  /* first row set */
  .item-1.item__heading, .item-2.item__heading {
    grid-row-start: 1;
    grid-row-end: 2;
  }

  .item-1.item__content, .item-2.item__content {
    grid-row-start: 2;
    grid-row-end: 3;
  }

  .item-1.item__features, .item-2.item__features {
    grid-row-start: 3;
    grid-row-end: 4;
  }

  .item-1.item__price, .item-2.item__price {
    grid-row-start: 4;
    grid-row-end: 5;
  }

  /* second row set */
  .item-3.item__heading, .item-4.item__heading {
    grid-row-start: 6;
    grid-row-end: 7;
  }

  .item-3.item__content, .item-4.item__content {
    grid-row-start: 7;
    grid-row-end: 8;
  }

  .item-3.item__features, .item-4.item__features {
    grid-row-start: 8;
    grid-row-end: 9;
  }

  .item-3.item__price, .item-4.item__price {
    grid-row-start: 9;
    grid-row-end: 10;
  }
}
<div class="items">

  <div class="item-block-of-four">

    <div class="item-1 item__heading">
      Item 1
    </div>
    <div class="item-2 item__heading">
      Item 2
    </div>
    <div class="item-3 item__heading">
      Item 3
    </div>
    <div class="item-4 item__heading">
      Item 4
    </div>

    <div class="item-1 item__content">
      Some content that is not that long
    </div>
    <div class="item-2 item__content">
      Some content that is longer than other items on the same row and sets the height of this section as it spans many more lines than the rest of the other content sections on this row
    </div>
    <div class="item-3 item__content">
      Some content that is not that long
    </div>
    <div class="item-4 item__content">
      Some content that is not that long
    </div>

    <div class="item-1 item__features">
      <ul>
        <li>feature 1</li>
      </ul>
    </div>
    <div class="item-2 item__features">
      <ul>
        <li>feature 1</li>
      </ul>
    </div>
    <div class="item-3 item__features">
      <ul>
        <li>feature 1</li>
        <li>feature 2</li>
        <li>feature 3</li>
      </ul>
    </div>
    <div class="item-4 item__features">
      <ul>
        <li>feature 1</li>
      </ul>
    </div>

    <div class="item-1 item__price">
      £99.99
    </div>
    <div class="item-2 item__price">
      £69.99
    </div>
    <div class="item-3 item__price">
      £69.99
    </div>
    <div class="item-4 item__price">
      £109.99
    </div>

  </div><!-- /item-block-of-four -->

  <div class="item-block-of-four">

    <div class="item-1 item__heading">
      Item 5
    </div>
    <div class="item-2 item__heading">
      Item 6
    </div>

    <div class="item-1 item__content">
      Some content that is a medium kind of length blah blah
    </div>
    <div class="item-2 item__content">
      Some content that is not that long
    </div>

    <div class="item-1 item__features">
      <ul>
        <li>feature 1</li>
      </ul>
    </div>
    <div class="item-2 item__features">
      <ul>
        <li>feature 1</li>
        <li>feature 2</li>
      </ul>
    </div>

    <div class="item-1 item__price">
      £29.99
    </div>
    <div class="item-2 item__price">
      £99.99
    </div>

  </div><!-- /item-block-of-four -->

</div><!-- /items-container -->
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!