Html Flexbox:每行 4 个项目
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29546550/
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
Flexbox: 4 items per row
提问by Vivek Maharajh
I'm using a flex box to display 8 items that will dynamically resize with my page. How do I force it to split the items into two rows? (4 per row)?
我正在使用弹性框来显示 8 个项目,这些项目将随着我的页面动态调整大小。如何强制它将项目分成两行?(每行 4 个)?
Here is a relevant snip:
这是一个相关的剪辑:
(Or if you prefer jsfiddle - http://jsfiddle.net/vivmaha/oq6prk1p/2/)
(或者,如果您更喜欢 jsfiddle - http://jsfiddle.net/vivmaha/oq6prk1p/2/)
.parent-wrapper {
height: 100%;
width: 100%;
border: 1px solid black;
}
.parent {
display: flex;
font-size: 0;
flex-wrap: wrap;
margin: -10px 0 0 -10px;
}
.child {
display: inline-block;
background: blue;
margin: 10px 0 0 10px;
flex-grow: 1;
height: 100px;
}
<body>
<div class="parent-wrapper">
<div class="parent">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
</div>
</body>
回答by Michael Benjamin
You've got flex-wrap: wrap
on the container. That's good, because it overrides the default value, which is nowrap
(source). This is the reason items don't wrap to form a grid in some cases.
你已经flex-wrap: wrap
到了容器上。这很好,因为它覆盖了默认值,即nowrap
( source)。这就是在某些情况下项目不会包裹以形成网格的原因。
In this case, the main problem is flex-grow: 1
on the flex items.
在这种情况下,主要问题出flex-grow: 1
在弹性项目上。
The flex-grow
property doesn't actually size flex items. Its task is to distribute free space in the container (source). So no matter how small the screen size, each item will receive a proportional part of the free space on the line.
该flex-grow
属性实际上并不调整弹性项目的大小。它的任务是分配容器(源)中的可用空间。因此无论屏幕尺寸有多小,每个项目都会获得在线上的可用空间的比例部分。
More specifically, there are eight flex items in your container. With flex-grow: 1
, each one receives 1/8 of the free space on the line. Since there's no content in your items, they can shrink to zero width and will never wrap.
更具体地说,您的容器中有八个弹性项目。使用flex-grow: 1
,每个人获得 1/8 的在线可用空间。由于您的项目中没有内容,它们可以缩小到零宽度并且永远不会换行。
The solution is to define a width on the items. Try this:
解决方案是在项目上定义宽度。尝试这个:
.parent {
display: flex;
flex-wrap: wrap;
}
.child {
flex: 1 0 21%; /* explanation below */
margin: 5px;
height: 100px;
background-color: blue;
}
<div class="parent">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
With flex-grow: 1
defined in the flex
shorthand, there's no need for flex-basis
to be 25%, which would actually result in three items per row due to the margins.
随着flex-grow: 1
中定义的flex
简写,也没有必要flex-basis
为25%,这实际上将导致三个项目每行由于利润率。
Since flex-grow
will consume free space on the row, flex-basis
only needs to be large enough to enforce a wrap. In this case, with flex-basis: 21%
, there's plenty of space for the margins, but never enough space for a fifth item.
由于flex-grow
会消耗行上的可用空间,因此flex-basis
只需要足够大以强制换行。在这种情况下,使用flex-basis: 21%
,边距有足够的空间,但永远没有足够的空间容纳第五个项目。
回答by dowomenfart
Add a width to the .child
elements. I personally would use percentages on the margin-left
if you want to have it always 4 per row.
为.child
元素添加宽度。margin-left
如果你想让它总是每行 4,我个人会使用百分比。
.child {
display: inline-block;
background: blue;
margin: 10px 0 0 2%;
flex-grow: 1;
height: 100px;
width: calc(100% * (1/4) - 10px - 1px);
}
回答by Capy
Here is another apporach.
这是另一种方法。
You can accomplish it in this way too:
您也可以通过这种方式完成它:
.parent{
display: flex;
flex-wrap: wrap;
}
.child{
width: 25%;
box-sizing: border-box;
}
Sample: https://codepen.io/capynet/pen/WOPBBm
示例:https: //codepen.io/capynet/pen/WOPBBm
And a more complete sample: https://codepen.io/capynet/pen/JyYaba
还有一个更完整的示例:https: //codepen.io/capynet/pen/JyYaba
回答by shanomurphy
I would do it like this using negative margins and calc for the gutters:
我会像这样使用负边距和计算排水沟:
.parent {
display: flex;
flex-wrap: wrap;
margin-top: -10px;
margin-left: -10px;
}
.child {
width: calc(25% - 10px);
margin-left: 10px;
margin-top: 10px;
}
Demo:https://jsfiddle.net/9j2rvom4/
演示:https : //jsfiddle.net/9j2rvom4/
Alternative CSS Grid Method:
替代 CSS 网格方法:
.parent {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-column-gap: 10px;
grid-row-gap: 10px;
}
回答by Muddasir Abbas
<style type="text/css">
.parent{
display: flex;
flex-wrap: wrap;
}
.parent .child{
flex: 1 1 25%;
}
</style>
<div class="parent">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
Hope it helps. for more detail you can follow this link
希望能帮助到你。有关更多详细信息,您可以点击此链接
回答by Joseph Cho
I believe this example is more barebones and easier to understandthen @dowomenfart.
我相信这个例子比@dowomenfart更准系统,更容易理解。
.child {
display: inline-block;
margin: 0 1em;
flex-grow: 1;
width: calc(25% - 2em);
}
This accomplishes the same width calculations while cutting straight to the meat. The math is way easier and em
is the new standarddue to its scalability and mobile-friendliness.
这在直接切割肉的同时完成了相同的宽度计算。由于其可扩展性和移动友好性,数学更容易并且em
是新标准。
回答by Mateus Manosso Barszcz
.parent-wrapper {
height: 100%;
width: 100%;
border: 1px solid black;
}
.parent {
display: flex;
font-size: 0;
flex-wrap: wrap;
margin-right: -10px;
margin-bottom: -10px;
}
.child {
background: blue;
height: 100px;
flex-grow: 1;
flex-shrink: 0;
flex-basis: calc(25% - 10px);
}
.child:nth-child(even) {
margin: 0 10px 10px 10px;
background-color: lime;
}
.child:nth-child(odd) {
background-color: orange;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style type="text/css">
</style>
</head>
<body>
<div class="parent-wrapper">
<div class="parent">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
</div>
</body>
</html>
;)
;)
回答by zurfyx
Flex wrap + negative margin
Flex wrap + 负边距
Why flex vs. display: inline-block
?
为什么是 flex 与display: inline-block
?
- Flex gives more flexibility with elements sizing
- Built-in white spacing collapsing (see 3 inline-block divs with exactly 33% width not fitting in parent)
- Flex 为元素大小调整提供了更大的灵活性
- 内置白色间距折叠(请参阅3 个宽度正好为 33% 的内联块 div 不适合父级)
Why negative margin?
为什么是负保证金?
Either you use SCSS or CSS-in-JS for the edge cases (i.e. first element in column), or you set a default margin and get rid of the outer margin later.
对于边缘情况(即列中的第一个元素),您可以使用 SCSS 或 CSS-in-JS,或者您可以设置默认边距并稍后去除外边距。
Implementation
执行
https://codepen.io/zurfyx/pen/BaBWpja
https://codepen.io/zurfyx/pen/BaBWpja
<div class="outerContainer">
<div class="container">
<div class="elementContainer">
<div class="element">
</div>
</div>
...
</div>
</div>
:root {
--columns: 2;
--betweenColumns: 20px; /* This value is doubled when no margin collapsing */
}
.outerContainer {
overflow: hidden; /* Hide the negative margin */
}
.container {
background-color: grey;
display: flex;
flex-wrap: wrap;
margin: calc(-1 * var(--betweenColumns));
}
.elementContainer {
display: flex; /* To prevent margin collapsing */
width: calc(1/var(--columns) * 100% - 2 * var(--betweenColumns));
margin: var(--betweenColumns);
}
.element {
display: flex;
border: 1px solid red;
background-color: yellow;
width: 100%;
height: 42px;
}
回答by wle8300
Here's another way without using calc()
.
这是另一种不使用calc()
.
// 4 PER ROW
// 100 divided by 4 is 25. Let's use 21% for width, and the remainder 4% for left & right margins...
.child {
margin: 0 2% 0 2%;
width: 21%;
}
// 3 PER ROW
// 100 divided by 3 is 33.3333... Let's use 30% for width, and remaining 3.3333% for sides (hint: 3.3333 / 2 = 1.66666)
.child {
margin: 0 1.66666% 0 1.66666%;
width: 30%;
}
// and so on!
That's all there is to it. You can get fancy with the dimensions to get a more aesthetic sizes but this is the idea.
这里的所有都是它的。您可以花哨的尺寸以获得更美观的尺寸,但这就是想法。