带有 flexbox 的 css 正方形网格
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29307971/
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
css grid of squares with flexbox
提问by Moto
I am trying to create a responsive grid of squares. The squares should resize to fit the viewport's width. The squares should not resize when changing the viewport's height.
我正在尝试创建一个响应式的正方形网格。方块应该调整大小以适应视口的宽度。更改视口的高度时,方块不应调整大小。
I got how to adjust the width of each square, but I don't know how to make the elements square and how to scale their height when the viewport width changes.
我知道如何调整每个正方形的宽度,但我不知道如何使元素变成正方形以及如何在视口宽度发生变化时缩放它们的高度。
In the example at the fiddle below the seven squares should always fit horizontally, and they should scale as squares. I do not care how many rows are visible.
在小提琴下方的示例中,七个正方形应始终水平放置,并且它们应按正方形缩放。我不在乎有多少行可见。
Fiddle here http://jsfiddle.net/gonyhvz8/11/
在这里小提琴http://jsfiddle.net/gonyhvz8/11/
<body>
<div class="flex-container">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
<div class="flex-item">4</div>
<div class="flex-item">5</div>
<div class="flex-item">6</div>
<div class="flex-item">7</div>
</div>
<div class="flex-container">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
<div class="flex-item">4</div>
<div class="flex-item">5</div>
<div class="flex-item">6</div>
<div class="flex-item">7</div>
</div>
<div class="flex-container">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
<div class="flex-item">4</div>
<div class="flex-item">5</div>
<div class="flex-item">6</div>
<div class="flex-item">7</div>
</div>
<div class="flex-container">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
<div class="flex-item">4</div>
<div class="flex-item">5</div>
<div class="flex-item">6</div>
<div class="flex-item">7</div>
</div>
<div class="flex-container">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
<div class="flex-item">4</div>
<div class="flex-item">5</div>
<div class="flex-item">6</div>
<div class="flex-item">7</div>
</div>
<div class="flex-container">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
<div class="flex-item">4</div>
<div class="flex-item">5</div>
<div class="flex-item">6</div>
<div class="flex-item">7</div>
</div>
<div class="flex-container">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
<div class="flex-item">4</div>
<div class="flex-item">5</div>
<div class="flex-item">6</div>
<div class="flex-item">7</div>
</div>
.flex-container {
padding: 0;
margin: 0;
list-style: none;
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-webkit-flex-flow: row;
justify-content: space-around;
height: 50px;
line-height:30px;
}
.flex-item {
background: tomato;
margin: 5px;
color: white;
font-weight: bold;
font-size: 1.5em;
text-align: center;
flex: 1 0 0px;
height: auto;
}
回答by G-Cyrillus
you should not set any size. you may use an extra element or a pseudo elemnt with vertical padding in %. this will allow you to use width as reference : a snippet to show:
你不应该设置任何大小。您可以使用额外的元素或带有 % 垂直填充的伪元素。这将允许您使用宽度作为参考:一个片段来显示:
.flex-container {
padding: 0;
margin: 0;
list-style: none;
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-webkit-flex-flow: row;
justify-content: space-around;
line-height:30px;
}
.flex-item {
background: tomato;
margin: 5px;
color: white;
font-weight: bold;
font-size: 1.5em;
text-align: center;
flex: 1 0 auto;
height:auto;
}
.flex-item:before {
content:'';
float:left;
padding-top:100%;
}
<body>
<div class="flex-container">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
<div class="flex-item">4</div>
<div class="flex-item">5</div>
<div class="flex-item">6</div>
<div class="flex-item">7</div>
</div>
<div class="flex-container">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
<div class="flex-item">4</div>
<div class="flex-item">5</div>
<div class="flex-item">6</div>
<div class="flex-item">7</div>
</div>
<div class="flex-container">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
<div class="flex-item">4</div>
<div class="flex-item">5</div>
<div class="flex-item">6</div>
<div class="flex-item">7</div>
</div>
<div class="flex-container">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
<div class="flex-item">4</div>
<div class="flex-item">5</div>
<div class="flex-item">6</div>
<div class="flex-item">7</div>
</div>
<div class="flex-container">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
<div class="flex-item">4</div>
<div class="flex-item">5</div>
<div class="flex-item">6</div>
<div class="flex-item">7</div>
</div>
<div class="flex-container">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
<div class="flex-item">4</div>
<div class="flex-item">5</div>
<div class="flex-item">6</div>
<div class="flex-item">7</div>
</div>
<div class="flex-container">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
<div class="flex-item">4</div>
<div class="flex-item">5</div>
<div class="flex-item">6</div>
<div class="flex-item">7</div>
</div>
</body>
an inline-blockelement could do too, just adapt the display/behavior of the box and it's content. the magic here comes from padding:50% 0; (100% vertical padding equals width of parent). see w3c about vertical marginand padding
一个inline-block的元素可以做太多,只是适应框的显示/行为和它的内容。这里的魔法来自 padding:50% 0; (100% 垂直填充等于父级的宽度)。请参阅 w3c 关于垂直边距和填充
回答by CGodo
For those that also want to use display: flex
inside the square divs, you need to use display: table
for the :before
element, otherwise the square will work with Chrome but won't work with Firefox or Edge (as of Firefox 47 and Edge 13).
对于那些还想display: flex
在方形 div 内使用的人,您需要使用display: table
for:before
元素,否则方形将适用于 Chrome,但不适用于 Firefox 或 Edge(从 Firefox 47 和 Edge 13 开始)。
In the snippet bellow, which should work for all browsers, I also demonstrate how to wrap unlimited items with percentage columns (in this case 20%) and separate them with padding and inner divs, since margins with percentages do not work correctly in FF and of course Edge.
在下面的代码段中,它应该适用于所有浏览器,我还演示了如何用百分比列(在本例中为 20%)包装无限项目,并用填充和内部 div 将它们分开,因为带有百分比的边距在 FF 和当然是边缘。
.flex-container {
display: flex;
justify-content: start;
flex-wrap: wrap;
}
.flex-cell {
flex: 0 0 20%;
display: flex;
justify-content: center;
align-items: stretch;
padding: 0.5rem;
box-sizing: border-box;
}
.flex-cell:before {
content: '';
display: table;
padding-top: 100%;
}
.flex-item {
flex-grow: 1;
border: 1px solid black;
background: tomato;
color: white;
display: flex;
justify-content: center;
align-items: center;
}
<body>
<div class="flex-container">
<div class="flex-cell">
<div class="flex-item">1</div>
</div>
<div class="flex-cell">
<div class="flex-item">2</div>
</div>
<div class="flex-cell">
<div class="flex-item">3</div>
</div>
<div class="flex-cell">
<div class="flex-item">4</div>
</div>
<div class="flex-cell">
<div class="flex-item">5</div>
</div>
<div class="flex-cell">
<div class="flex-item">6</div>
</div>
<div class="flex-cell">
<div class="flex-item">7</div>
</div>
<div class="flex-cell">
<div class="flex-item">8</div>
</div>
<div class="flex-cell">
<div class="flex-item">9</div>
</div>
<div class="flex-cell">
<div class="flex-item">10</div>
</div>
<div class="flex-cell">
<div class="flex-item">11</div>
</div>
<div class="flex-cell">
<div class="flex-item">12</div>
</div>
</div>
</body>
回答by James Montagne
The usual trick for maintaining aspect ratio is to use the fact that percentage values of margin and/or padding top & bottom are calculated based on the width of the containing element, and not the height.
保持纵横比的常用技巧是利用这样一个事实,即根据包含元素的宽度而不是高度计算边距和/或填充顶部和底部的百分比值。
You can see a non-flex version of this question HERE
你可以看到这个问题的非柔性版HERE
However, you would like to have flex
deal with the width of your elements, not set percentage based widths. For that, I have come up with a variation of that approach that will work with flex:
但是,您希望flex
处理元素的宽度,而不是设置基于百分比的宽度。为此,我想出了一种适用于 flex 的方法的变体:
.flex-item:before {
content: "";
display: block;
padding-top: 100%;
float: left;
}
The trick here is to use the :before
pseudo-element to insert a 0 width element with a padding-top
of 100%. That 100% is 100% of the width, meaning this element with no content will be equally as tall as its container. This will stretch the flex-item to the same height as its width:
这里的技巧是使用:before
伪元素插入一个宽度为 0、apadding-top
为 100% 的元素。100% 是宽度的 100%,这意味着这个没有内容的元素将与其容器一样高。这会将 flex-item 拉伸到与其宽度相同的高度:
Additionally, you will need to remove the defined height from your flex-container or the height can't grow. You also may want to add min-width: 1.5em
so that your elements don't shrink below the height of the character you have in each square.
此外,您需要从 flex-container 中删除定义的高度,否则高度无法增长。您可能还想添加,min-width: 1.5em
以便您的元素不会缩小到您在每个方块中所拥有的角色的高度以下。
http://jsfiddle.net/gonyhvz8/14/
http://jsfiddle.net/gonyhvz8/14/
.flex-container {
padding: 0;
margin: 0;
list-style: none;
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-webkit-flex-flow: row;
justify-content: space-around;
line-height:30px;
}
.flex-item {
background: tomato;
margin: 5px;
color: white;
font-weight: bold;
font-size: 1.5em;
text-align: center;
flex: 1 0 0px;
min-width: 1.5em;
}
.flex-item:before {
content: "";
display: block;
padding-top: 100%;
float: left;
}
<body>
<div class="flex-container">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
<div class="flex-item">4</div>
<div class="flex-item">5</div>
<div class="flex-item">6</div>
<div class="flex-item">7</div>
</div>
<div class="flex-container">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
<div class="flex-item">4</div>
<div class="flex-item">5</div>
<div class="flex-item">6</div>
<div class="flex-item">7</div>
</div>
<div class="flex-container">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
<div class="flex-item">4</div>
<div class="flex-item">5</div>
<div class="flex-item">6</div>
<div class="flex-item">7</div>
</div>
<div class="flex-container">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
<div class="flex-item">4</div>
<div class="flex-item">5</div>
<div class="flex-item">6</div>
<div class="flex-item">7</div>
</div>
<div class="flex-container">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
<div class="flex-item">4</div>
<div class="flex-item">5</div>
<div class="flex-item">6</div>
<div class="flex-item">7</div>
</div>
<div class="flex-container">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
<div class="flex-item">4</div>
<div class="flex-item">5</div>
<div class="flex-item">6</div>
<div class="flex-item">7</div>
</div>
<div class="flex-container">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
<div class="flex-item">4</div>
<div class="flex-item">5</div>
<div class="flex-item">6</div>
<div class="flex-item">7</div>
</div>
</body>
回答by Octavioamu
There is a way to made it with no extra html elements also. I created a fiddle with your codebase http://jsfiddle.net/octavioamu/kq97pm3L/but the tick is to use after elemento with display table
还有一种方法可以在没有额外的 html 元素的情况下制作它。我用你的代码库http://jsfiddle.net/octavioamu/kq97pm3L/创建了一个小提琴,但勾号是在 elemento 和显示表之后使用
flex-item:after {
content: ' ';
padding-top: 100%;
display: table;
}
You can use it in any grid, for example an square inside a column grid with bootstrap... Here is a sass mixin working inside a % grid column https://codepen.io/octavioamu/pen/xzeXGm
您可以在任何网格中使用它,例如带有引导程序的列网格内的正方形......这是一个在 % 网格列内工作的 sass mixin https://codepen.io/octavioamu/pen/xzeXGm
And here is with your code:
这是您的代码:
.flex-container {
display: flex;
}
.flex-item {
display: flex;
width: 100%;
justify-content: center;
align-items: center;
background-color: red;
margin: 5px
}
.flex-item:after {
content: ' ';
padding-top: 100%;
display: table;
}
<body>
<div class="flex-container">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
<div class="flex-item">4</div>
<div class="flex-item">5</div>
<div class="flex-item">6</div>
<div class="flex-item">7</div>
</div>
<div class="flex-container">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
<div class="flex-item">4</div>
<div class="flex-item">5</div>
<div class="flex-item">6</div>
<div class="flex-item">7</div>
</div>
<div class="flex-container">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
<div class="flex-item">4</div>
<div class="flex-item">5</div>
<div class="flex-item">6</div>
<div class="flex-item">7</div>
</div>
<div class="flex-container">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
<div class="flex-item">4</div>
<div class="flex-item">5</div>
<div class="flex-item">6</div>
<div class="flex-item">7</div>
</div>
<div class="flex-container">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
<div class="flex-item">4</div>
<div class="flex-item">5</div>
<div class="flex-item">6</div>
<div class="flex-item">7</div>
</div>
<div class="flex-container">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
<div class="flex-item">4</div>
<div class="flex-item">5</div>
<div class="flex-item">6</div>
<div class="flex-item">7</div>
</div>
<div class="flex-container">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
<div class="flex-item">4</div>
<div class="flex-item">5</div>
<div class="flex-item">6</div>
<div class="flex-item">7</div>
</div>
</body>
回答by Michael Czechowski
Surely it is nice to use flexboxes, but the solution mentioned has a lack of flexability even it uses flexboxes
. You are not able to adjust a floating of boxes. You are bounded to set the number of boxes per row before.
使用 flexboxes 当然很好,但是提到的解决方案缺乏灵活性,即使它使用flexboxes
. 您无法调整浮动框。您必须在之前设置每行的框数。
In this solution you can adapt a dynamic width of tiles/square and float them how you like. If you try this with flexboxes, you will get a problem with padding-top
because it does not orientate on the given width of the containing blocks.
在此解决方案中,您可以调整瓷砖/正方形的动态宽度并按照您的喜好浮动它们。如果你用 flexboxes 尝试这个,你会得到一个问题,padding-top
因为它没有定位在包含块的给定宽度上。
Solution without
flexboxes
but more flexability:
没有
flexboxes
但更具灵活性的解决方案:
.flex-container {
padding: 0;
margin: -5px;
font-size: 0;
font-family: Helvetica, Arial, sans-serif;
}
.flex-item {
position: relative;
display: inline-block;
height: 0;
width: 100%;
padding-top: 100%;
height: auto;
font-size: 20px;
color: white;
font-weight: bold;
text-align: center;
}
@media (min-width: 480px) {
.flex-item {
width: 33.3333%;
padding-top: 33.3333%;
}
}
@media (min-width: 768px) {
.flex-item {
width: 25%;
padding-top: 25%;
}
}
.flex-item-inner {
position: absolute;
display: flex;
justify-content: center;
align-items: center;
top: 0;
bottom: 0;
right: 0;
left: 0;
margin: 10px;
background: tomato;
}
<body>
<div class="flex-container">
<div class="flex-item">
<div class="flex-item-inner">
<div class="flex-item-inner-content">
1
</div>
</div>
</div>
<div class="flex-item">
<div class="flex-item-inner">
<div class="flex-item-inner-content">
2
</div>
</div>
</div>
<div class="flex-item">
<div class="flex-item-inner">
<div class="flex-item-inner-content">
3
</div>
</div>
</div>
<div class="flex-item">
<div class="flex-item-inner">
<div class="flex-item-inner-content">
4
</div>
</div>
</div>
<div class="flex-item">
<div class="flex-item-inner">
<div class="flex-item-inner-content">
5
</div>
</div>
</div>
<div class="flex-item">
<div class="flex-item-inner">
<div class="flex-item-inner-content">
6
</div>
</div>
</div>
</div>
</body>
Link to the codepen: http://codepen.io/dailysh-it/pen/xOVydO
代码笔链接:http://codepen.io/dailysh-it/pen/xOVydO
回答by Shaun Luttin
Simplified Version of G-Cyr's Answer
G-Cyr 答案的简化版
.flex-container {
display: flex;
flex-flow: row;
justify-content: center;
}
.flex-item {
background: tomato;
margin: 10px;
max-width: 50px;
flex-grow: 1;
flex-shrink: 0;
flex-basis: 0;
height: auto;
}
.flex-item:before {
/* The psuedo-element's padding-top percentage is based on the element's width. */
padding-top: 100%;
content: '';
float: left;
}
<div class="flex-container">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
</div>
<div class="flex-container">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
<div class="flex-item">4</div>
</div>
<div class="flex-container">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
<div class="flex-item">4</div>
<div class="flex-item">5</div>
</div>
<div class="flex-container">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
<div class="flex-item">4</div>
<div class="flex-item">5</div>
<div class="flex-item">6</div>
</div>