了解flex:wrap with align-items:stretch

das*_*dsa 4 html css css3 flexbox

如果您运行以下代码段,则可以看到height两行中的行flexbox container不同.有人可以解释一下吗?

如果您对线A进行注释(= heightflexbox项中删除显式),则两行都相等height.我不明白为什么?

是一个相同片段的JSfiddle,如果方便的话.

*{
  color: blue;
  font-size: 22px;
}
.box1 {
  width: 50px;
  background-color: black;
  border: 1px solid blue;
}

.box2 {
  width: 50px;
  background-color: red;
  border: 1px solid blue;
}

.box3 {
  width: 50px;
  height: 30px;/*Line A: comment this and both rows will have same height*/
  background-color: yellow;
  border: 1px solid blue;
}

.container {
  display: flex;
  width: 160px;
  height: 500px;
  border: 1px solid red;
  align-items: stretch;
  flex-wrap:wrap;
}
Run Code Online (Sandbox Code Playgroud)
<div class="container">
    <div class="box1">.box1</div>
    <div class="box2">.box2</div>
    <div class="box3">.box3</div>
    <div class="box1">.box1</div>
    <div class="box2">.box2</div>
</div>
Run Code Online (Sandbox Code Playgroud)

我的理解:

我找不到任何详细的解释flex-wrap: wrap.诸如MDNCSS技巧之类的网站只是说当wrap应用项目时将会有项目width = flex-basis,当row项目完成后,项目将转移到下一个flexbox row.但是这些row内部的对齐方式是flexbox container什么呢?

我的理解是:(假设flex-direction: row和包装是允许的)如果项目占用多个row,则每个项目row将具有相同的高度(= flexbox_container_height/row_count),并且每个项目都row作为一个flexbox container.因此,如果我应用属性flex-items:center,则项目将在这些行的每个内部居中.

我的理解是否正确?

Mic*_*l_B 7

这里的问题不是flex-wrap或(align-itemsalign-content至少不是直接).

真正的问题是box-sizing.

关键点:

free space !== length 
Run Code Online (Sandbox Code Playgroud)

box-sizing属性适用于长度,包括height,widthflex-basis.

box-sizing属性并不适用于自由空间,所以它被忽略align-items,flex-grow,justify-content,fr和其他属性和管理的自由空间的功能.


box-sizing

box-sizing属性有两个值:

  • content-box (默认值)
  • border-box

使用时content-box,您定义的任何长度都不包括填充或边框.

使用border-box,填充和边框是长度计算的因素.

在引用CSS Box模型时请考虑这些术语.

在此输入图像描述

来源:W3C

请注意,box-sizing提供no padding-boxmargin-box值.边距总是单独添加.


你的代码

这是你的flex容器:

.container {
   display: flex;
   flex-wrap: wrap;  
   align-items: stretch; /* default setting */
   width: 160px;
   height: 500px;
   border: 1px solid red;
}
Run Code Online (Sandbox Code Playgroud)

在你的弹性项目中,让我们box3暂时删除.这是定义高度为30px的项目.

.container {
  display: flex;
  flex-wrap: wrap;  
  align-items: stretch; /* default setting */  
  width: 160px;
  height: 500px;
  border: 1px solid red;
}

.box3 { height: 30px; }


.box1 { background-color: gray;   }
.box2 { background-color: orange; }
.box3 { background-color: yellow; }

.container > div {
  flex: 0 0 50px;
  border: 1px solid blue;
}

* {
  color: blue;
  font-size: 22px;
}
Run Code Online (Sandbox Code Playgroud)
<div class="container">
    <div class="box1">box1</div>
    <div class="box2">box2</div>
    <!--<div class="box3">box3</div>-->
    <div class="box1">box1</div>
    <div class="box2">box2</div>
</div>
Run Code Online (Sandbox Code Playgroud)

主要观察:

  • 这两行现在都是250px的高度.
  • 即使顶部/底部边框有4px,并且box-sizing默认情况下content-box,高度仍为250px.
  • 边框被忽略,因为项目的高度是使用align-items: stretch(自由空间,而不是长度,计算)设置的.

现在,align-items: stretch让我们使用height: 50%每个项目,而不是使用:

.container {
  display: flex;
  flex-wrap: wrap;  
  /* align-items: stretch; */  
  width: 160px;
  height: 500px;
  border: 1px solid red;
}

.box3 { height: 30px; }


.box1 { background-color: gray;   }
.box2 { background-color: orange; }
.box3 { background-color: yellow; }

.container > div {
  height: 50%; /* NEW */
  flex: 0 0 50px;
  border: 1px solid blue;
}

