ChatGPT解决这个技术问题 Extra ChatGPT

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

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

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

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

目前它看起来像

https://i.stack.imgur.com/UrT6g.png

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

.exposegrid { 显示:弹性; flex-flow:换行; justify-content: 之间的空格; } .exposetab { 宽度:100px;高度:66px;背景颜色:rgba(255, 255, 255, 0.2);边框:1px 实心 rgba(0, 0, 0, 0.4);边框半径:5px;盒子阴影:1px 1px 2px rgba(0, 0, 0, 0.2);边距底部:10px; }

< /div>

在这里查看我的解决方案,我认为没有 hack 就可以很好地工作,只是数学:stackoverflow.com/questions/18744164/…
或者,可以使用较新的 css grid module - 它没有这个问题
我为子宽度可变的情况添加了一个通用 JS 解决方案,从而使行上的项目数也可变。

R
Robin Métral

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

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

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

是否有可能让它以某种方式与空间一起工作?
@DanAndreasson有两个问题,它不是从左边开始(如空格),最后一行项目之间的空间与前一行不同(模拟“任意大小”中的一些固定宽度项目网格 - 与两者有关)... codepen.io/anon/pen/gPoYZE 我想要的是保持“策略”(空间周围或空间之间)但从左侧开始,就像前几行一样...我想知道,如果它可以概括您的惊人解决方案。
这仅适用于项目有填充以将它们隔开,并且每组 4 个的组合百分比宽度等于 100%。In this codepen我从 .grid 中删除了 justify-content: space-between; 并删除了 .grid:after,它的工作原理相同。现在,如果您尝试 like this,它会完全崩溃。请注意,每组 4 个的宽度加起来不等于 100%。在 OP's fiddle 中,宽度以 px 为单位设置,因此您的解决方案 doesn't work 这种情况。
最初尝试此解决方案时,最后一行缺少的项目没有与 space-between 正确分布。但是,当我将 .grid:afterflex-basis 设置为与网格中其他项目相同的大小(每个断点,覆盖上述默认/基本模块代码)时,最后一行正确展开。似乎可以在 Safari、iOS、Firefox、Chrome 上运行(需要测试 IE),并且在我最初的实现中我最大的行大小是 3。
根据我的需要,这适用于以下修改:{ content: "";flex: 0 0 32%;max-width: 480px;} 并且我通过媒体查询更改更改了最大宽度,因此网格在所有宽度上都是完美的。
V
Vadim Ovchinnikov

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

然而,值得一提的是:使用 CSS Grid Layout Module,这非常容易产生:

基本上相关代码归结为:

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

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

2) 使用宽度为 100px 的自动列设置网格。 (注意 auto-fill 的使用(与 auto-fit 相对 - 它(对于 1 行布局)将空轨道折叠为 0 - 导致项目展开以占用剩余空间。这将导致合理的 ' space-between' 布局,当网格只有一行时,这在我们的例子中不是我们想要的。(查看 this demo 以查看它们之间的区别)。

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

4) 类似于弹性盒。

ul {显示:网格;网格模板列:重复(自动填充,100px);网格间隙:1rem; justify-content: 之间的空格; /* 无聊的属性 */ list-style: none;背景:小麦;填充:2rem;宽度:80vw;边距:0 自动; } li { 高度:50px;边框:1px 纯绿色; }

  • < /li>

Codepen Demo(调整大小看效果)


很好的解决方案。唯一的问题是它不适用于 IE10/11。
鉴于目前的可能性,这现在应该是公认的答案。在极端情况下使用 :after 伪元素可能会导致不需要的结果。
@Danield 这个建议对我帮助很大,谢谢!
这应该是公认的答案。本着渐进增强的精神,我会将它与 flexbox 结合起来作为后备:不支持网格的浏览器将显示 flexbox 版本,这对我来说足够接近。
“没有干净的方法将最后一行与 flexbox 左对齐(至少根据当前规范)” - 哈检查我的答案,它非常简单:)
T
Tamil Selvan C

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

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

身体{填充:5%; } div { 溢出:隐藏;背景颜色:黄色; } ul { 显示:弹性;弹性包装:换行;边距:0 -4px -4px 0;列表样式:无;填充:0; } li { 弹性:1 0 200px;高度:200px;右边框:4px 纯黑色;边框底部:4px 纯黑色;背景颜色:深粉色; } li:empty { 高度: 0;边框:无; } *, :before, :after { box-sizing:border-box; }

  • a
  • b
  • c
  • d
  • e
  • f
  • g
  • h
  • i
  • j
  • k

