【问题标题】:extra space when centering elements using flexbox使用 flexbox 使元素居中时的额外空间
【发布时间】:2019-01-21 01:26:49
【问题描述】:

我使用align-itemsjustify-content 将元素居中,我的html 是:

<div class="flex-container">
    <div class="item-1">div</div>
    <div class="item-2">w=250px</div>
    <div class="item-3">h=250px</div>
    <div class="item-4">w/h=300px</div>
    <div class="item-5">w=350px</div>
    <div class="item-6">w=350px</div>
</div>

我的 css 代码是这样的:

.flex-container {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    align-content: center;
}

(我省略了一些不重要的 css 代码。)

所以结果会是这样的:

但是如果我缩小浏览器窗口,它会是这样的:

我不明白为什么两行之间有这么大的空间(我知道使用align-content: center; 可以解决,但我想知道这些多余的空间是如何存在的)

* {
  box-sizing: border-box;
  font-size: 1.5rem;
}

html {
  background: #b3b3b3;
  padding: 5px;
}

body {
  background: #b3b3b3;
  padding: 5px;
  margin: 0;
}

.flex-container {
  background: white;
  padding: 10px;
  border: 5px solid black;
  height: 800px;
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
}

.item-1 {
  background: #ff7300;
  color: white;
  padding: 10px;
  border: 5px solid black;
  margin: 10px;
}

.item-2 {
  background: #ff9640;
  color: white;
  padding: 10px;
  border: 5px solid black;
  margin: 10px;
  width: 250px;
  /* font-size: 1.8rem; */
}

.item-3 {
  background: #ff9640;
  color: white;
  padding: 10px;
  border: 5px solid black;
  margin: 10px;
  height: 250px;
}

.item-4 {
  background: #f5c096;
  color: white;
  padding: 10px;
  border: 5px solid black;
  margin: 10px;
  width: 300px;
  height: 300px;
}

.item-5 {
  background: #d3c0b1;
  color: white;
  padding: 10px;
  border: 5px solid black;
  margin: 10px;
  width: 350px;
}

.item-6 {
  background: #d3c0b1;
  color: white;
  padding: 10px;
  border: 5px solid black;
  margin: 10px;
  width: 350px;
}
<div class="flex-container">
  <div class="item-1">div</div>
  <div class="item-2">w=250px</div>
  <div class="item-3">h=250px</div>
  <div class="item-4">w/h=300px</div>
  <div class="item-5">w=350px</div>
  <div class="item-6">w=350px</div>
</div>

如果我进一步缩小浏览器窗口,那么就没有多余的空间了:

【问题讨论】:

  • 如果您也输入您的.item-n 代码会很有用

标签: html css flexbox


【解决方案1】:

align-content

请注意,align-content: stretch 也在此处发挥作用。

align-content 属性在弹性线之间分配可用空间。默认值为stretch

因此,当您的项目换成两行时,align-content: stretch 会在各行之间平均分配可用空间。


align-items

从容器中删除 align-items: center。然后您会注意到,当项目换行时,行(或“行”,在本例中)之间没有间隙。 demo

行高由align-content、项目的高度和项目的内容设置。


align-contentalign-items 一起工作

恢复align-items: center。现在,当项目换行时,行之间会出现明显的间隙。

这是因为align-items: center 根据align-content: stretch 建立的行高、项目高度和项目内容将项目定位在行的垂直中心。

在此处设置行高(使用align-content: stretchalign-items: stretch):

...并在此处继续(使用align-content: stretchalign-items: center):

align-items 对弯曲线的高度没有影响。该工作由align-content 领导。

但是,通过更改 align-content 的值(更改为 flex-startflex-endspace-betweencenter 等),您可以打包 flex 行,挤出可用空间,从而删除差距。


为什么第一行比第二行高align-content: stretch

容器设置为height: 800px

有两个已定义高度的项目:

  • .item-3 { height: 250px }
  • .item-4 { height: 300px }

.item-5.item-6 构成第二行时,容器中的可用空间最简单的形式是500px(800px - 300px)。

所以,在一个有两行和align-content: stretch 的容器中,250px 被分配到每行的高度。

  • 第一行是 300 像素(定义的高度)加上 250 像素(可用空间)
  • 第二行是 250 像素(可用空间)

这就是第一行更高的原因。

请注意,上面的可用空间计算在实际布局中略有偏差。那是因为项目中有文本,这会消耗可用空间。您可以考虑文本的高度以获得精确的数字,或者完全删除文本以查看上述计算是否到位。


更多细节:

【讨论】:

  • 我是否正确地说仅 align-content 不足以定义线条?因为即使我保持拉伸,我的行高也不相同,但这取决于元素的高度。
  • @TemaniAfif,是的,你是对的。我在答案中添加了一个部分并附有解释。
