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

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

Flexbox: 4 items per row

htmlcssflexbox

提问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: wrapon 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: 1on the flex items.

在这种情况下,主要问题出flex-grow: 1在弹性项目上。

The flex-growproperty 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: 1defined in the flexshorthand, there's no need for flex-basisto be 25%, which would actually result in three items per row due to the margins.

随着flex-grow: 1中定义的flex简写,也没有必要flex-basis为25%,这实际上将导致三个项目每行由于利润率。

Since flex-growwill consume free space on the row, flex-basisonly 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 .childelements. I personally would use percentages on the margin-leftif you want to have it always 4 per row.

.child元素添加宽度。margin-left如果你想让它总是每行 4,我个人会使用百分比。

DEMO

演示

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

Demo:https://jsfiddle.net/jc2utfs3/

演示:https : //jsfiddle.net/jc2utfs3/

回答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 emis 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?

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.

这里的所有都是它的。您可以花哨的尺寸以获得更美观的尺寸,但这就是想法。