CSS 带有响应方块的网格布局

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/46548987/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 12:44:24  来源:igfitidea点击:

A grid layout with responsive squares

cssflexboxcss-grid

提问by Stretch0

I am wanting to create a grid layout with responsive squares.

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

I feel like I should be able to do this with CSS Grid layout but having trouble setting the height of each square to be equal to the width.

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

Also having trouble setting a gutter between each square.

在每个方块之间设置排水沟也有问题。

Would I be better off using flexbox?

使用 flexbox 会更好吗?

Currently my HTML looks like this but will be dynamic so more squares may be added. And of course it needs to be responsive so will ideally use a media query to collapse it to one column.

目前我的 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>

Using css grid, this is as far as I got

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

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

    }
}

I was able to get a bit further with flexbox and able to use space-between to align squares with a nice gutter but was still struggling to get the height to match the width of each square.

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

I wasn't able to find any examples of this being done with either flexbox or grid but any examples would be appreciated as well.

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

Thanks

谢谢

采纳答案by Ason

The padding-bottomtrick is the most used to accomplish that.

padding-bottom技巧是用来实现这一目标最。

You can combine it with both Flexbox and CSS Grid, and since using percent for margin/padding gives inconsistent result for flex/grid items, one can add an extra wrapper, or like here, using a pseudo, so the element with percent is not the flex/grid item.

您可以将它与 Flexbox 和 CSS Grid 结合使用,并且由于使用百分比作为边距/填充会为 flex/grid 项目提供不一致的结果,因此可以添加额外的包装器,或者像这里一样使用伪代码,因此带有百分比的元素不是弹性/网格项目。



Edit:Note, there's an update made to the specs., that now should give consistent result when used on flex/grid items. Be aware though, the issue still occurs on older versions.

编辑:请注意,对规格进行更新。,现在在 flex/grid 项目上使用时应该给出一致的结果。但请注意,该问题仍会出现在旧版本上。



Note, if you will add content to the contentelement, it need to be position absolute to keep the square's aspect ratio.

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

Fiddle demo - Flexbox

Fiddle 演示 - Flexbox

.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%;
}
<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>



CSS Grid version

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>

回答by Michael Benjamin

Try using viewport percentage units.

尝试使用视口百分比单位

jsFiddle

js小提琴

.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>

From the spec:

从规范:

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

The viewport-percentage lengths are relative to the size of the initial containing block. When the height or width of the initial containing block is changed, they are scaled accordingly.

  • vw unit- Equal to 1% of the width of the initial containing block.
  • vh unit- Equal to 1% of the height of the initial containing block.
  • vmin unit- Equal to the smaller of vwor vh.
  • vmax unit- Equal to the larger of vwor vh.

5.1.2. 视口百分比长度:vw, vh, vmin,vmax单位

视口百分比长度与初始包含块的大小有关。当初始包含块的高度或宽度发生变化时,它们会相应地缩放。

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

回答by kukkuz

You can use the fact that paddingis calculated based on the width and set padding-top: 100%directlyto the squaregrid items(the grid items would be square now).

您可以使用基于宽度计算填充padding-top: 100%直接设置为square网格项目(网格项目现在是方形的)这一事实。



2019 update

2019年更新

Note that for flex itemsas well as grid itemsearlier this doesn't used to work - see the post linked in the comments to this answer:

请注意,对于flex 项以及之前的网格项,这并不适用 - 请参阅此答案的评论中链接的帖子:

Now that there is a consensus between browsers (newer versions) to have the same behaviour for paddingfor flex itemsand grid items, you can use this solution.

现在浏览器(较新版本)之间已达成共识,paddingflex itemsgrid items具有相同的行为,您可以使用此解决方案。

See demo below:

请参阅下面的演示:

.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>