CSS Flex-box:将最后一行与网格对齐

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18744164/
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 00:19:49  来源:igfitidea点击:

Flex-box: Align last row to grid

cssflexboxgrid-layout

提问by Thorben Croisé

I have a simple flex-box layout with a container like:

我有一个简单的 flex-box 布局,其中包含一个容器,例如:

.grid {
  display: flex;
  flex-flow: row wrap;
  justify-content: space-between;
}

Now I want the items in the last row to be aligned with the other. justify-content: space-between;should be used because the width and height of the grid can be adjusted.

现在我希望最后一行中的项目与另一行对齐。justify-content: space-between;应该使用,因为可以调整网格的宽度和高度。

Currently it looks like

目前看起来像

The item in the bottom right should be in the middle

右下角的项目应该在中间

Here, I want the item in the bottom right to be in the "middle column". What is the simplest way to accomplish that? Here is a small jsfiddlethat shows this behaviour.

在这里,我希望右下角的项目位于“中间列”中。实现这一目标的最简单方法是什么?这是一个显示这种行为的小jsfiddle

.exposegrid {
  display: flex;
  flex-flow: row wrap;
  justify-content: space-between;
}

.exposetab {
  width: 100px;
  height: 66px;
  background-color: rgba(255, 255, 255, 0.2);
  border: 1px solid rgba(0, 0, 0, 0.4);
  border-radius: 5px;
  box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.2);
  margin-bottom: 10px;
}
<div class="exposegrid">
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
</div>

回答by Dan Andreasson

Add a ::afterwhich autofills the space. No need to pollute your HTML. Here is a codepen showing it: http://codepen.io/DanAndreasson/pen/ZQXLXj

添加一个::after自动填充空间。无需污染您的 HTML。这是一个显示它的代码笔:http://codepen.io/DanAndreasson/pen/ZQXLXj

.grid {
  display: flex;
  flex-flow: row wrap;
  justify-content: space-between;
}

.grid::after {
  content: "";
  flex: auto;
}

回答by dalgard

One technique would be inserting a number of extra elements (as many as the max number of elements you ever expect to have in a row) that are given zero height. Space is still divided, but superfluous rows collapse to nothing:

一种技术是插入一些高度为零的额外元素(与您期望在一行中拥有的最大元素数一样多)。空间仍然被分割,但多余的行会坍塌为空:

http://codepen.io/dalgard/pen/Dbnus

http://codepen.io/dalgard/pen/Dbnus

body {
  padding: 5%;
}

div {
  overflow: hidden;
  background-color: yellow;
}

ul {
  display: flex;
  flex-wrap: wrap;
  margin: 0 -4px -4px 0;
  list-style: none;
  padding: 0;
}

li {
  flex: 1 0 200px;
  height: 200px;
  border-right: 4px solid black;
  border-bottom: 4px solid black;
  background-color: deeppink;
}
li:empty {
  height: 0;
  border: none;
}

*,
:before,
:after {
  box-sizing: border-box;
}
<div>
  <ul>
    <li>a</li>
    <li>b</li>
    <li>c</li>
    <li>d</li>
    <li>e</li>
    <li>f</li>
    <li>g</li>
    <li>h</li>
    <li>i</li>
    <li>j</li>
    <li>k</li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
  </ul>
</div>

In the future, this may become achievable through using multiple ::after(n).

将来,这可能可以通过使用多个::after(n).

回答by Danield

As other posters have mentioned - there's no clean way to left-align the last row with flexbox (at least as per the current spec)

正如其他海报所提到的 - 没有干净的方法可以将最后一行与 flexbox 左对齐(至少按照当前规范)

However, for what it's worth: With the CSS Grid Layout Modulethis is surprisingly easy to produce:

然而,它的价值在于:使用CSS Grid Layout Module,这非常容易生成:

Basically the relevant code boils down to this:

基本上相关的代码归结为:

ul {
  display: grid; /* 1 */
  grid-template-columns: repeat(auto-fill, 100px); /* 2 */
  grid-gap: 1rem; /* 3 */
  justify-content: space-between; /* 4 */
}

1) Make the container element a grid container

1) 使容器元素成为网格容器

