弹性框:将最后一行与网格对齐

Tho*_*isé 325 css css3 grid-layout flexbox

我有一个简单的flex-box布局,其容器如下:

.grid {
  display: flex;
  flex-flow: row wrap;
  justify-content: space-between;
}
Run Code Online (Sandbox Code Playgroud)

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

目前它看起来像

右下方的项目应位于中间

在这里,我希望右下角的项目位于"中间列"中.实现这一目标的最简单方法是什么?这是一个显示此行为的小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;
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

Dan*_*son 368

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

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

.grid::after {
  content: "";
  flex: auto;
}
Run Code Online (Sandbox Code Playgroud)

  • @DanAndreasson有两个问题,它不是从左边开始(如空格之间),最后一行的项目之间的空间也不同于前一行(模拟"any-size"中的一些固定宽度项目)网格 - 与两者有关... ... http://codepen.io/anon/pen/gPoYZE我想要的是保持"策略"(空间或空间)但从左边开始就像前面的行一样...我想知道,如果有可能推广你的惊人解决方案. (54认同)
  • 这只能起作用,因为这些项目有填充空间,每组4的组合百分比宽度等于100%.[在此编码器中](http://codepen.io/anon/pen/wMmmaR)我删除了`justify- content:space-between;`from` .grid`并删除`.grid:after`并且它的工作方式相同.现在,如果你尝试过这样的东西[像这样](http://codepen.io/anon/pen/dGmmYV)它就完全破了.请注意,每组4的宽度不要达到100%.在[OP的小提琴](http://jsfiddle.net/thorbenb/qxhHx/)中,宽度设置为px,因此您的解决方案[不起作用](http://jsfiddle.net/qxhHx/16/)情况. (40认同)
  • 尝试这个解决方案,最初,它在最后一行短的项目没有正确地传播`space-between`.但是,当我将`.grid:after`的`flex-basis`设置为与网格中的其他项相同的大小(每个断点,覆盖上面的默认/基本模块代码)时,最后一行正确展开.似乎可以在Safari,iOS,Firefox,Chrome(需要测试IE)上工作,我的最大行大小在我的初始实现时为3. (20认同)
  • 是否有可能以某种方式使其与空间一起工作? (16认同)
  • 根据我的需要,这可以通过以下修改:`{content:""; flex:0 0 32%; max-width:480px;}`并且我使用媒体查询更改更改了最大宽度,因此网格非常完美所有宽度. (6认同)
  • 我正在寻找和汤姆一样的东西.在响应式站点上,使用间隔,元素之间的空间将更改除最后一行之外的所有行.最后一个都是左对齐的. (3认同)
  • 我需要在由 `justify-content: space-between` 创建的元素之间保持自动空间。如果我将所有网格元素的宽度设置为与 flex-basis 的值相同,并且不要像这样使用 flex-auto:`&amp;:after { content: ''; @include mf-tabletPortrait { flex-basis: 48%; } @include mf-tabletLandscape { flex-basis: calc(33% - 30px); } } }` (3认同)
  • 只是我,或者如果您的物品宽度为33%,这个解决方案是否工作?https://codepen.io/jakobud/pen/wmEJmv看起来伪元素在这种情况下由于某种原因接收宽度,这会抛出布局.这是一个错误吗?有没有解决这个问题? (2认同)
  • @dyh333 是的。我们放弃了display:flex,转而使用display:grid。`显示:网格;间隙:20px;顶部填充:10px;网格模板列:重复(自动填充,minmax(250px,1fr));` (2认同)
  • 最后一行没有间距,所以我添加了:`flex-basis: &lt;your card width&gt;; flex-grow: 0` 到 `::after element`。现在最后一行的空间是正确的。 (2认同)
  • 此解决方案打破了最后一个行距。可以通过 margin/padding 来解决,但是这样 flex 属性就毫无意义了。我认为这个问题值得一个本地解决方案 (2认同)
  • 使用 `:last-child { margin-right: auto; 也可以实现同样的效果。}` 忽略之间的空格 (2认同)

dal*_*ard 145

一种技术是插入一些给定零高度的额外元素(与您预期的最大元素数一样多).空间仍然存在分歧,但多余的行崩溃为空:

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;
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

将来,通过使用多个可以实现这一点::after(n).

  • 同意,它很脏,但它的工作原理,并且比很多黑客更少hacky.哎呀,我正在使用它,直到::之后(12)获得支持,或者他们添加一些额外的对齐选项.这是一个真正的耻辱,因为此刻flexbox合理的方式是完全错误的!如果你正在证明一段文字是正确的,那么你永远不会试图证明最后一行的合理性.绝对应该是一种选择,我不敢相信他们错过了这个. (32认同)
  • 不幸的是,这会以非语义方式污染标记,但它完全有效.:SI希望我知道任何其他方式来复制这种行为,flexbox或其他方式,不需要非语义元素. (11认同)
  • @Codemonkey耶稣.我只是开始使用flexbox思考如何摆脱所有这些黑客,以便在网格中对齐那些内联块,现在事实证明它根本不可能!我马上就遇到了这个障碍,达到了极限,我认为我几乎无法愉快地解决所有这些旧的无法解决的CSS问题.我猜不是那么快.只需要20年才能获得适当的垂直居中 - 我们当然可以等待.耶稣,这似乎是如此简单的任务...... (7认同)
  • 我提出了一个只有CSS的解决方案..需要注意的是它只能解决两个丢失的项目,因此只能在一个弹性网格中安全地工作,每个包装行最多有三个项目.演示:http://codepen.io/lukejacksonn/pen/dozqVq这里的原则是使用伪元素作为*extra children*,并为它们提供与容器中的项相同的flex属性. (4认同)
  • @dalgard我不这么认为.请参阅[我的评论](http://stackoverflow.com/questions/18744164/flex-box-align-last-row-to-grid/34816625#comment-57760388). (3认同)
  • 似乎使用`:: after`从未超越松散的谈话.在本节中提到的内容很接近,但不完全是我在上面写的:http://www.w3.org/TR/css3-content/#inserting0 (2认同)

Dan*_*eld 82

正如其他海报所提到的那样 - 没有干净的方法将最后一行与flexbox对齐(至少根据当前规范)

但是,它的价值在于:使用CSS网格布局模块,这非常容易制作:

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

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

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

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

3)设置网格行和列的间隙/檐槽 - 这里,因为需要'间隔'布局 - 间隙实际上是最小间隙,因为它将根据需要增长.

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;
}
Run Code Online (Sandbox Code Playgroud)
<ul>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
</ul>
Run Code Online (Sandbox Code Playgroud)