将来,这可能会通过使用多个 ::after(n) 来实现。


不幸的是,这以非语义的方式污染了标记,但它完全有效。 :SI 希望我知道任何其他方式来复制这种行为,flexbox 或其他方式,不需要非语义元素。
同意,它很脏,但它可以工作,并且比许多 hack 少。去死吧,我一直在使用它,直到 ::after(12) 获得支持,或者他们添加了一些额外的 justify 选项。真的很遗憾,因为 flexbox justify 目前的工作方式是完全错误的!如果您要证明一段文本的合理性,那么您永远不会尝试证明最后一行的合理性。绝对应该是一个选择,我不敢相信他们错过了这个。
我想出了一个纯 CSS 的解决方案.. 需要注意的是它只能解决两个丢失的项目,因此只能在每个包装行最多三个项目的弹性网格中安全地工作。演示:codepen.io/lukejacksonn/pen/dozqVq这里的原则是使用伪元素作为额外的子元素,并赋予它们与容器中的项目相同的flex属性。
@Codemonkey耶稣。我才刚刚开始使用 flexbox,想着如何摆脱所有这些旨在将这些内联块对齐网格内的黑客,现在事实证明这根本不可能!我马上就达到了那个障碍,达到了我认为我很难愉快地解决所有这些旧的无法解决的 CSS 问题的极限。没那么快,我猜。只用了 20 年就得到了正确的垂直定心——我们当然可以等待。天哪,这似乎是一个如此简单的任务......
@dalgard 我不这么认为。请参阅my comment
N
Nicolás Arévalo

没有任何额外的标记,只需添加 ::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;
}

使用这样的 HTML:

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

这很有趣,但并不完全正确。当您处理底行中的两个以上元素时,问题就出现了——上行元素之间出现的间距永远不会出现在最后一行;这些物品被硬包装在一起,否定了空间之间的原始效用。
如果您使用 flex-basis: 10em 而不是宽度,那就更好了。
S
SilverSurfer

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

.exposegrid { 显示:网格;网格模板列:重复(自动填充,100px); justify-content: 之间的空格; } .exposetab { 宽度:100px;高度:66px;背景颜色:rgba(255, 255, 255, 0.2);边框:1px 实心 rgba(0, 0, 0, 0.4);边框半径:5px;盒子阴影:1px 1px 2px rgba(0, 0, 0, 0.2);边距底部:10px; }

< /div>


这是使最后一行项目左对齐的正确解决方案。
我同意,正确的方法是使用网格。它可以使用 flexbox 来实现,但使用网格要干净得多。
c
cimmanon

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

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

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

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

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

ul {
  columns: 15em;
}

有一种方法;看我的回答。
@dalgard,您的答案是一种解决方法,而不是真正的解决方案。 cimmanon 的回答是正确的。
@Jonah我认为“技术”是对我答案的公平描述。对于包括提问者在内的很多人来说,它无疑是一种解决方案。
@dalgard 这并没有改变 Flexbox 不提供语言结构来完成所要求的事情这一事实。此外,我认为添加虚假元素是一种非常肮脏的做法,就像使用表格进行布局一样。
这并不漂亮,但前端开发是可能的艺术;实用主义是一个基本前提。我认为极端这个词用错了,因为在 99.9% 的真实网站上使用了额外的元素来进行样式设置(参见 Bootstrap 容器元素)。
J
Jared

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

对于 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%;
}

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

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


O
OZZIE

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

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

如果你想要最初的 5px 空间,那么只需删除负边距 :) 简单。

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

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


令人惊讶的是,这没有更多的赞成票。这是一个属于 Flex 博物馆的漂亮方法。
@EduardoLaHozMiranda 谢谢!但为什么是“博物馆”? IE11 不支持 CSS 网格,大多数网站仍然需要支持。 + 前端开发中的一些大人物仍然声称 grid 与 flexbox 有不同的用例。但也许你的意思是这应该是网络历史的重要组成部分:D
哈哈,是啊。我当时很兴奋。只是意味着这是对这个问题的一个很好的和最小的处理。
@dencey 你不需要知道这个解决方案,它是 25%,所以每行最多 4 个,但是你可以使用你想要的任何百分比
@OZZIE 固定项目宽度,而不是百分比,指的是问题中的样式,期望的效果是项目与两侧的容器边缘对齐,并且每行项目之间的空间相等。 jsfiddle.net/n6k831Ld
O
Orman Faghihi Mohaddes