2) Set the grid with auto columns of width 100px. (Note the use of auto-fill(as apposed to auto-fit- which (for a 1-row layout) collapses empty tracks to 0 - causing the items to expand to take up the remaining space. This would result in a justified 'space-between' layout when grid has only one row which in our case is not what we want. (check out this demoto see the difference between them)).

2) 使用宽度为 100px 的自动列设置网格。(请注意使用自动填充(与auto-fit- 它(对于 1 行布局)将空轨道折叠为 0 - 导致项目扩展以占用剩余空间。这将导致合理的“间隔”) ' 布局时网格只有一行,这在我们的例子中不是我们想要的。(查看这个演示以了解它们之间的区别))。

3) Set gaps/gutters for the grid rows and columns - here, since want a 'space-between' layout - the gap will actually be a minimum gap because it will grow as necessary.

3)为网格行和列设置间隙/装订线 - 在这里,因为想要“间隔”布局 - 间隙实际上将是最小间隙,因为它会根据需要增长。

4) Similar to flexbox.

4) 类似于 flexbox。

ul {
  display: grid;
  grid-template-columns: repeat(auto-fill, 100px);
  grid-gap: 1rem;
  justify-content: space-between;
  
  /* boring properties */
  list-style: none;
  background: wheat;
  padding: 2rem;
  width: 80vw;
  margin: 0 auto;
}

li {
  height: 50px;
  border: 1px solid green;
}
<ul>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
</ul>

Codepen Demo(Resize to see the effect)

Codepen Demo(调整大小看效果)

回答by Nicolás Arévalo

Without any extra markup, just adding ::afterworked for me specifying the width of the column.

没有任何额外的标记,只需添加::after为我指定列的宽度即可。

.grid {
  display:flex;
  justify-content:space-between;
  flex-wrap:wrap;
}
.grid::after{
  content: '';
  width: 10em // Same width of .grid__element
}
.grid__element{
  width:10em;
}

With the HTML like this:

使用这样的 HTML:

<div class=grid">
   <div class="grid__element"></div>
   <div class="grid__element"></div>
   <div class="grid__element"></div>
</div>

回答by cimmanon

You can't. Flexbox is not a grid system. It does not have the language constructs to do what you're asking for, at least not if you're using justify-content: space-between. The closest you can get with Flexbox is to use the column orientation, which requires setting an explicit height:

你不能。Flexbox 不是网格系统。它没有语言结构来完成您的要求,至少在您使用justify-content: space-between. 使用 Flexbox 最接近的是使用列方向,这需要设置明确的高度:

http://cssdeck.com/labs/pvsn6t4z(note: prefixes not included)

http://cssdeck.com/labs/pvsn6t4z(注意:不包括前缀)

ul {
  display: flex;
  flex-flow: column wrap;
  align-content: space-between;
  height: 4em;
}

However, it would be simpler to just use columns, which has better support and doesn't require setting a specific height:

但是,仅使用具有更好支持且不需要设置特定高度的列会更简单:

http://cssdeck.com/labs/dwq3x6vr(note: prefixes not included)

http://cssdeck.com/labs/dwq3x6vr(注意:不包括前缀)

ul {
  columns: 15em;
}

回答by Jared

A possible solution is to use justify-content: flex-start;on the .gridcontainer, size restrictions on its children, and margins on the appropriatechild elements -- depending on the desired number of columns.

一种可能的解决方案是justify-content: flex-start;.grid容器上使用,对其子元素进行大小限制,并在适当的子元素上使用边距——这取决于所需的列数。

For a 3-column grid, the basic CSS would look like this:

对于 3 列网格,基本 CSS 如下所示:

.grid {
    display: flex;
    flex-flow: row wrap;
    justify-content: flex-start;
}

.grid > * {
    flex: 0 0 32%;
    margin: 1% 0;
}

.grid > :nth-child(3n-1) {
    margin-left: 2%;
    margin-right: 2%;
}

It's another imperfect solution, but it works.

这是另一个不完美的解决方案,但它有效。

http://codepen.io/tuxsudo/pen/VYERQJ

http://codepen.io/tuxsudo/pen/VYERQJ

回答by SilverSurfer

I know there are many answers here but.. The simplest way to do this is with a gridinstead of flexand grid template columnswith repeatand auto fills, where you have to set the number of pixels that you have given to each element, 100pxfrom your snippet code.

