使用flexbox将元素居中时的额外空间

时间:2018-11-02 13:15:14

标签: html css css3 flexbox

我正在使用public class Order { private int id; private String name; private String date1; private int date2; private char numerOfFile; private List<OrderBody> orderBodyList; } public class OrderBody { private int lp; private int id; private BigDecimal priceByOne; private BigDecimal count; private int foreignId; } align-items来使元素居中,我的html是:

justify-content

我的CSS代码类似于:

<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代码。)

所以结果将是:

enter image description here

但是如果我缩小浏览器窗口,它将像: enter image description here

我不明白为什么两行之间有这么大的空间(我知道使用.flex-container { display: flex; flex-direction: row; flex-wrap: wrap; align-items: center; justify-content: center; align-content: center; } 可以解决,但是我想知道这些多余的空间最初是怎么存在的)

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

如果我进一步缩小浏览器窗口,则不会有多余的空间:

enter image description here

2 个答案:

答案 0 :(得分:2)

align-content

请注意,align-content: stretch也在这里。

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

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


align-items

从容器中删除align-items: center。然后,您会注意到,在包装物品时,行之间没有间隙(在这种情况下为“行”)。 demo

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

enter image description here


align-contentalign-items一起工作

还原align-items: center。现在,当物品包装好时,线之间有一个可见的间隙。

enter image description here

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

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

enter image description here

...,然后继续(使用align-content: stretchalign-items: center):

enter image description here

align-items对伸缩线的高度没有影响。该工作由align-content负责。

但是,通过将align-content的值(更改为flex-startflex-endspace-betweencenter等),可以打包弯曲线,挤压出自由空间,从而消除空隙。

enter image description here


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

容器设置为height: 800px

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

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

.item-5.item-6形成第二行时,容器中的自由空间以其最简单的形式为500px(800px-300px)。

因此,在具有两行和align-content: stretch的容器中,将250px分配到每一行的高度。

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

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

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


更多详细信息:

答案 1 :(得分:1)

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

让我们考虑以下初始代码:

* {
  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>

在这里,我们有一个复杂的行为,我们有一个多行flex容器,其中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