弹性盒子布局模型
是一种用于按行或按列布局元素的 一维布局方法。元素可以膨胀以填充额外的空间,收缩以适应更小的空间。
示例1: 正常流布局
.css
section{
display: block;
}
.html
<header>
<h3>Sample flexbox example</h3>
</header>
<section>
<article>
<h4>First article</h4>
<p>Tacos actually microdosing</p>
</article>
<article>
<h4>Second article</h4>
<p>Tacos actually microdosing</p>
</article>
<article>
<h4>Third article</h4>
<p>Tacos actually microdosing</p>
<p>Cray food truck brunch</p>
</article>
</section>
效果:示例2: 弹性盒子布局 修改 display
的值 为flex
section{
display: flex;
}
article {
padding: 5px;
margin: 5px;
background: aqua;
width: 100%; // 充满空间
}
效果:flex 模型的概念说明
- 主轴(main axis):是沿着 flex 元素放置的方向延伸的轴(比如页面上的横向的行、纵向的列)。该轴的开始和结束被称为 main start 和 main end。
- 交叉轴(cross axis):是垂直于 flex 元素放置方向的轴。该轴的开始和结束被称为 cross start 和 cross end。
-
flex 容器(flex container):设置了
display: flex
的父元素。(在本例中是<section>
被称之为 flex 容器(flex container)。 -
flex 项(flex item):在 flex 容器中表现为柔性的盒子的元素。 (本例中是
<article>
元素。
属性 flex-direction
决定弹性盒子内部项的方向。
指定了内部元素是如何在 flex 容器中布局的,定义了主轴的方向 (正方向或反方向)。
语法:
flex-direction =
row |
row-reverse |
column |
column-reverse
取值:
row
:主轴与文本方向相同。主轴起点和主轴终点与内容方向相同。row-reverse
:表现和 row 相同,但置换了主轴起点和主轴终点column
:主轴和块轴相同。主轴起点与主轴终点和书写模式的前后点相同column-reverse
:表现和column相同,但置换了主轴起点和主轴终点
属性 flex-wrap
换行 处理溢出的布局
指定 flex
元素单行显示还是多行显示。如果允许换行,这个属性允许你控制行的堆叠方向。
语法:
flex-wrap =
nowrap |
wrap |
wrap-reverse
取值
nowrap
:默认值,flex 的元素被摆放到到一行,这可能导致 flex 容器溢出。cross-start 会根据flex-direction
的值等价于 start 或 before。wrap
:flex 元素 被打断到多个行中。cross-start 会根据flex-direction
的值等价于 start或before。cross-end 为确定的 cross-start 的另一端。wrap-reverse
:和wrap
的行为一样,但是 cross-start 和 cross-end 互换。
示例:
如图是未换行,且益处的 弹性布局:添加如下代码:
section{
display: flex;
flex-wrap: wrap;
}
效果:也添加如下代码:
article {
flex: 100px;
}
效果:
属性 flex-flow
简写属性
是 flex-direction
和 flex-wrap
的简写。
语法:
flex-flow = <'flex-direction'> || <'flex-wrap'>
属性 flex
增大,缩小
设置了弹性项目如何增大或缩小以适应其弹性容器中可用的空间。
是简写属性,其包含如下属性:
flex-grow
、flex-shrink
、flex-basis
语法:
flex =
none |
[ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
取值:
flex-grow
flex-shrink
flex-basis
单值语法:
- 一个无单位数
<number>
: 它会被当作 flex:<number> 1 0; <flex-shrink>的值被假定为 1,然后<flex-basis> 的值被假定为0。 - 一个有效的 宽度 (width) 值:它会被当作
flex-basis
的值。 - 关键字
none
、auto
、initial
.
双值语法:
- 第一个值必须为一个无单位数,并且它会被当作
flex-grow
的值。- 第二个值必须为以下之一:
一个无单位数:它会被当作flex-shrink
的值。
一个有效的宽度值:它会被当作flex-basis
的值。
- 第二个值必须为以下之一:
三值语法:
- 第一个值必须为一个无单位数,并且它会被当作
flex-grow
的值。 - 第二个值必须为一个无单位数,并且它会被当作
flex-shrink
的值。 - 第三个值必须为一个有效的宽度值,并且它会被当作
flex-basis
的值。
属性 flex-grow
MDN介绍:
设置 flex 项 主尺寸 的 flex 增长系数,负值无效,默认为 0。
主尺寸:flex项的宽度或高度,取决于flex-direction
值。
个人理解:
属性规定了 flex项 在 flex 容器中分配剩余空间的 所占有相对比例。
剩余空间:是 flex 容器的大小减去所有 flex 项的大小加起来的空间。
如果所有的兄弟项目
flex-grow
属性值,都是一致的,那么所有的项目 所占的剩余空间 ,按相同比例分配,否则将根据不同的flex-grow
定义的比例进行分配。
语法:
flex-grow =
<number [0,∞]>
示例1:所有的flex项的 flex-grow
属性值 全部为 0
,即默认值,按相同比例分配。
.html
<div id="content">
<div class="box box1" style="background-color:red;">A</div>
<div class="box box2" style="background-color:lightblue;">B</div>
<div class="box box3" style="background-color:yellow;">C</div>
<div class="box box4" style="background-color:brown;">D</div>
<div class="box box5" style="background-color:lightgreen;">E</div>
</div>
.css
#content{
width: 100px;
padding: 0px;
border: 2px solid black;
display: flex;
justify-content: space-around;
flex-flow: row wrap;
}
.box{
width: 10px;
}
效果:示例2:我们将 .box1 的 flex-grow
属性值 改为 1
,添加如下代码
.box1{
flex-grow: 1;
}
效果:代码解析:
将 .box1 的flex-grow
属性值 改为1
。意味着:所有的剩余空间,全部分配给了 .box1。
即使你将 属性值设为100
,结果也是一样的,此时不论值为多少,.box 占有所有剩余空间。
示例3:我们将 .box1 和 .box2 的 flex-grow
属性值 改为 1
,添加如下代码
.box1{
flex-grow: 1;
}
.box2{
flex-grow: 1;
}
效果:代码解析:
将 .box1 和 .box2 的flex-grow
属性值 都改为1
。意味着:所有的剩余空间,全部 平均 分配给了 .box1 和 .box2 ,各占1 / 2
。
示例4:我们将 .box2 的 flex-grow
属性值 改为 2
,添加如下代码
.box1{
flex-grow: 1;
}
.box2{
flex-grow: 2;
}
效果:代码解析:
将 ..box2 的flex-grow
属性值 改为2
。意味着:所有的剩余空间,.box1 占1 / 3
,.box2 占2 / 3
;
示例5:看一下 flex项 换行之后,修改 flex-grow
属性,会是什么效果,添加如下代码
.box{
width: 30px;
}
.box1{
flex-grow: 1;
}
.box4{
flex-grow: 1;
}
效果:代码解析:
在第一行,所有的剩余空间,全部分配给了 .box1。
在第二行,所有的剩余空间,全部分配给了 .box4。
属性 flex-basis
MDN:指定了 flex 元素在主轴方向上的初始大小。如果不使用 box-sizing
改变盒模型的话,那么这个属性就决定了 flex 元素的内容盒(content-box)的尺寸。
语法:
flex-basis =
content |
<'width'>
<'width'> =
<length> |
<percentage>
语法示例:
指定<'width'>
flex-basis: 10em;
flex-basis: 3px;
flex-basis: auto;
固有的尺寸关键词
flex-basis: fill;
flex-basis: max-content;
flex-basis: min-content;
flex-basis: fit-content;
在 flex item 内容上的自动尺寸
flex-basis: content;
全局数值
flex-basis: inherit;
flex-basis: initial;
flex-basis: unset;
取值:
<'width'>
:width
值可以是<length>
; 该值也可以是一个相对于其父弹性盒容器主轴尺寸的百分数
。负值是不被允许的。默认为auto
。content
:基于 flex 的元素的内容自动调整大小。
由于最初规范中没有包括这个值,在一些早期的浏览器实现的 flex 布局中,content 值无效,可以利用设置width
或height
为auto
达到同样的效果。
示例:
.box{
flex-basis: 100px;
}
.box1{
flex-basis: max-content;
}
效果:
属性 flex-shrink
MDN:指定了 flex 元素的收缩规则。flex 元素仅在默认宽度之和大于容器的时候才会发生收缩,其收缩的大小是依据 flex-shrink 的值。负值是不被允许的。默认值 0。
自己的理解:原理同 属性 flex-grow
相似。属性 按比例 分配 溢出父元素的空间。如果设置了属性 flex-wrap
属性值 wrap
,那么 flex-shrink
会失效。
语法:
flex-grow =
<number [0,∞]>
示例:未设置 flex-shrink
属性,且 子元素 共 超出 父元素 100px的宽度 空间。
.css
#content{
width: 500px;
padding: 0px;
border: 2px solid black;
align-items: center;
display: flex;
justify-content: space-around;
}
.box{
flex-basis: 120px;
}
效果:示例1:设置 .box 的 属性 flex-shrink
属性,添加如下代码。
.box{
flex-basis: 120px;
}
.box1{
flex-shrink: 1;
}
效果:代码解析:
.box1 收缩了 全部 溢出的 宽度 100px 剩余 20px ,下面的红色方块就是 20px 的宽度。
属性 align-self
用于 单独 设置 弹性元素 (flex项) 在侧轴(纵轴)方向上的对齐方式。
align-self
会对齐当前 grid
或 flex
行中的元素,并覆盖已有的 align-items
的值。
语法:
align-self =
auto |
normal |
stretch |
<baseline-position> |
<overflow-position>? <self-position>
<baseline-position> =
[ first | last ]? &&
baseline
<overflow-position> =
unsafe |
safe
<self-position> =
center |
start |
end |
self-start |
self-end |
flex-start |
flex-end
取值:
auto
:继承 父元素的align-items
的 属性值。如果其没有父元素,则值为stretch
。center
:flex 元素会对齐到 cross-axis 的中间,如果该元素的 cross-size 尺寸大于 flex 容器,将在两个方向均等溢出。-
flex-start
:flex 元素会对齐到 cross-axis 的首端。专门为了弹性布局而开发的属性。-
start
:效果同flex-start
。 -
self-start
:效果同flex-start
。
-
-
flex-end
:flex 元素会对齐到 cross-axis 的尾端。专门为了弹性布局而开发的属性。-
end
:效果同flex-end
。 -
self-end
:效果同flex-end
。
-
stretch
:默认值。元素被拉伸以适应容器,但同时会遵照min/max-width/height
属性的限制。-
baseline
:元素被定位到容器的基线。侧轴起点到元素基线距离最大的元素将会于侧轴起点对齐以确定基线。first baseline
last baseline
示例1:设置 algin-self
属性 为 center
.html
.css
#content{
width: 300px;
height: 50px;
padding: 0px;
border: 2px solid black;
display: flex;
}
.box{
flex-basis: 50px;
}
.box1{
align-self: center;
}
.box2{
height: 30px;
align-self: center;
}
.box3{
height: 70px;
align-self: center;
}
效果:代码解析:
子元素 设置了align-self
属性后,元素不再填充满 父元素。
示例2:flex-start
、start
、self-start
.box1{
align-self: flex-start;
}
.box2{
align-self: self-start;
}
.box3{
align-self: start;
}
单行效果:换行效果:
示例3:flex-end
、end
、self-end
.box1{
align-self: flex-end;
}
.box2{
align-self: self-end;
}
.box3{
align-self: end;
}
效果:示例4:stretch
.box1{
align-self: stretch;
}
.box2{
height: 20px;
align-self: stretch;
}
.box3{
height: 70px;
align-self: stretch;
}
效果:示例5:basline
、first baseline
、last baseline
.box1{
font-size: 10px;
align-self: baseline;
}
.box2{
font-size: 15px;
align-self: baseline;
}
.box3{
font-size: 20px;
align-self: baseline;
}
.box4{
font-size: 25px;
align-self: baseline;
}
.box5{
font-size: 30px;
align-self: baseline;
}
效果:代码解析:
不同的flex项 设置不同的字体大小时,first baseline
|baseline
会在纵轴首端进行基线的对齐。
不同的flex项 设置不同的字体大小时,lase baseline
会在纵轴尾端进行基线的对齐。
不同的flex项 设置相同的字体大小时,lase baseline
效果同flex-end
;first baseline
|baseline
效果同flex-start
。
属性 align-items
用于 统一 设置 弹性元素 (flex项) 在侧轴(纵轴、交叉轴)方向上的对齐方式。
行排列。
语法,取值,示例 同 align-self
。
属性 align-content
当交叉轴上有可用的空间,且容器内有多行的项目时,才可以对齐容器内的各项(垂直)。
语法:
align-content =
normal |
<baseline-position> |
<content-distribution> |
<overflow-position>? <content-position>
<baseline-position> =
[ first | last ]? &&
baseline
<content-distribution> =
space-between |
space-around |
space-evenly |
stretch
<overflow-position> =
unsafe |
safe
<content-position> =
center |
start |
end |
flex-start |
flex-end
取值:
normal
:这些项按默认位置填充,就像没有设置对齐内容值一样。-
flex-start
:所有行从垂直轴起点开始填充。剩余空间,全部堆砌到容器的下面。-
start
:同flex-start
。
-
-
flex-end
:所有行从垂直轴终点开始填充。剩余空间,全部堆砌到容器的上面。-
end
:同flex-end
。
-
center
:所有行朝向容器的中心填充。剩余空间,全部平均的堆砌到容器的上面和下面。space-between
:所有行在容器中平均分布。相邻两行间距相等。容器的垂直轴起点边和终点边分别与第一行和最后一行的边对齐。space-around
:所有行在容器中平均分布,相邻两行间距相等。容器的垂直轴起点边和终点边分别与第一行和最后一行的距离是相邻两行间距的一半。space-evenly
:所有行沿垂直轴均匀分布在对齐容器内。stretch
:均匀分布项目, 拉伸‘自动’ - 大小的项目以充满容器
示例1:flex-start
、start
#content1{
flex-flow: row wrap;
// flex-flow: stretch; 默认值
}
#content2{
flex-flow: row wrap;
align-content: flex-start;
}
#content3{
flex-flow: row wrap;
align-content: start;
}
效果:示例2:flex-end
、end
#content1{
flex-flow: row wrap;
// flex-flow: stretch; 默认值
}
#content2{
flex-flow: row wrap;
align-content: flex-end;
}
#content3{
flex-flow: row wrap;
align-content: end;
}
效果:示例3:center
#content1{
flex-flow: row wrap;
// flex-flow: stretch; 默认值
}
#content2{
flex-flow: row wrap;
align-content: center;
}
效果:示例4:space-between
、space-around
、space-evenly
#content1{
flex-flow: row wrap;
align-content: space-between;
}
#content2{
flex-flow: row wrap;
align-content: space-around;
}
#content3{
flex-flow: row wrap;
align-content: space-evenly;
}
效果:
align-self
、align-items
、align-content
,
还有safe
、unsafe
、safe
、normal
等值,没有研究出来,有懂的小伙伴可以在评论区分享一下。
属性 justify-content
定义 顺着弹性容器主轴 (或者网格行轴) ,如何分配元素之间及其周围的空间。
语法:
justify-content =
normal |
<content-distribution> |
<overflow-position>? [ <content-position> | left | right ]
<content-distribution> =
space-between |
space-around |
space-evenly |
stretch
<overflow-position> =
unsafe |
safe
<content-position> =
center |
start |
end |
flex-start |
flex-end
语法示例:
/* Positional alignment */
justify-content: center; /* 居中排列 */
justify-content: start; /* Pack items from the start */
justify-content: end; /* Pack items from the end */
justify-content: flex-start; /* 从行首起始位置开始排列 */
justify-content: flex-end; /* 从行尾位置开始排列 */
justify-content: left; /* Pack items from the left */
justify-content: right; /* Pack items from the right */
/* Baseline alignment */
justify-content: baseline;
justify-content: first baseline;
justify-content: last baseline;
/* Distributed alignment */
justify-content: space-between; /* 均匀排列每个元素
首个元素放置于起点,末尾元素放置于终点 */
justify-content: space-around; /* 均匀排列每个元素
每个元素周围分配相同的空间 */
justify-content: space-evenly; /* 均匀排列每个元素
每个元素之间的间隔相等 */
justify-content: stretch; /* 均匀排列每个元素
'auto'-sized 的元素会被拉伸以适应容器的大小 */
/* Overflow alignment */
justify-content: safe center;
justify-content: unsafe center;
/* Global values */
justify-content: inherit;
justify-content: initial;
justify-content: unset;
取值:
center
:元素向每行中点排列。-
flex-start
:从行首开始排列。-
start
: 从行首开始排列。
-
-
flex-end
:从行尾开始排列。-
end
: 从行尾开始排列。
-
stretch
:如果元素的组合尺寸小于对齐容器的尺寸,那么所有自动设置大小的元素的尺寸都会等量(而不是按比例)增加,同时仍然遵守max-height/max-width的约束(或类似的功能),这样组合尺寸就会沿着主轴完全填充对齐容器。space-between
:均匀排列每个元素,首个元素放置于起点,末尾元素放置于终点。space-around
:均匀排列每个元素,每个元素周围分配相同的空间。space-evenly
:均匀排列每个元素,每个元素之间的间隔相等。
示例1:center
#content1{
flex-flow: row nowrap;
justify-content: center;
}
#content2{
flex-flow: row wrap;
justify-content: center;
}
效果:示例2:flex-start
、start
、left
#content1{
flex-flow: row nowrap;
justify-content: flex-start;
}
#content2{
flex-flow: row wrap;
justify-content: flex-start;
}
#content3{
flex-flow: row wrap;
justify-content: start;
}
效果:示例3:flex-end
、end
、right
#content1{
flex-flow: row nowrap;
justify-content: flex-end;
}
#content2{
flex-flow: row wrap;
justify-content: flex-end;
}
#content3{
flex-flow: row wrap;
justify-content: end;
}
效果:示例4:stretch
#content1{
flex-flow: row nowrap;
justify-content: stretch;
}
#content2{
flex-flow: row wrap;
justify-content: stretch;
}
.box{
flex=basis: 60px;
}
.boxx{
flex=basis: 60px;
}
效果:在多行的容器内,感觉没啥效果。
示例5:space-between
#content1{
flex-flow: row nowrap;
justify-content: space-between;
}
#content2{
flex-flow: row wrap;
justify-content: space-between;
}
效果:示例6:space-around
、space-evenly
#content1{
flex-flow: row nowrap;
justify-content: space-around;
}
#content2{
flex-flow: row wrap;
justify-content: space-around;
}
效果:示例7:space-evenly
#content1{
flex-flow: row nowrap;
justify-content: space-evenly;
}
#content2{
flex-flow: row wrap;
justify-content: space-evenly;
}
效果:
属性 justify-items
、justify-self
justify-items
:为 所有 盒中的项目定义了默认的 justify-self
,可以使这些项目以默认方式沿 主轴线 对齐到每个盒子。
justify-self
:使 单个 盒中的项目 以默认方式沿 主轴线 对齐到每个盒子。
该属性的作用效果取决于我们使用的布局模式:
- 在块级布局中,会将其包含的项目在其行内轴上对齐;
- 绝对定位的元素中,会将其包含的项目在其行内轴上对齐,同时考虑 top、left、bottom、right 的值;
- 表格单元中,该属性被忽略;
- 弹性盒子布局中,该属性被忽略;
- 栅格布局中,会将其栅格区域内的项目在其行内轴上对齐;
flex项排序
:弹性盒子也有可以改变 flex 项的布局位置的功能,而不会影响到源顺序(即 dom 树里元素的顺序)。这也是传统布局方式很难做到的一点。
属性 order
规定了弹性容器中的可伸缩项目在布局时的顺序。元素按照 order 属性的值的增序进行布局。拥有相同 order 属性值的元素按照它们在源代码中出现的顺序进行布局。
所有 flex 项默认的 order
值是0
。
语法:
order =
<integer>
示例:
.item1{
order: 5;
}
.item2{
order: 4;
}
.item3{
order: 3;
}
.item4{
order: 2;
}
.item5{
order: 1;
}
效果:
flex 嵌套
弹性盒子也能创建一些颇为复杂的布局。设置一个元素为 flex 项,那么他同样成为一个 flex 容器,它的孩子(直接子节点)也表现为弹性盒子。
示例:
参考嵌套弹性盒子
属性值 flex
与inline-flex
的区别
-
flex
: 将对象作为弹性伸缩盒显示。 -
inline-flex
:将对象作为内联块级弹性伸缩盒显示。
一句话来描述就是 当Flex Box 容器没有设置宽度大小限制时,当display
指定为 flex
时,FlexBox 的宽度会填充父容器,当display
指定为 inline-flex
时,FlexBox的宽度会包裹flex Item。
inlein-flex
效果:
flex
效果: