【问题标题】:A grid layout with responsive squares带有响应方块的网格布局
【发布时间】:2018-03-14 21:50:42
【问题描述】:

我想创建一个带有响应方块的网格布局。

我觉得我应该能够使用 CSS Grid 布局来做到这一点,但是在将每个正方形的高度设置为等于宽度时遇到了问题。

也无法在每个方格之间设置排水沟。

使用 flexbox 会更好吗?

目前我的 HTML 看起来像这样,但将是动态的,因此可以添加更多方块。当然,它需要响应式,因此理想情况下会使用媒体查询将其折叠到一列。

<div class="square-container">

  <div class="square">
    <div class="content">
    </div>
  </div>

  <div class="square">
    <div class="content spread">
    </div>
  </div>

  <div class="square">
    <div class="content column">
    </div>
  </div>

</div>

使用css网格,这是我所得到的

.square-container{
    display: grid;
    grid-template-columns: 30% 30% 30%;
    .square {

    }
}

我能够更进一步地使用 flexbox,并且能够使用 space-between 将正方形与漂亮的排水沟对齐,但仍在努力使高度与每个正方形的宽度相匹配。

我无法找到任何使用 flexbox 或网格完成此操作的示例,但任何示例也将不胜感激。

谢谢

【问题讨论】:

  • 我应该在内容 div 中添加一点,我希望使用 flexbox 对 img 和文本进行各种布局,因此我想避免在内容 div 中使用位置或填充
  • @kukkuz,您可能需要考虑在此处保留您的答案。它可能有一天会有效(当浏览器制造商达成共识时)。此外,它会阻止其他人发布相同的解决方案。

标签: css flexbox css-grid


【解决方案1】:

padding-bottom 技巧是最常用的方法。

您可以将它与 Flexbox 和 CSS Grid 结合使用,因为使用百分比作为边距/填充会导致 flex/grid 项目的结果不一致(在旧浏览器版本上,请参阅下面的编辑说明 ),可以添加一个额外的包装器,或者像这里一样,使用伪,所以带有百分比的元素不是 flex/grid 项。


编辑:注意,有一个update made to the specs.,现在在用于弹性/网格项目时应该会给出一致的结果。但请注意,旧版本仍会出现此问题。


注意,如果您要向content 元素添加内容,它需要绝对位置以保持正方形的纵横比。

Fiddle demo - Flexbox

编辑 2:在评论中有人问我如何使文本居中,所以我在下面的 sn-p 中添加了它。

.square-container {
  display: flex;
  flex-wrap: wrap;
}

.square {
  position: relative;
  flex-basis: calc(33.333% - 10px);
  margin: 5px;
  border: 1px solid;
  box-sizing: border-box;
}

.square::before {
  content: '';
  display: block;
  padding-top: 100%;
}

.square .content {
  position: absolute;
  top: 0; left: 0;
  height: 100%;
  width: 100%;

  display: flex;               /* added for centered text */
  justify-content: center;     /* added for centered text */
  align-items: center;         /* added for centered text */
}
<div class="square-container">

  <div class="square">
    <div class="content">
      <span>Some centered text</span>
    </div>
  </div>

  <div class="square">
    <div class="content spread">
    </div>
  </div>

  <div class="square">
    <div class="content column">
    </div>
  </div>

  <div class="square">
    <div class="content spread">
    </div>
  </div>

  <div class="square">
    <div class="content column">
    </div>
  </div>

</div>

CSS 网格版本

.square-container {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(30%, 1fr));
  grid-gap: 10px;
}

.square {
  position: relative;
  border: 1px solid;
  box-sizing: border-box;
}

.square::before {
  content: '';
  display: block;
  padding-top: 100%;
}

.square .content {
  position: absolute;
  top: 0; left: 0;
  height: 100%;
  width: 100%;
}
<div class="square-container">

  <div class="square">
    <div class="content">
    </div>
  </div>

  <div class="square">
    <div class="content spread">
    </div>
  </div>

  <div class="square">
    <div class="content column">
    </div>
  </div>

  <div class="square">
    <div class="content spread">
    </div>
  </div>

  <div class="square">
    <div class="content column">
    </div>
  </div>

</div>

【讨论】:

  • 这似乎在我迄今为止测试过的所有浏览器中都运行良好。谢谢
  • 这个解决方案在任何浏览器中都像魅力一样工作哇!猜猜我用 bootstrap 实现了什么并且像魅力一样工作!
  • LGSon,你能补充一点关于魔法是什么以及它是如何工作的解释吗?
  • @aaaidan 主要的魔法是 “填充”。为了使元素保持正方形,它的高度和宽度应该相同,以及为什么例如padding-top 的工作原理是,当使用百分比设置顶部(或底部)填充时,它使用自己的宽度来计算填充的值,这也将成为它的高度,因此它变成一个正方形。第二部分,当涉及到它的内容时,在这种情况下它需要是绝对定位的,所以它不会影响正方形的内容,否则填充计算也需要考虑到这一点(为此,a需要脚本)。
  • 如何垂直对齐弹性项目中的文本?
【解决方案2】:

几天来,我很惊讶,2020 年没有简单的解决方案。我确信使用 CSS 网格,这将是小菜一碟……Ason 提供的 Flexbox 解决方案是唯一可以跨浏览器工作的解决方案。在 Stack 上,我发现了另一种使用 padding-bottom: 100% 的 CSS 网格解决方案,但它在 Firefox 中不起作用(页脚下方有很多空白)。

这是我对这个问题的看法,我认为这是我这些天遇到的最简单的解决方案。

Codepen 上的 CSS Grid 解决方案: https://codepen.io/abudimir/pen/ExKqyGp

<div class="square-container">

【讨论】:

  • 您使用的是方形图像 - 所以这不适用于非方形缩放的图像;
【解决方案3】:

您可以使用 padding 是根据宽度计算的事实并将padding-top: 100% 直接设置为square 网格项 (网格项目现在是方形的)。


2019 年更新

请注意,对于 flex items 以及 grid items 之前这不起作用 - 请参阅 cmets 中链接到此答案的帖子:

现在浏览器(较新版本)之间已经达成共识,对于 flex 项grid 项padding 具有相同的行为,您可以使用此解决方案.

请看下面的演示:

.square-container {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(30%, 1fr));
  grid-gap: 10px;
}

.square {
  background: cadetblue;
  padding-top: 100%; /* padding trick directly on the grid item */
  box-sizing: border-box;
  position: relative;
}

.square .content { /* absolutely positioned */
  position: absolute;
  top: 0;
  right:0;
  left: 0;
  bottom: 0;
}
<div class="square-container">
  <div class="square">
    <div class="content"> some content here</div>
  </div>
  <div class="square">
    <div class="content"> some content here</div>
  </div>
  <div class="square">
    <div class="content"> some content here</div>
  </div>
  <div class="square">
    <div class="content"> some content here</div>
  </div>
  <div class="square">
    <div class="content column">some content here and there is a lot of text here</div>
  </div>
  <div class="square">
    <div class="content spread">text</div>
  </div>
  <div class="square">
    <div class="content column">some text here</div>
  </div>
</div>

【讨论】:

  • “作者应完全避免在网格项目的填充或边距中使用百分比,因为它们在不同的浏览器中会得到不同的行为。” stackoverflow.com/q/42708323/3597276
  • 在 Firefox 上试用。
  • flexbox 有同样的问题:stackoverflow.com/q/36783190/3597276
  • 由于解决方案现在有效,我已取消删除答案,谢谢大家:)
  • 这是一个完美的响应式方形网格,效果很好。
【解决方案4】:

尝试使用视口百分比单位

jsFiddle

.square-container {
  display: grid;
  grid-template-columns: repeat(3, 30vw);
  grid-template-rows: 30vw;
  grid-gap: 2.5vw;
  padding: 2.5vw;
  background-color: gray;
}

.square {
  background-color: lightgreen;
}

body {
  margin: 0; /* remove default margins */
}
<div class="square-container">
  <div class="square">
    <div class="content"></div>
  </div>
  <div class="square">
    <div class="content spread"></div>
  </div>
  <div class="square">
    <div class="content column"></div>
  </div>
</div>

来自规范:

5.1.2. Viewport-percentage lengths: the vw, vh, vmin, vmax units

视口百分比长度是相对于 初始包含块。当初始的高度或宽度 包含块被更改,它们会相应地缩放。

  • vw unit - 等于初始包含块宽度的 1%。
  • vh unit - 等于初始包含高度的 1% 阻止。
  • vmin 单位 - 等于vwvh 中的较小者。
  • vmax 单位 - 等于vwvh 中的较大者。

【讨论】:

  • 不幸的是 .square-container 嵌套在几个容器中,因此使用 vw 会导致方块溢出 .square-container 包装器之外
  • 发布完整的演示。这可能是一个可以克服的问题。
  • 我真的更喜欢这个答案,因为它不需要填充技巧。
  • 这个解决方案的浏览器支持怎么样?
  • 如果有一些垂直滚动条,该解决方案不再起作用,因为 100vw 等于主体宽度 + 滚动条宽度。这是与上面相同的示例,其中垂直滚动条会破坏显示:jsfiddle.net/0obt9cvs/3
猜你喜欢
  • 2018-07-28
  • 1970-01-01
  • 2015-08-05
  • 2012-10-01
  • 1970-01-01
  • 2013-12-25
  • 2023-01-09
  • 1970-01-01
相关资源
最近更新 更多