仅限CSS的解决方案,用于在响应式网格上设置“相同高度”的行部分

时间:2017-05-22 14:28:32

标签: html css css3 flexbox css-grid

通缉:一种仅限CSS的解决方案,可以在每行的基础上启用相等高度的网格“部分”,这也是响应式的。

这个图表希望能比这篇文章中的文字更好地解释这个要求:

helpful diagram

“项目网格”应该是响应式的 - 因为它可以根据视口宽度显示每行不同数量的卡片。在给定的行中,等效的部分应该在“每行”的基础上具有相同的高度。

在下面的HTML& CSS - 项目卡分为我们需要的行(在桌面和移动设备的两个示例断点处)但内容部分高度是可变的(yuck):

.items {
  max-width: 1200px;
}

.item {
  width: 25%;
  box-sizing: border-box;
  display: inline-block;
  vertical-align: top;
  padding: 0 12px;
  margin: 24px -4px 24px 0;
}

@media (max-width: 600px) {
  .item {
    width: 50%;
  }
}

.item__heading {
  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__price {
  background-color: #e0f6d9;
  padding: 10px;
  text-align: center;
  border: 1px solid #bbbbbb;
}
<div class="items">

  <div class="item">
    <div class="item__heading">
      Item 1
    </div>
    <div class="item__content">
      Some content that is not that long
    </div>
    <div class="item__price">
      £99.99
    </div>
  </div>


  <div class="item">
    <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
    </div>
    <div class="item__price">
      £69.99
    </div>
  </div>

  <div class="item">
    <div class="item__heading">
      Item 3
    </div>
    <div class="item__content">
      Some content that is not that long
    </div>
    <div class="item__price">
      £69.99
    </div>
  </div>

  <div class="item">
    <div class="item__heading">
      Item 4
    </div>
    <div class="item__content">
      Some content that is not that long
    </div>
    <div class="item__price">
      £109.99
    </div>
  </div>

  <div class="item">
    <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__price">
      £29.99
    </div>
  </div>

  <div class="item">
    <div class="item__heading">
      Item 6
    </div>
    <div class="item__content">
      Some content that is not that long
    </div>
    <div class="item__price">
      £99.99
    </div>
  </div>

    
</div>

以下codepen是基于JavaScript的解决方案,可实现预期的结果 -  但我正在努力避免: https://codepen.io/rusta/pen/KmbVKd

限制

  • 要在网格列表中显示的项目数可以是1-150
  • 中的任意数字
  • 要显示的项目内容的大小将是真正可变的(因此选择“明智的”最小高度不是一个选项)

我希望新的CSS Grid系统可以帮助我实现上述目标,但是玩了一段时间它似乎需要比我希望的更多的结构,并且响应方面看起来相当具有挑战性。但也许在某处有一个基于CSS Grid的答案

进一步说明:我说的是一个仅限CSS的解决方案,我的意思是非JS解决方案。如果HTML块需要更改(命令/嵌套/类名)以支持非JS的非JS解决方案

在这个简单的例子中 - 我们只关注具有“匹配高度”的“内容”部分 - 因为我们可以假设标题和价格部分自然会是相同的高度。在任何匹配的网格部分(标题/内容/价格/其他)中启用“等效”会很好,但这可能是另一天......

1 个答案:

答案 0 :(得分:2)

通过提供.items display: flex; flex-wrap: wrap;,您的item将变为弹性项目并从左向右流动,并在没有更多空间时进行换行。

然后你给.item display: flex; flex-direction: column;,这也将使它们成为一个灵活容器,并且通过使用列方向,它的子元素将像块元素一样垂直流动。

最后,您提供.item__content flex: 1;,这将使其在垂直方向上占用任何剩余空间,因此每行的item将具有相同的高度。

Updated codepen

Stack snippet

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

.item {
  display: flex;
  flex-direction: column;
  width: 25%;
  box-sizing: border-box;
  vertical-align: top;
  padding: 0 12px;
  margin: 24px -4px 24px 0;
}

@media (max-width: 600px) {
  .item {
    width: 50%;
  }
}

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

.item__content {
  flex: 1 1 auto;                   /* IE need 1 1 auto */
  padding: 10px;
  border-left: 1px solid #bbbbbb;
  border-right: 1px solid #bbbbbb;
}

.item__price {
  background-color: #e0f6d9;
  padding: 10px;
  text-align: center;
  border: 1px solid #bbbbbb;
}
<div class="items">

  <div class="item">
    <div class="item__heading">
      Item 1
    </div>
    <div class="item__content">
      Some content that is not that long
    </div>
    <div class="item__price">
      £99.99
    </div>
  </div>

  <div class="item">
    <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
    </div>
    <div class="item__price">
      £69.99
    </div>
  </div>

  <div class="item">
    <div class="item__heading">
      Item 3
    </div>
    <div class="item__content">
      Some content that is not that long
    </div>
    <div class="item__price">
      £69.99
    </div>
  </div>

  <div class="item">
    <div class="item__heading">
      Item 4
    </div>
    <div class="item__content">
      Some content that is not that long
    </div>
    <div class="item__price">
      £109.99
    </div>
  </div>

  <div class="item">
    <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__price">
      £29.99
    </div>
  </div>

  <div class="item">
    <div class="item__heading">
      Item 6
    </div>
    <div class="item__content">
      Some content that is not that long
    </div>
    <div class="item__price">
      £99.99
    </div>
  </div>

</div>