【解决方案2】:

为方便起见,我将减少代码,以便我们更好地理解行为。

让我们考虑这个初始代码:

* {
  box-sizing: border-box;
  font-size: 1.5rem;
}

html {
  background: #b3b3b3;
  padding: 5px;
}

body {
  background: #b3b3b3;
  padding: 5px;
  margin: 0;
}

.flex-container {
  background: white;
  padding: 10px;
  border: 5px solid black;
  height: 400px;
  display: flex;
  flex-direction: row;
  flex-wrap:wrap;
}

.item-1 {
  background: #ff7300;
  color: white;
  padding: 10px;
  border: 5px solid black;
  margin: 10px;
}

.item-2 {
  background: #ff9640;
  color: white;
  padding: 10px;
  border: 5px solid black;
  margin: 10px;
  width: 250px;
}

.item-3 {
  background: #ff9640;
  color: white;
  padding: 10px;
  border: 5px solid black;
  margin: 10px;
  height: 150px;
}
<div class="flex-container">
  <div class="item-1">div</div>
  <div class="item-2">w=250px</div>
  <div class="item-3">h=150px</div>
</div>

容器具有固定高度,只有一个元素具有固定高度,另一个元素将被拉伸以填充父级高度,因为默认情况下align-itemsstretch

现在让我们减小容器的宽度,以使第三个元素位于第二行:

* {
  box-sizing: border-box;
  font-size: 1.5rem;
}

html {
  background: #b3b3b3;
  padding: 5px;
}

body {
  background: #b3b3b3;
  padding: 5px;
  margin: 0;
}

.flex-container {
  background: white;
  padding: 10px;
  border: 5px solid black;
  height: 400px;
  display: flex;
  flex-direction: row;
  flex-wrap:wrap;
  width:500px;
}

.item-1 {
  background: #ff7300;
  color: white;
  padding: 10px;
  border: 5px solid black;
  margin: 10px;
}

.item-2 {
  background: #ff9640;
  color: white;
  padding: 10px;
  border: 5px solid black;
  margin: 10px;
  width: 250px;
}

.item-3 {
  background: #ff9640;
  color: white;
  padding: 10px;
  border: 5px solid black;
  margin: 10px;
  height: 150px;
}
<div class="flex-container">
  <div class="item-1">div</div>
  <div class="item-2">w=250px</div>
  <div class="item-3">h=150px</div>
</div>

这里我们有一个复杂的行为,我们有一个多行弹性容器,其中item1item2 属于第一行,item3 属于第二行。我无法很好地解释每条线的高度是如何定义的(复杂的部分)。在此之后,每个 flex 项目将拉伸以填充其行的高度,除非它具有像 item3 这样的固定高度,或者我们更改了对齐方式。

现在,如果我们将align-items 更改为与stretch 不同的东西,我们就会有差距:

* {
  box-sizing: border-box;
  font-size: 1.5rem;
}

html {
  background: #b3b3b3;
  padding: 5px;
}

body {
  background: #b3b3b3;
  padding: 5px;
  margin: 0;
}

.flex-container {
  background: white;
  padding: 10px;
  border: 5px solid black;
  height: 400px;
  display: flex;
  flex-direction: row;
  flex-wrap:wrap;
  width:500px;
  align-items:flex-start;
}

.item-1 {
  background: #ff7300;
  color: white;
  padding: 10px;
  border: 5px solid black;
  margin: 10px;
}

.item-2 {
  background: #ff9640;
  color: white;
  padding: 10px;
  border: 5px solid black;
  margin: 10px;
  width: 250px;
}

.item-3 {
  background: #ff9640;
  color: white;
  padding: 10px;
  border: 5px solid black;
  margin: 10px;
  height: 150px;
}
<div class="flex-container">
  <div class="item-1">div</div>
  <div class="item-2">w=250px</div>
  <div class="item-3">h=150px</div>
</div>

如果我们将上面的代码与前面的代码进行比较,我们可以看到item3 保持原位,只有item1item2 的高度发生了变化。这解释了align-items 将对齐项目在其先前定义的行内由于换行。

换句话说,当我们有一个多行 flex 容器时,我们首先定义行(考虑容器的高度、元素的高度和其他 flexbox 属性)然后我们将项目对齐在它们的行内,我们拥有的间隙是由于对齐是如何完成的。

这里有一个更好的例子来展示不同的情况:

.flex-container {
  background: white;
  padding: 10px;
  border: 5px solid black;
  height: 200px;
  display: inline-flex;
  vertical-align:top;
  flex-direction: row;
  flex-wrap:wrap;
  width:100px;
}

.item-1 {
  background: #ff7300;
  color: white;
  border: 1px solid black;
  margin: 2px;
}