你也可以这样做:

.exposegrid:last-child {
  margin-right: auto;
}

对...继续忘记自动边距👍
几乎,但这会删除 space-between 提供的元素之间的所有间距。
a
abatista

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

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

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

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

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

M
Mohamed Mohaideen AH

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

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

.container { 显示:弹性;显示:-webkit-flex;显示:-moz-flex; flex-flow:换行; -webkit-flex-flow:换行; -moz-flex-flow:换行; } .container .item { 显示:弹性;显示:-webkit-flex;显示:-moz-flex;证明内容:中心; -webkit-justify-content:中心; -moz-justify-content:中心;弹性基础:25%; //最大列数 %, 25% = 4 Columns } .container .item .item-child { width: 130px;高度:180px;背景:红色;边距: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%; } }

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

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


这只会在最新的 IE 中创建 3 个
F
Frank Spin

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

网格容器

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

网格中的项目

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

}

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

Live demo on Codepen


cthulu祝福你和你的电脑
当卡片大小固定且每行中的卡片数量未知时,此方法不起作用。 codepen.io/zendu/pen/WXNGvo
S
Sebastien Lorber

可以使用“flex-start”并手动添加边距。它需要一些数学技巧,但绝对很容易做到,并且可以很容易地与像 LESS 这样的 CSS 预处理器一起使用。

例如,请参阅这个 LESS 混合:

.flexboxGridMixin(@columnNumber,@spacingPercent) {
  @contentPercent: 100% - @spacingPercent;
  @sideMargin: @spacingPercent/(@columnNumber*2);
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  justify-content: flex-start;
  > * {
    box-sizing: border-box;
    width: @contentPercent/@columnNumber;
    margin-left: @sideMargin;
    margin-right: @sideMargin;
  }
}

然后它可以很容易地用于显示响应式网格布局:

ul {
  list-style: none;
  padding: 0;
  @spacing: 10%;
  @media only screen and (max-width: 499px) { .flexboxGridMixin(1,@spacing); }
  @media only screen and (min-width: 500px) { .flexboxGridMixin(2,@spacing); }
  @media only screen and (min-width: 700px) { .flexboxGridMixin(3,@spacing); }
  @media only screen and (min-width: 900px) { .flexboxGridMixin(4,@spacing); }
  @media only screen and (min-width: 1100px) { .flexboxGridMixin(5,@spacing); }
}

li {
  background: pink;
  height: 100px;
  margin-top: 20px;
}

这是一个例子

http://codepen.io/anon/pen/YyLqVB?editors=110


你从不使用@contentPercent。你打算吗?
宽度:@contentPercent/@columnNumber;
哇 !这个解决方案给我留下了深刻的印象。我会努力适应我的情况
M
Margaret

这是很多答案的组合,但它正是我所需要的——也就是说,将 flex 容器中的最后一个子元素向左对齐,同时保持间隔行为(在这种情况下,它是一个三列布局)。

这是标记:

.flex-container {
  display: flex;
  justify-content: space-between;
  flex-direction: row;
}

.flex-container:after {
  content: "";
  flex-basis: 30%;
}

