容器的属性
flex-direction
主轴和交叉轴 flex 布局是一种一维的布局,是因为一个 flexbox 一次只能处理一个维度的元素布局,一行或者一列。作为对比的是另外一个二维布局 CSS Grid Layout,可以同时处理行和列上的布局。
当使用 flex 布局时,首先想到的是两根轴线 — 主轴和交叉轴。主轴由 flex-direction 定义,另一根轴垂直于它。我们使用 flexbox 的所有属性都跟这两根轴线有关, 所以有必要在一开始首先理解它。
主轴和交叉轴由 flex-direction 定义,可以取4个值:
rowrow-reversecolumncolumn-reverse
当 flex-direction: row 的时候,
当 flex-direction: row-reverse 的时候,
当 flex-direction: column 的时候,
当 flex-direction: column-reverse 的时候,
总结一下:
flex-direction主要改变了主轴的方向,而交叉轴要么是从上到下,要么是从左到右的。
flex-wrap
flex-wrap 属性指定 flex 元素单行显示还是多行显示。如果允许换行,这个属性允许你控制行的堆叠方向。
nowrap默认取值,不换行,元素在一行显示wrap换行显示wrap-reverse换行显示,会使交叉轴开始和结束方向与wrap相反。
当 flex-direction: row; flex-wrap: wrap; align-items: flex-start; 的时候,
当 flex-direction: row; flex-wrap: wrap-reverse; align-items: flex-start; 的时候,
flex-wrap: wrap-reverse是唯一能改变了交叉轴开始、结束方向的设置。
flex-flow
flex-flow属性是flex-direction属性和flex-wrap属性的简写形式,默认值为row nowrap
.box {
flex-flow: <flex-direction> || <flex-wrap>;
}
justify-content
justify-content 属性定义了项目在主轴上的对齐方式。
如果主轴方向是从左向右,各属性的设置含义如下:
flex-start(默认值):左对齐flex-end:右对齐center: 居中space-between:两端对齐,项目之间的间隔都相等。space-around:每个项目两侧的间隔相等。所以,项目之间的间隔比项目与边框的间隔大一倍。
align-items
align-items属性定义项目在交叉轴上如何对齐。如果交叉轴方向是从上到下,各属性的设置含义如下:
flex-start:交叉轴的起点对齐。flex-end:交叉轴的终点对齐。center:交叉轴的中点对齐。baseline: 项目的第一行文字的基线对齐。stretch(默认值):如果项目未设置高度或设为auto,将占满整个容器的高度。
注意:当子元素设置了高度或者宽度的时候,align-items: stretch;会失效,也就是 height/min-height/max-height 优先级高于align-items: stretch;
.container{
display: flex;
flex-direction: row;
flex-wrap: nowrap;
align-items: stretch;
}
.item{
width: 100px;
height: 100px;
}
align-content
align-content属性定义项目在交叉轴上如何对齐;如果项目只有一根轴线,该属性不起作用。如果交叉轴方向是从上到下,各属性的设置含义如下:
flex-start:与交叉轴的起点对齐。flex-end:与交叉轴的终点对齐。center:与交叉轴的中点对齐。space-between:与交叉轴两端对齐,轴线之间的间隔平均分布。space-around:每根轴线两侧的间隔都相等。所以,轴线之间的间隔比轴线与边框的间隔大一倍。stretch(默认值):轴线占满整个交叉轴。
项目的属性
align-self
align-self属性允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性。默认值为auto,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch。用于设置单个项目在 交叉轴 上的对齐方式。
.container{
display: flex;
flex-direction: row;
flex-wrap: nowrap;
align-items: flex-start;
}
.item:nth-child(1){
align-self: flex-end;
}
flex-grow
flex-grow 表示在主轴方向上,如果子项目的宽度和(或者高度和)并没有完全占满 flex 父容器的宽度,父容器剩余宽度将如何分配。flex-grow 默认是0,即不拉伸子容器,即使父容器没有被占满,如下:
.container{
width: 550px;
height: 250px;
border: 5px solid silver;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
align-items: flex-start;
}
.item{
width: 100px;
height: 100px;
background-color: blueviolet;
}
flex-grow 一般取数字,表示占分配父容器剩余宽度(高度)的份数,如下:
.item:nth-child(1){
flex-grow: 1
}
.item:nth-child(2){
flex-grow: 2
}
.item:nth-child(3){
flex-grow: 2
}
表示如果父容器宽度还有剩余,则第一个元素占 1 份,第二个元素占 2 份,第三个元素占 2 份。计算如下:
父元素剩余宽度:550 - 100 - 100 - 100 = 250
总份数:1 + 2 + 2 = 5
每份占的宽度:250/5 = 50
第一个子元素宽度:50*1 + 100 = 150
第二个子元素宽度:50*2 + 100 = 200
第三个子元素宽度:50*2 + 100 = 200
flex-shrink
flex-shrink 表示在主轴方向上,如果子项目的宽度和(或者高度和)超过 flex 父容器的宽度,子项目会不会缩小。flex-shrink 默认为1,即如果空间不足,该项目将缩小。
.container{
width: 550px;
height: 250px;
border: 5px solid silver;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
align-items: flex-start;
}
.item{
width: 200px;
height: 100px;
}
.item:nth-child(1){
flex-shrink: 1
}
.item:nth-child(2){
flex-shrink: 2
}
.item:nth-child(3){
flex-shrink: 2
}
表示如果父容器被超过时,则第一个元素缩小占 1 份,第二个元素缩小占 2 份,第三个元素缩小占 2 份。计算如下:
父元素超过的宽度:200 + 200 + 200 - 550 = 50
每份占的宽度:50/(200*1 + 200*2 + 200*2) = 0.05
第一个子元素宽度:200 - 1*0.05*200 = 190
第二个子元素宽度:200 - 2*0.05*200 = 180
第三个子元素宽度:200 - 2*0.05*200 = 180
flex-basis
flex-basis属性定义了在分配多余空间之前,项目占据的主轴空间(main size)。浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为auto,即项目的本来大小。
优先级:
min-width/max-width>flex-basis>width
.item{
width: 200px;
height: 100px;
}
.item:nth-child(1){
flex-basis: 50px;
}
.item:nth-child(2){
flex-basis: 50px;
min-width: 100px;
}
.item:nth-child(3){
flex-basis: 150px;
max-width: 100px;
}
flex
flex属性是flex-grow, flex-shrink 和 flex-basis的简写,默认值为0 1 auto。后两个属性可选。
.item {
flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
}
该属性有两个快捷值:auto (1 1 auto) 和 none (0 0 auto)。
建议优先使用这个属性,而不是单独写三个分离的属性,因为浏览器会推算相关值。
面试常问:flex: 1 什么含义?
在 Chrome 浏览器下:
order
order属性定义项目的排列顺序。数值越小,排列越靠前,默认为0。
.container{
width: 550px;
height: 550px;
display: flex;
flex-direction: column;
}
.item{
width: 200px;
height: 100px;
}
.item:nth-child(1){
order: 1
}
一些技巧
margin 自动撑满
实现头像靠右对齐,可以利用 flex 弹性布局 + margin 实现:
.container{
width: 850px;
display: flex;
align-items: center;
}
.item{
width: 200px;
height: 80px;
line-height: 80px;
}
.circle{
width: 50px;
height: 50px;
border-radius: 50%;
margin-left: auto; // 关键代码
}
<div class="container">
<div class="item">首页</div>
<div class="item">菜单1</div>
<div class="circle"></div>
</div>
水平垂直居中
.container{
display: flex;
justify-content: center;
align-items: center;
width: 300px;
height: 200px;
border: 1px solid black;
}
<div class="container">文本居中</div>
栅格平分
左右间距是 10px,距离下面边距也是 10px;元素一行 4 个,所以宽度是 25%。
<style>
.container{
width: 900px;
display: flex;
flex-wrap: wrap;
border: 1px solid black;
padding-bottom: 10px;
}
.item{
width: 25%;
padding: 0 10px;
margin-top: 10px;
box-sizing: border-box;
display: flex;
justify-content: center;
align-items: center;
}
.search{
width: 100%;
}
</style>
<body>
<div class="container">
<div class="item"><input class="search" /></div>
<div class="item"><input class="search" /></div>
<div class="item"><input class="search" /></div>
<div class="item"><input class="search" /></div>
<div class="item"><input class="search" /></div>
</div>
</body>
</html>
参考推荐:
Flex 布局教程:语法篇
原来flex布局还能那么细?