Flexbox:每行 4 个项目
Flexbox: 4 items per row
我正在使用弹性框来显示 8 个项目,这些项目将随我的页面动态调整大小。我如何强制它将项目分成两行? (每行 4 个)?
这是一个相关的片段:
(或者如果你更喜欢 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>
为 .child
元素添加宽度。如果你想让它总是每行 4 个,我个人会在 margin-left
上使用百分比。
.child {
display: inline-block;
background: blue;
margin: 10px 0 0 2%;
flex-grow: 1;
height: 100px;
width: calc(100% * (1/4) - 10px - 1px);
}
这是不使用 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!
仅此而已。您可以花哨的尺寸以获得更美观的尺寸,但这就是想法。
这是另一个方法。
你也可以这样完成:
.parent{
display: flex;
flex-wrap: wrap;
}
.child{
width: 25%;
box-sizing: border-box;
}
样本:
https://codepen.io/capynet/pen/WOPBBm
还有一个更完整的示例:
https://codepen.io/capynet/pen/JyYaba
容器上有 flex-wrap: wrap
。这很好,因为它覆盖了默认值,即 nowrap
(source). This is the reason items don't wrap to form a grid in .
在这种情况下,主要问题是弹性项目 flex-grow: 1
。
flex-grow
属性 实际上并没有调整弹性项目的大小。它的任务是在容器(source)中分发免费的space。所以无论屏幕尺寸多小,每个项目都会按比例获得免费的一部分space就行了。
更具体地说,您的容器中有八个弹性项目。使用flex-grow: 1
,每人获得在线免费space的1/8。由于您的项目中没有内容,它们可以缩小到零宽度并且永远不会换行。
解决方案是在项目上定义宽度。试试这个:
.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>
在 flex
shorthand 中定义了 flex-grow: 1
,因此 flex-basis
不需要为 25%,这实际上会导致每行三个项目,因为边距。
由于 flex-grow
将消耗行上的空闲 space,因此 flex-basis
只需要足够大以强制换行。在这种情况下,对于 flex-basis: 21%
,页边距有很多 space,但对于第五项来说永远不够 space。
更多细节你可以关注这个Link
.parent{
display: flex;
flex-wrap: wrap;
}
.parent .child{
flex: 1 1 25%;
/*Start Run Code Snippet output CSS*/
padding: 5px;
box-sizing: border-box;
text-align: center;
border: 1px solid #000;
/*End Run Code Snippet output CSS*/
}
<div class="parent">
<div class="child">1</div>
<div class="child">2</div>
<div class="child">3</div>
<div class="child">4</div>
<div class="child">5</div>
<div class="child">6</div>
<div class="child">7</div>
<div class="child">8</div>
</div>
我相信这个例子比@dowomenfart 更准,更容易理解。
.child {
display: inline-block;
margin: 0 1em;
flex-grow: 1;
width: calc(25% - 2em);
}
这在直接切肉时完成了相同的宽度计算。数学更简单,em
是 new standard 由于其可扩展性和移动友好性。
.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>
;)
我会这样做,使用负边距和计算排水沟:
.parent {
display: flex;
flex-wrap: wrap;
margin-top: -10px;
margin-left: -10px;
}
.child {
width: calc(25% - 10px);
margin-left: 10px;
margin-top: 10px;
}
演示: https://jsfiddle.net/9j2rvom4/
备选 CSS 网格方法:
.parent {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-column-gap: 10px;
grid-row-gap: 10px;
}
Flex wrap + 负边距
为什么选择 flex 而不是 display: inline-block
?
- Flex 在调整元素大小方面提供了更大的灵活性
- 内置白色间距折叠(参见3 inline-block divs with exactly 33% width not fitting in parent)
为什么保证金为负数?
要么使用 SCSS 要么 CSS-in-JS 用于边缘情况(即列中的第一个元素),或者设置默认边距并稍后删除外边距.
实施
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;
}
你可以试试这个
.parent-wrapper {
height:100%;
width:100%;
border: 1px solid black;
}
.parent {
display: grid;
font-size: 0;
grid-template-columns: 25% 25% 25% 25%;
}
.child {
background:blue;
flex-grow: 1;
height:100px;
margin: 10px;
margin-bottom: 0;
}
.child:last-child {
margin-bottom: 10px;
}
<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>
我正在使用弹性框来显示 8 个项目,这些项目将随我的页面动态调整大小。我如何强制它将项目分成两行? (每行 4 个)?
这是一个相关的片段:
(或者如果你更喜欢 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>
为 .child
元素添加宽度。如果你想让它总是每行 4 个,我个人会在 margin-left
上使用百分比。
.child {
display: inline-block;
background: blue;
margin: 10px 0 0 2%;
flex-grow: 1;
height: 100px;
width: calc(100% * (1/4) - 10px - 1px);
}
这是不使用 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!
仅此而已。您可以花哨的尺寸以获得更美观的尺寸,但这就是想法。
这是另一个方法。
你也可以这样完成:
.parent{
display: flex;
flex-wrap: wrap;
}
.child{
width: 25%;
box-sizing: border-box;
}
样本: https://codepen.io/capynet/pen/WOPBBm
还有一个更完整的示例: https://codepen.io/capynet/pen/JyYaba
容器上有 flex-wrap: wrap
。这很好,因为它覆盖了默认值,即 nowrap
(source). This is the reason items don't wrap to form a grid in
在这种情况下,主要问题是弹性项目 flex-grow: 1
。
flex-grow
属性 实际上并没有调整弹性项目的大小。它的任务是在容器(source)中分发免费的space。所以无论屏幕尺寸多小,每个项目都会按比例获得免费的一部分space就行了。
更具体地说,您的容器中有八个弹性项目。使用flex-grow: 1
,每人获得在线免费space的1/8。由于您的项目中没有内容,它们可以缩小到零宽度并且永远不会换行。
解决方案是在项目上定义宽度。试试这个:
.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>
在 flex
shorthand 中定义了 flex-grow: 1
,因此 flex-basis
不需要为 25%,这实际上会导致每行三个项目,因为边距。
由于 flex-grow
将消耗行上的空闲 space,因此 flex-basis
只需要足够大以强制换行。在这种情况下,对于 flex-basis: 21%
,页边距有很多 space,但对于第五项来说永远不够 space。
更多细节你可以关注这个Link
.parent{
display: flex;
flex-wrap: wrap;
}
.parent .child{
flex: 1 1 25%;
/*Start Run Code Snippet output CSS*/
padding: 5px;
box-sizing: border-box;
text-align: center;
border: 1px solid #000;
/*End Run Code Snippet output CSS*/
}
<div class="parent">
<div class="child">1</div>
<div class="child">2</div>
<div class="child">3</div>
<div class="child">4</div>
<div class="child">5</div>
<div class="child">6</div>
<div class="child">7</div>
<div class="child">8</div>
</div>
我相信这个例子比@dowomenfart 更准,更容易理解。
.child {
display: inline-block;
margin: 0 1em;
flex-grow: 1;
width: calc(25% - 2em);
}
这在直接切肉时完成了相同的宽度计算。数学更简单,em
是 new standard 由于其可扩展性和移动友好性。
.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>
;)
我会这样做,使用负边距和计算排水沟:
.parent {
display: flex;
flex-wrap: wrap;
margin-top: -10px;
margin-left: -10px;
}
.child {
width: calc(25% - 10px);
margin-left: 10px;
margin-top: 10px;
}
演示: https://jsfiddle.net/9j2rvom4/
备选 CSS 网格方法:
.parent {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-column-gap: 10px;
grid-row-gap: 10px;
}
Flex wrap + 负边距
为什么选择 flex 而不是 display: inline-block
?
- Flex 在调整元素大小方面提供了更大的灵活性
- 内置白色间距折叠(参见3 inline-block divs with exactly 33% width not fitting in parent)
为什么保证金为负数?
要么使用 SCSS 要么 CSS-in-JS 用于边缘情况(即列中的第一个元素),或者设置默认边距并稍后删除外边距.
实施
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;
}
你可以试试这个
.parent-wrapper {
height:100%;
width:100%;
border: 1px solid black;
}
.parent {
display: grid;
font-size: 0;
grid-template-columns: 25% 25% 25% 25%;
}
.child {
background:blue;
flex-grow: 1;
height:100px;
margin: 10px;
margin-bottom: 0;
}
.child:last-child {
margin-bottom: 10px;
}
<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>