为了更通用:flex-basis size 必须等于孩子的大小。
我发现 flex-grow: 0.9 而不是 flex-basis 适用于任意数量的列。在一堆现代浏览器中测试 - 它适用于所有浏览器,但填充在 IE 中被破坏(但在 Edge0 中工作
V
Vikram Kumar

如果您希望网格视图中的项目与最后一个元素的距离相等。确保您的卡片宽度为 100% 使用以下 css。这工作得很好

.container {
  /* ... snip ... */
  display: grid;
  grid-template-columns: repeat(auto-fill, 100px);
  justify-content: space-between;
  grid-gap: 20px;
}

Z
Znacovean Simion

此版本是固定宽度块的最佳方式:

http://codepen.io/7iomka/pen/oxxeNE

在其他情况下 - dalgard 版本

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

身体{填充:5%; } div { 溢出:隐藏;背景颜色:黄色; } ul { 显示:弹性;弹性包装:换行;证明内容:中心;边距:0 -4px -4px 0;列表样式:无;填充:0; } li { 弹性:1 0 200px;高度:200px;最大宽度:200px;最小宽度:200px;右边框:4px 纯黑色;边框底部:4px 纯黑色;背景颜色:深粉色; } li:empty { 高度: 0;边框:无; } *, :before, :after { box-sizing:border-box; }

  • a
  • b
  • c
  • d
  • e
  • f
  • g
  • h
  • i
  • j
  • k


E
Erik Parso

只需添加几个具有相同属性的假项目,除了高度设置为 0px 到最后。


添加假货在各个方面都是不好的做法。除非是强制性的,否则您不应该仅仅为了破解 css 而在 DOM 中填充东西。出于许多原因,从可访问性,到用奇怪的东西淹没代码库,再到使逻辑更复杂,难以理解,并且继续列出。除非您明确表示这可能是一个糟糕的解决方案或有特殊情况,否则不要推荐黑客攻击。
@Eksapsy 好吧,我找不到任何解决方案在 100% 的情况下工作且不使用 javascript。使用 javascript 会使事情变得更加复杂。网格+列模板?也许它也必须在 IE11 中工作,所以不。 nth-child, last-child, 'after' 说明符......这些都不适用于特定场景。有时除了使用丑陋的代码或较低的设计要求之外别无他法。
有趣的是,这实际上是唯一可行的解决方案(除了 JS-hacking),它有 0 票。嗯……不再了!无论如何,您需要添加的空 div 的数量是 N - 1,其中 N 是一行中的最大项目数。请注意,此解决方案允许容器将 space-around、space-between 和 space-evenly 用于其 justify-content 属性。最好将空 div 设置为 flex: 0 0 nn 其中 nn 与真实元素具有相同的 flex-basis。
S
Simon

即使 Flexbox 出现了差距,我也会添加一个可行的解决方案。

它使用兄弟组合器来检查 2 个条件。

它检查的第一个条件是元素是否是倒数第二个 div:nth-last-child(2)

对于 4 列布局,我们需要检查位置 2 和3 检查它是在 4 个div:nth-of-type(4n+2) 的第二行还是在一个行的第三个 div:nth-of-type(4n+3)

对于 3 列布局,我们只需要检查位置 2

div:nth-of-type(3n+2)

然后我们可以像下面这样组合 4 列布局

div:nth-last-child(2) + div:nth-of-type(4n+2)

div:nth-last-child(2) + div:nth-of-type(4n+3)

我们还需要处理一种极端情况,即 3n+2 和4 的倍数将获得 35% 的边距右 div:nth-last-child(2) + div:nth-of-type(4n+4)

3列布局将是

div:nth-last-child(2) + div:nth-of-type(3n+2)

然后我们需要为上面的选择器添加一个边距。需要计算margin-right,这取决于flex-basis。

我添加了一个包含 3 列和 4 列的示例以及一个媒体查询。我还添加了一个小的 JavaScript 按钮,它添加了一个新的 div,以便您检查它是否有效。

它是一点点 CSS,但它可以工作。如果您需要更多解释,我也在我的网站上写过这个。 https://designkojo.com/css-programming-using-css-pseudo-classes-and-combinators

变量编号 = 11; $("#add").on("click", function() { number = number + 1; $("#main").append("

" + number + "
"); });身体{边距:0; } 主要{ 显示:弹性;弹性包装:换行;对齐项目:弹性开始;对齐内容:弹性开始; /* 垂直 */ justify-content: space-between;最小宽度:300px;最大宽度:1200px;边距:20px 自动;背景颜色:浅灰色;高度:100vh; } div { 弹性基础:30%;背景颜色:#5F3BB3;最小高度:20px;高度:50px;边距底部:20px;显示:弯曲;证明内容:中心;对齐项目:居中;颜色:#9af3ff;字体大小:3em; } div:nth-last-child(2) + div:nth-of-type(3n+2) { 背景颜色:#f1b73e;右边距:35%; } @media screen and (min-width: 720px) { div { flex-basis: 22%; } div:nth-last-child(2) { 背景色:greenyellow; } div:nth-of-type(4n+2) { 背景颜色: deeppink; } /* 使用 Plus 组合器用于直接兄弟 */ div:nth-last-child(2) + div:nth-of-type(4n+2) { background-color: #f1b73e;保证金-权利:52%; } div:nth-last-child(2) + div:nth-of-type(4n+3) { 背景颜色:#f1b73e;保证金权利:26%; } /* 还需要将 last 设置为 0% 以在变为 (3n+2) 时覆盖 * 任何 3n+2 和 4 的倍数的数字将获得 35% 的 margin-right * div:nth-last-child (2) + div:nth-of-type(3n+2) */ div:nth-last-child(2) + div:nth-of-type(4n+4) { 背景颜色:#f1b73e;右边距:0; } } 我的新项目