Flexbox 是 flexible box 的简称(意思是“灵活的盒子容器”),是 CSS3 引入的新的布局模式。它决定了元素如何在页面上排列,使它们能在不同的屏幕尺寸和设备下可预测地展现出来。
它之所以被称为 Flexbox ,是因为它能够扩展和收缩 flex 容器内的元素,以最大限度地填充可用空间。与以前布局方式(如 table 布局和浮动元素内嵌块元素)相比,Flexbox 是一个更强大的方式:
- 在不同方向排列元素
- 重新排列元素的显示顺序
- 更改元素的对齐方式
- 动态地将元素装入容器
什么情况下不建议使用 Flexbox ?
- 整体页面布局
- 完全支持旧浏览器的网站
浏览器支持 Flexbox 的情况:
旧版浏览器,如IE11或更低版本,不支持或仅部分支持 Flexbox 。如果你想安全的使用页面正常呈现,你应该退回到其他的 CSS 布局方式,比如结合float
的 display: inline-block
或者 display: table
等。但是,如果您只针对现代浏览器,那么 Flexbox 绝对值得一试。
进入flex学习:
在 Flexbox 模型中,有三个核心概念:
– flex 容器,其包含 flex 项
– flex 项(也称 flex 子元素),需要布局的元素
– 排列方向(direction),这决定了 flex 项的布局方向
基本步骤:
1.在父盒子中设置这个盒子为弹性盒:display:flex;
2.在父盒子中设置子盒子排布的主轴方向(默认:水平 从左到右 ;垂直 从上到下):
flex-direction:row(默认)/row-reserve/column/column-reserve
3.子盒子占父盒子的空间比例:flex:number;
4.子盒子的排列顺序 :order:number;(默认从左到右,number越小越靠前)
display: flex;
三个子元素left、center、right,
若left、right设定了固定宽度px,center设定了flex:1,那么center元素会占据剩余的所有空间
flex: 1; 等同于 flex: 1 1 0%;含义是项目在容器有多余空间的时候会拉伸、项目在容器没有空间的时候会缩小、项目本身尽量占较小的空间显示。
flex: 0; 等同于 flex: 0 1 0%; 含义是即使容器有多余空间项目不会拉伸、项目在容器没有空间的时候会缩小、项目本身尽量占较小的空间显示。所以“普通人类”文本换行显示,尽量占较小的空间。
flex: none; 等同于 flex: 0 0 auto; 含义是即使容器有多余空间项目不会拉伸、即使容器没有空间也不会缩小、项目本身 auto 显示。
flex: auto; 等同于 flex: 1 1 auto; 含义是容器有多余空间的时候会拉伸、项目在容器没有空间的时候会缩小、项目本身 auto 显示。
总结:项目本身的宽度以及是否拉伸或者缩小,跟 flex-grow flex-shrink flex-basis width max-width min-width 都是有关的,不能单单根据其中的一项或者两项去计算,而要根据flex-grow flex-shrink flex-basis width max-width min-width 一起计算。整体而言,flex-grow 控制容器有多余空间项目是否会拉伸;flex-shrink 控制容器空间不够项目是否会缩小;而 flex-basis 控制项目本身的宽度,浏览器根据这个属性,计算主轴是否有多余空间,flex-basis: 0; 项目会尽量占较小空间显示。flex-basis: auto; 本身大小显示。
注意问题:
Flex 布局会默认:
- 把所有子项变成水平排列。
- 默认不自动换行。
- 让子项与其内容等宽(子项flex:number;设定子项占父的宽度),并把所有子项的高度变为最高子项的高度。项目没有设置高度,或者高度为 auto 时,align-items: stretch; 会拉伸项目,高度占满容器。
flex-grow:0; 空间多子项不会被拉伸
flex-shrink:1; 空间不够子项会被缩放
flex-basis:auto; 项目本身的大小
这样设置背景色的时候非常不方便,那么直接在父项上,将align-items设为 flex-start,或者align-items属性的其他值都可以,子项就会保持自身的高度了。
.fat{
display: flex;
align-items: flex-start;
}
基础
1)创建一个 flex 容器(父)
<style>
.flex{
display: flex;
background-color: pink;
}
.flex-item1{
background-color: green;;
}
.flex-item2{
background-color: aqua;;
}
.flex-item3{
background-color: azure;
}
</style>
</head>
<body>
<div class="flex">
<div class="flex-item1">1</div>
<div class="flex-item2">2</div>
<div class="flex-item3">3</div>
</div>
要创建一个 flex 容器,您只需要将一个 display: flex
属性添加到一个父元素上。默认情况下,所有的直接子元素都被认为是 flex 项,并从左到右依次排列在一行中。如果 flex 项的宽度总和大于容器,那么 flex 项将按比例缩小,直到它们适应 flex 容器宽度。
2)flex-direction 定义了 flex 容器中 flex 子项的排列方向
.flex{
display: flex;
/* 将 flex 项排成一列(主轴方向)*/
flex-direction: column;
background-color: pink;
}
可以通过(在 flex 容器中)设置 flex-direction: column
使 flex 项垂直布局。也可以通过设置 flex-direction: column-reverse
或 flex-direction: row-reverse
来使 flex 项以相反的顺序排列。
.flex{
display: flex;
/*flex-direction: column;*/
flex-direction:column-reverse;
background-color: pink;
}
3) justify-content 定义了 flex 容器中 flex 子项在主轴方向上对齐方式以处理空白部分。默认值为 flex-start
justify-content:flex-start(以容器开始的位置对齐即左对齐 默认)
justify-content:center(居中对齐)
justify-content:flex-end(以容器结束的位置对齐即右对齐)
.flex{
display: flex;
justify-content: flex-end;
background-color: pink;
}
回想一下,每个 Flexbox 模型都有 flex 方向(主轴)。justify-content
用于指定 flex 项在 flex 方向(direction)上的对齐位置。在上面的例子中,justify-content:flex-end
表示 flex 项在水平方向上靠 flex 容器的末端对齐。这就是为什么他们被放在了右边。
3.1)铺开的 flex 项
可以通过使用以下 justify-content
属性的三个间距值之一来指定容器中 flex 项之间应显示多少空间:
space-evenly
: flex 容器起始边缘和第一个 flex 项之间的间距和每个相邻 flex 项之间的间距是相等。(愚人码头注:该属性以前很少看到,原因是以前浏览器不支持,chrome 也是 60 版本之后才支持。延伸一下,align-content: space-evenly
也是这个逻辑,建议在 chrome 60 下查看 这个demo 。 )space-between
: 任何两个相邻 flex 项之间的间距是相同的,但不一定等于第一个/最后一个 flex 项与 flex 容器边缘之间的间距;起始边缘和第一个项目之间的间距和末端边缘和最后一个项目之间的间距是相等的。space-around
: flex 容器中的每个 flex 项的每一侧间距都是相等的。请注意,这意味着两个相邻 flex 项之间的空间将是第一个/最后一个 flex 项与其最近边缘之间的空间的两倍。
4)justify-items 用于控制网格容器中的网格项目在其网格单元格中的水平对齐方式
justify-items 的常见属性
start:将网格项目的内容对齐到网格单元格的起始位置。
end:将网格项目的内容对齐到网格单元格的末尾位置。
center:将网格项目的内容对齐到网格单元格的中间位置。
stretch:将网格项目的内容水平拉伸以填充整个网格单元格的宽度。
baseline:将网格项目的基线与网格单元格的基线对齐。
5)align-items 定义了 flex 容器中 flex 子项在纵轴方向上对齐方式以处理空白部分。默认值为 stretch
align-items:center/flex-start/flex-end;flex 子项在交叉轴上(侧轴/垂直)的对齐方式
<style>
.flex{
display: flex;
justify-content: center;;
align-items: center;
background-color: pink;
}
.flex-item1{
background-color: green;
height: 30px;
}
.flex-item2{
background-color: aqua;
height: 50px;
}
.flex-item3{
background-color:indianred;
height: 100px;
}
</style>
</head>
<body>
<div class="flex">
<div class="flex-item1">1</div>
<div class="flex-item2">2</div>
<div class="flex-item3">3</div>
</div>
</body>
通常,我们想沿着 flex 方向(主轴)排列 flex 项,还可以在垂直于它的方向(交叉轴)上对齐 flex 项。通过设置 justify-content:center
和align-items:center
,可以使 flex 项水平和垂直放置在 flex 容器的中心。
6)place-items 这个属性是 align-items
和 justify-items
属性的简写形式。如果未提供第二个值,则第一个值将作为第二个值的默认值。
基本用法
place-items 属性可以接受以下类型的值:
- 关键字值:如 normal、stretch、center、start、end、self-start、self-end、flex-start、flex-end、left、right、baseline、first baseline、last baseline 等。这些值用于指定元素的对齐方式。
- 全局值:如 inherit、initial、unset 等,这些值可以应用于任何 CSS 属性。
place-items: <align-items> <justify-items>?;
.container {
display: flex;
place-items: center; /* 水平和垂直方向都居中 */
}
7)align-self 对齐某个特定的 flex 子项在侧轴的对齐方式(某子元素参照父元素设定的方式对齐)
align-self 属性允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性。默认值为auto,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch。
align-self:flex-end/center/flex-start
.flex-item1{
background-color: green;
height: 30px;
align-self: flex-end;
}
8)align-content 在存在多行或多列时,控制各行(各列)之间的对齐方式
.box { align-content: flex-start | flex-end | center | space-between | space-around | stretch; }
9)order属性
order属性定义flex子项的排列顺序。数值越小,排列越靠前,默认为0。
.item {
order: <integer>;
}
中级
1)允许 flex 子项多行/列排列(同一行放不下的时候,将溢出的子项自动放在下一行)
flex-wrap:wrap/nowrap(默认)/wrap-reverse
<style>
.flex{
display: flex;
flex-wrap: wrap;
}
.flex div{
width: 270px;
}
.flex-item1{
background-color: green;
}
.flex-item2{
background-color: aqua;
}
.flex-item3{
background-color:indianred;
}
</style>
</head>
<body>
<div class="flex">
<div class="flex-item1">1</div>
<div class="flex-item2">2</div>
<div class="flex-item3">3</div>
<div class="flex-item2">2</div>
<div class="flex-item3">3</div>
</div>
默认情况下, flex 项不允许多行/列排列,如果 flex 容器尺寸对于所有 flex 项来说不够大,那么flex 项将被调整大小以适应单行或列排列。
通过添加 flex-wrap: wrap
,可以将溢出容器的 flex 项将被排列到另一行/列中
flex 项反向多行/列排列
flex-wrap: wrap-reverse;
flex-wrap:wrap-reverse
仍然使 flex 项以多行/列排列,但是它们从 flex 容器的末尾开始排列的。
2)多列排列的 flex 子项在交叉轴上的对齐方式
默认情况下,当 flex 容器的交叉轴(cross axis)上存在多余空间时,您可以在 flex 容器上设置 align-content
,以控制 flex 项在交叉轴(cross axis)上的对齐方式。可能的值是 flex-start
,flex-end
,center
,space-between
,space-around
,space-evenly
和 stretch
(默认)。
.flex{
display: flex;
flex-wrap: wrap-reverse;
justify-content: space-evenly;
align-content: flex-end;
}
3)flex-flow:<flex-direction> || <flex-wrap>
flex-flow属性是flex-direction属性和flex-wrap属性的简写形式,默认值为row nowrap。
.box {
flex-flow: <flex-direction> || <flex-wrap>;
}
高级
1)flex-grow
拉伸 flex 子项
flex-grow
只有在 flex 容器中有剩余空间时才会生效。flex 项的 flex-grow
属性指定该 flex 项相对于其他 flex 项将拉伸多少,以填充 flex 容器。默认值为0。当设置为 0
时,该 flex 项将不会被拉伸去填补剩余空间。在这个例子中,两个项的比例是 1:2,意思是在被拉伸时,第一个 flex 项将占用 1/3,而第二个 flex 项将占据余下的空间。
这里特别要注意的是 flex-grow
控制的是 flex 项的拉伸比例,而不是占据 flex 容器的空间比例。(注意与flex进行区分)
<style>
.flex{
display: flex;
flex-wrap: wrap-reverse;
justify-content: space-evenly;
align-content: flex-end;
}
.flex div{
width: 270px;
}
.flex-item1{
background-color: green;
flex-grow: 1;
}
.flex-item2{
background-color: aqua;
flex-grow: 2;
}
.flex-item3{
background-color:indianred;
}
</style>
</head>
<body>
<div class="flex">
<div class="flex-item1">1</div>
<div class="flex-item2">2</div>
<!--<div class="flex-item3">3</div>-->
<!--<div class="flex-item2">2</div>-->
<!--<div class="flex-item3">3</div>-->
</div>
2)flex-shrink 子项
收缩元素
flex-shrink
只有在 flex 容器空间不足时才会生效。它指定 flex 项相对于其他 flex 项将缩小多少,以使 flex 项不会溢出 flex 容器。 默认值为 1
。当设置为0
时,该 flex 项将不会被收缩。在这个例子中,比例是1:2,意思是在收缩时,第一项将收缩 1/3 ,而第二个项目将被收缩 2/3 。愚人码头注: flex-shrink
和 flex-grow
正好相反
3)flex-basis
设置元素的大小
可以使用 flex-basis
定制 flex 项尺寸来代替元素的初始大小。默认情况下,其值为 flex-basis: auto 项目本身的大小
,这意味该尺寸着从非 Flexbox CSS规则计算的。您还可以将其设置为某个绝对值或相对于 flex 容器百分比的值;例如 flex-basis:200px
和flex-basis:10%
。
min-width/max-width > flex-basis > width
flex-basis 设置宽度的优先级肯定是高于 width,即使 width 设置在 flex-basis 之后。
当 flex-basis 比 min-width 小的时候,项目表现 min-width 的值;否则表现 flex-basis 的值。
当 flex-basis 比 max-width 大的时候,项目表现为 max-width 的值,否则表现为 flex-basis 的值。
4)将 flex-grow, flex-shrink, 和 flex-basis 放在一起(flex:拉伸 收缩 元素大小;默认值为0 1 auto)
flex
是 flex-grow
,flex-shrink
和 flex-based
的缩写。在这个例子中,第一个 flex 项设置为flex-grow: 1
,flex-shrink: 0
,flex-basis: 100px
,第二个 flex 项设置为flex-grow: 2
,flex-shrink: 0
,flex-basis: 10%
。
如果用这种缩写形式:flex:number;值为数字表示所占容器的比例,自适应的将容器占满。
flex:1
= flex: 1 1 0%;
在父元素尺寸不足的时候,会优先最小化内容尺寸。
flex:3
= flex: 3 1 0%;
flex:0
= flex: 0 1 0%;
通常表现为内容最小化宽度
.flex-container {
display: flex;
}
.flex-item:nth-of-type(1) {
flex: 1 0 100px;
}
.flex-item:nth-of-type(2) {
flex: 2 0 10%;
}
案例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.flex{
display: flex;
flex-direction: column;
flex-flow: wrap;
background-color: pink;
}
.flex-item1{
background-color: green;
height: 30px;
align-self: flex-start;
order: 3;
flex: 1;
}
.flex-item2{
background-color: aqua;
height: 50px;
align-self: flex-end;
order: 1;
flex: 2;
}
.flex-item3{
background-color:indianred;
height: 100px;
order: 2;
flex: 3;
}
</style>
</head>
<body>
<div class="flex">
<div class="flex-item1">1</div>
<div class="flex-item2">2</div>
<div class="flex-item3">3</div>
</div>
</body>
</html>
flex
属性属性有两个快捷值:
- auto (1 1 auto) :自动放大与缩小,在父元素尺寸不足的时候,会优先最大化内容尺寸。
- none (0 0 auto):不自动放大与缩小,元素没有弹性,通常表现为
内容最大化宽度
建议优先使用这个属性,而不是单独写三个分离的属性,因为浏览器会推算相关值。
总结
-
flex:1 & flex:auto 的区别主要体现在 =>在充分分配父元素宽度的情况下,子元素是优先扩展(auto)自己的尺寸还是优先减小(1)自己的尺寸
-
flex:0 & flex: none 的区别主要体现在 =>不考略父元素宽度的情况下,最大化内容宽度(none)还是最小化内容宽度(0)
-
对于不同的使用场景,我们应该使用不同的flex。比如flex:1多用于等分布局中,flex:auto多用于内容动态适配中,flex:none多用于元素内容最大化处理
响应式案例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
* {margin: 0; padding: 0;}
.flex{
display: flex;
flex-direction: column;
flex-flow: wrap;
background-color: pink;
}
.flex-item{
/* flex-grow: 1; 优先级高于 flex-basis */
flex-grow: 1;
flex-basis: 200px;
border: 1px solid #000;
}
</style>
</head>
<body>
<div class="flex">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
<div class="flex-item">3</div>
<div class="flex-item">3</div>
<div class="flex-item">3</div>
</div>
</body>
</html>
如有不足请多多指教!希望给您带来帮助!