.item-2 {
  background: #ff9640;
  color: white;
  border: 1px solid black;
  margin: 2px;
  width: 70px;
}

.item-3 {
  background: #ff9640;
  color: white;
  border: 1px solid black;
  margin: 2px;
  height: 50px;
}
<div class="flex-container">
  <div class="item-1">A</div>
  <div class="item-2">B</div>
  <div class="item-3">C</div>
</div>
<div class="flex-container" style="align-items:flex-start;">
  <div class="item-1">A</div>
  <div class="item-2">B</div>
  <div class="item-3">C</div>
</div>
<div class="flex-container" style="align-items:center;">
  <div class="item-1">A</div>
  <div class="item-2">B</div>
  <div class="item-3">C</div>
</div>
<div class="flex-container" style="align-items:flex-end;">
  <div class="item-1">A</div>
  <div class="item-2">B</div>
  <div class="item-3">C</div>
</div>
<div class="flex-container" style="align-items:flex-end;">
  <div class="item-1">A</div>
  <div class="item-2">B</div>
  <div class="item-3" style="margin-bottom:auto;">C</div>
</div>

<div class="flex-container">
  <div class="item-1" style="margin-top:auto;">A</div>
  <div class="item-2">B</div>
  <div class="item-3" >C</div>
</div>

我们可以清楚地注意到,我们在所有容器上都有相同的线条,只有对齐方式发生了变化,从而产生了不同的间隙。


如果没有固定高度的元素,则行的高度相同,因此容器将被平均分割。

.flex-container {
  background: white;
  padding: 10px;
  border: 5px solid black;
  height: 200px;
  display: inline-flex;
  vertical-align:top;
  flex-direction: row;
  flex-wrap:wrap;
  width:100px;
}

.item-1 {
  background: #ff7300;
  color: white;
  border: 1px solid black;
  margin: 2px;
}

.item-2 {
  background: #ff9640;
  color: white;
  border: 1px solid black;
  margin: 2px;
  width: 70px;
}

.item-3 {
  background: #ff9640;
  color: white;
  border: 1px solid black;
  margin: 2px;
}
<div class="flex-container">
  <div class="item-1">A</div>
  <div class="item-2">B</div>
  <div class="item-3">C</div>
</div>
<div class="flex-container" style="align-items:flex-start;">
  <div class="item-1">A</div>
  <div class="item-2">B</div>
  <div class="item-3">C</div>
</div>
<div class="flex-container" style="align-items:center;">
  <div class="item-1">A</div>
  <div class="item-2">B</div>
  <div class="item-3">C</div>
</div>
<div class="flex-container" style="align-items:flex-end;">
  <div class="item-1">A</div>
  <div class="item-2">B</div>
  <div class="item-3">C</div>
</div>
<div class="flex-container" style="align-items:flex-end;">
  <div class="item-1">A</div>
  <div class="item-2">B</div>
  <div class="item-3" style="margin-bottom:auto;">C</div>
</div>

<div class="flex-container">
  <div class="item-1" style="margin-top:auto;">A</div>
  <div class="item-2">B</div>
  <div class="item-3" >C</div>
</div>

通过更改align-content,我们将更改行的创建方式,然后再考虑align-items 以对齐行内的项目:

.flex-container {
  background: white;
  padding: 10px;
  border: 5px solid black;
  height: 200px;
  display: inline-flex;
  vertical-align:top;
  flex-direction: row;
  flex-wrap:wrap;
  width:100px;
}

.item-1 {
  background: #ff7300;
  color: white;
  border: 1px solid black;
  margin: 2px;
}

.item-2 {
  background: #ff9640;
  color: white;
  border: 1px solid black;
  margin: 2px;
  width: 70px;
}

.item-3 {
  background: #ff9640;
  color: white;
  border: 1px solid black;
  margin: 2px;
  height:50px;
}
<div class="flex-container">
  <div class="item-1">A</div>
  <div class="item-2">B</div>
  <div class="item-3">C</div>
</div>
<div class="flex-container" style="align-content:flex-start;">
  <div class="item-1">A</div>
  <div class="item-2">B</div>
  <div class="item-3">C</div>
</div>
<div class="flex-container" style="align-content:center;">
  <div class="item-1">A</div>
  <div class="item-2">B</div>
  <div class="item-3">C</div>
</div>
<div class="flex-container" style="align-content:flex-end;">
  <div class="item-1">A</div>
  <div class="item-2">B</div>
  <div class="item-3">C</div>
</div>

为了理解这个答案的复杂部分(如何定义行),您可以参考规范:https://www.w3.org/TR/css-flexbox-1/#layout-algorithm

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-01-04
    • 2013-10-23
    • 1970-01-01
    • 2017-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-13
    相关资源
    最近更新 更多