Codepen演示(调整大小以查看效果)

  • 好的解决方案 唯一的问题是它不适用于IE10/11. (4认同)
  • 鉴于目前的可能性,现在应该是公认的答案.使用`:after`伪元素可能会在边缘情况下导致不必要的结果. (4认同)
  • 这应该是公认的答案.我会将它与flexbox结合起来作为后备,本着渐进增强的精神:不支持网格的浏览器会显示flexbox版本,这对我来说足够接近. (4认同)
  • @Danield这个建议帮了我很多,谢谢! (2认同)

Nic*_*alo 24

没有任何额外的标记,只需添加::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;
}
Run Code Online (Sandbox Code Playgroud)

使用这样的HTML:

<div class=grid">
   <div class="grid__element"></div>
   <div class="grid__element"></div>
   <div class="grid__element"></div>
</div>
Run Code Online (Sandbox Code Playgroud)

  • 这很有趣,但不太正确.当你在底行中处理两个以上的元素时会出现问题 - 上面行中元素之间出现的间距永远不会出现在最后一行; 这些物品被硬包装在一起,否定了空间之间的原始效用. (8认同)
  • 如果您使用“flex-basis: 10em”而不是宽度,效果会更好。 (2认同)

cim*_*non 13

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

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

ul {
  display: flex;
  flex-flow: column wrap;
  align-content: space-between;
  height: 4em;
}
Run Code Online (Sandbox Code Playgroud)

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

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

ul {
  columns: 15em;
}
Run Code Online (Sandbox Code Playgroud)

  • 它并不漂亮,但前端开发是可能的艺术; 实用主义是一个基本前提.我认为*very*这个词是错误的,因为额外的元素被用于99.9%的真实网站上的样式(参见Bootstrap容器元素). (4认同)
  • 有一种方法; 看到我的回答. (2认同)
  • @dalgard它没有改变Flexbox不提供语言结构来执行所要求的事实.此外,我认为添加假元素是一种极其肮脏的做法,就在那里使用表格进行布局. (2认同)

小智 11

一种可能的解决方案是justify-content: flex-start;.grid容器上使用它的子节点的大小限制,以及相应子元素的边距- 取决于所需的列数.

对于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%;
}
Run Code Online (Sandbox Code Playgroud)

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

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


小智 10

您也可以这样做:

.exposegrid:last-child {
  margin-right: auto;
}
Run Code Online (Sandbox Code Playgroud)

  • 几乎,但这会删除“space- Between”提供的元素之间的所有间距。 (4认同)

小智 7

使用 CSS 网格为我解决了这个问题,

此解决方案仅适用于您有固定数量的列,即没有。要在一行中显示的元素数

-> 使用网格但不指定行数,随着元素数量的增加,它会包装成列并动态添加行,我在此示例中指定了三列

-> 你不必给你的孩子/细胞任何位置,因为它会修复,这是我们不想要的。

.grid-class{
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  column-gap: 80px;
}
Run Code Online (Sandbox Code Playgroud)


Moh*_* AH 6

是。!我们可以但可以进行一些媒体查询,并且可以预定义最大列数

在这里使用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%;
  }
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)


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


OZZ*_*ZIE 6

如果您想要一个网格,在项目之间和项目之间都留有一定的空间,而没有任何初始空间,则可以使用以下简单解决方案:

.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.
}
Run Code Online (Sandbox Code Playgroud)

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

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

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


Fra*_*pin 5

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

网格容器

.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%;
}
Run Code Online (Sandbox Code Playgroud)

网格中的项目

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

}
Run Code Online (Sandbox Code Playgroud)

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

Codepen 上的现场演示

  • 当卡片大小固定且每行卡片数量未知时,此方法不起作用。https://codepen.io/zendu/pen/WXNGvo (3认同)

Sil*_*fer 5

我知道这里有很多答案,但是..最简单的方法是使用a grid代替flexand grid template columnsrepeatand auto 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;
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

  • 这是使最后一行项目保持对齐的正确解决方案。 (2认同)