* {
  color: blue;
  font-size: 22px;
}
Run Code Online (Sandbox Code Playgroud)
<div class="container">
    <div class="box1">box1</div>
    <div class="box2">box2</div>
    <!--<div class="box3">box3</div>-->
    <div class="box1">box1</div>
    <div class="box2">box2</div>
</div>
Run Code Online (Sandbox Code Playgroud)

每个项目(和行)的高度现在是252px.顶部和底部边框已添加.

如果我们添加box-sizing: border-box,那么我们回到250px,就像我一样align-items: stretch.

.container {
  display: flex;
  flex-wrap: wrap;  
  /* align-items: stretch; */  
  width: 160px;
  height: 500px;
  border: 1px solid red;
}

.box3 { height: 30px; }


.box1 { background-color: gray;   }
.box2 { background-color: orange; }
.box3 { background-color: yellow; }

.container > div {
  box-sizing: border-box;  /* NEW */
  height: 50%;
  flex: 0 0 50px;
  border: 1px solid blue;
}

* {
  color: blue;
  font-size: 22px;
}
Run Code Online (Sandbox Code Playgroud)
<div class="container">
    <div class="box1">box1</div>
    <div class="box2">box2</div>
    <!--<div class="box3">box3</div>-->
    <div class="box1">box1</div>
    <div class="box2">box2</div>
</div>
Run Code Online (Sandbox Code Playgroud)


.box3

现在,让我们重新引入.box3到HTML结构,恢复box-sizing: content-boxalign-items: stretch和删除height: 50%的项目.我们回到原来的布局.

.container {
  display: flex;
  flex-wrap: wrap;  
  align-items: stretch; 
  width: 160px;
  height: 500px;
  border: 1px solid red;
}

.box3 { height: 30px; }


.box1 { background-color: gray;   }
.box2 { background-color: orange; }
.box3 { background-color: yellow; }

.container > div {
  flex: 0 0 50px;
  border: 1px solid blue;
}

* {
  color: blue;
  font-size: 22px;
}
Run Code Online (Sandbox Code Playgroud)
<div class="container">
    <div class="box1">box1</div>
    <div class="box2">box2</div>
    <div class="box3">box3</div>
    <div class="box1">box1</div>
    <div class="box2">box2</div>
</div>
Run Code Online (Sandbox Code Playgroud)

align-items: stretch第一行的项目高度为252px.

align-items: stretch第二行的项目高度为248像素.

这是因为box3有一个实际长度defined(height: 30px),它激活box-sizing: content-box,它将顶部和底部边框(2px)添加到行高(252px).

所以让我们只适用box-sizing: border-boxbox3.

听起来不对,除了align-items不关心box-sizing.

因此虽然box-sizing确实使第一行250px,但仍然在第二行(248px)中计算边界.

.container {
  display: flex;
  flex-wrap: wrap;  
  align-items: stretch; 
  width: 160px;
  height: 500px;
  border: 1px solid red;
}

.box3 { height: 30px; }


.box1 { background-color: gray;   }
.box2 { background-color: orange; }
.box3 { background-color: yellow; }

.container > div {
  flex: 0 0 50px;
  border: 1px solid blue;
}

* {
  box-sizing: border-box; /* new */
  color: blue;
  font-size: 22px;
}
Run Code Online (Sandbox Code Playgroud)
<div class="container">
    <div class="box1">box1</div>
    <div class="box2">box2</div>
    <div class="box3">box3</div>
    <div class="box1">box1</div>
    <div class="box2">box2</div>
</div>
Run Code Online (Sandbox Code Playgroud)

需要注意的是,除了paddingborders,也有相关的问题line-height,并font-size在这个特殊的布局.为了使行高明显有意义,您必须删除这些因素.

* {
  font-size: 0;
  line-height: 0;
  margin: 0;
  padding: 0;
  border: 0;
}

.container {
  display: flex;
  flex-wrap: wrap;  
  width: 160px;
  height: 500px;
}

.box3 { height: 30px; }

.box1 { background-color: gray;   }
.box2 { background-color: orange; }
.box3 { background-color: yellow; }

.container > div { flex: 0 0 50px; }
Run Code Online (Sandbox Code Playgroud)
<div class="container">
  <div class="box1">box1</div>
  <div class="box2">box2</div>
  <div class="box3">box3</div>
  <div class="box1">box1</div>
  <div class="box2">box2</div>
</div>
Run Code Online (Sandbox Code Playgroud)

现在第一行中的项目高度为265px,第二行中的项目高度为235px.

在将所有固定长度计算在计算中之后,自由空间就是剩下的空间.

500 - 30 = 470 ----> this is the free vertical space in your container

470 / 2 = 235  ----> this is the free space allocated to each row

235 + 30 = 265  ----> this is the height of the first row, since 30px is added to the free space
Run Code Online (Sandbox Code Playgroud)