我知道这里有很多答案,但是.. 最简单的方法是使用grid而不是flexgrid template columns使用repeatauto fills,您必须100px从代码片段中设置为每个元素提供的像素数。

.exposegrid {
     display: grid;
     grid-template-columns: repeat(auto-fill, 100px);
     justify-content: space-between;
}
 .exposetab {
     width: 100px;
     height: 66px;
     background-color: rgba(255, 255, 255, 0.2);
     border: 1px solid rgba(0, 0, 0, 0.4);
     border-radius: 5px;
     box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.2);
     margin-bottom: 10px;
}
<div class="exposegrid">
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
</div>

回答by OZZIE

If you want a grid with some space between the items and the items starting without any initial space then this simple solution works:

如果您想要一个在项目之间有一些空间的网格,并且项目开始时没有任何初始空间,那么这个简单的解决方案有效:

.grid {
    display: flex;
    flex-flow: row wrap;
    margin: 0 -5px; // remove the inital 5px space
    width: auto;
}
.grid__item {
    width: 25%;
    padding: 0 5px; // should be same as the negative margin above.
}

If you want the initial 5px space then just remove the negative margin :) Simple.

如果您想要初始 5px 空间,则只需删除负边距 :) 简单。

https://jsfiddle.net/b97ewrno/2/

https://jsfiddle.net/b97ewrno/2/

The accepted answer, whilst good, it causes there to be no space between the elements on the second row..

接受的答案虽然很好,但它导致第二行的元素之间没有空格。

回答by Mohamed Mohaideen AH

Yes.! We can but with some media queries & Maximum no of columns are predefined.

是的。!我们可以使用一些媒体查询和预定义的最大列数

Here am using 4 columns. Check my code:

这里使用 4 列。检查我的代码:

.container {
  display: flex;
  display: -webkit-flex;
  display: -moz-flex;
  flex-flow: row wrap;
  -webkit-flex-flow: row wrap;
  -moz-flex-flow: row wrap;
}

.container .item {
  display: flex;
  display: -webkit-flex;
  display: -moz-flex;
  justify-content: center;
  -webkit-justify-content: center;
  -moz-justify-content: center;
  flex-basis: 25%; //max no of columns in %, 25% = 4 Columns
}

.container .item .item-child {
  width: 130px;
  height: 180px;
  background: red;
  margin: 10px;
}

@media (max-width: 360px) {
  .container .item {
    flex-basis: 100%;
  }
}

@media (min-width:360px) and (max-width: 520px) {
  .container .item {
    flex-basis: 50%;
  }
}

@media (min-width:520px) and (max-width: 680px) {
  .container .item {
    flex-basis: 33.33%;
  }
}
<div class="container">

  <div class="item">
    <div class="item-child">1</div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>

</div>

NOTE
1) No need to create child div. It may be any other tag like 'img' r whatever you want..
2) If you want more columns adjust the media queries and maximum no.of columns.

注意
1) 无需创建子 div。它可能是任何其他标签,如“img”或任何您想要的标签。
2)如果您想要更多列,请调整媒体查询和最大列数。

回答by Frank Spin

If you want to align the last item to the grid use the following code:

如果要将最后一项与网格对齐,请使用以下代码:

Grid container

网格容器

.card-grid {
  box-sizing: border-box;
  max-height: 100%;
  display: flex;
  flex-direction: row;
  -webkit-box-orient: horizontal;
  -webkit-box-direction: normal;
  justify-content: space-between;
  align-items: stretch;
  align-content: stretch;
  -webkit-box-align: stretch;
  -webkit-box-orient: horizontal;
  -webkit-box-direction: normal;
  -ms-flex-flow: row wrap;
  flex-flow: row wrap;
}

.card-grid:after {
  content: "";
  flex: 1 1 100%;
  max-width: 32%;
}

Item in the grid

网格中的项目

.card {
  flex: 1 1 100%;
  box-sizing: border-box;
  -webkit-box-flex: 1;
  max-width: 32%;
  display: block;
  position: relative;

}

The trick is to set the max-width of the item equal to the max-width of the .card-grid:after.

诀窍是将项目的最大宽度设置为等于 .card-grid:after 的最大宽度。

Live demo on Codepen

Codepen 上的现场演示