简介
flex 容器默认存在两根轴主轴(main axis): 默认水平,可通过设置flex-direction改变主轴方向。
交叉轴(cross axis): 默认垂直。
主轴的开始位置(与边框的交叉点)叫做main start,结束位置叫做main end;
交叉轴的开始位置叫做cross start,结束位置叫做cross end
项目默认沿主轴排列
单个项目占据的主轴空间叫做main size,占据的交叉轴空间叫做cross size。
复制代码
1. flex-direction
决定主轴的方向(即项目的排列方向)。
默认为row(水平轴),设置为column则为垂直轴。
当有reverse时,主轴起点和终点交换位置。
row
(默认值): 主轴为水平方向,起点在左端。row-reverse
: 主轴为水平方向,起点在右端。column
: 主轴为垂直方向,起点在上沿。column-reverse
: 主轴为垂直方向,起点在下沿。
对于下面的例子:
<!DOCTYPE html>
<html>
<head>
<title></title>
<style type="text/css">
ul{
display: flex;
flex-direction: row;
}
ul>li{
width:100px;
height:50px;
background:#ffff00;
border:1px red solid;
display: inline-block;
}
</style>
</head>
<body>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
</body>
</html>
复制代码
1)flex-direction: row
从左边向右依次排开(截图中红色框指空白部分)。
2)flex-direction: row-reverse
从右边向左依次排开。
3)flex-direction: column
从上边向下依次排开。
4)flex-direction: column-reverse
从下边向上依次排开。
2. flex-wrap
项目默认都排在主轴上,如果一行排不下,如何换行?可用flex-wrap属性设置。
nowrap
: 不换行wrap
: 换行,第一行在上方wrap-reverse
: 换行,第一行在下方
1)flex-wrap: nowrap
每个项目依次排开不换行(每个项目宽度固定时,按照宽度依次放置,如果项目过宽一行放不下,且内部元素不会撑开容器时,会导致压缩,如果内部元素撑开容器会出现滚动条,如果上个例子li的宽度改为600px,实际只有400++px , 压缩原因参考7.flex属性 )。
2)flex-wrap: wrap
依次排开,一行不够换行展示。
flex-wrap:wrap
类似浮动float(当flex-direction为row-reverse时,类似float:right
)。
与浮动有一点不同,flex布局每一行高度都是一行所有项目中最高项目的高度,即每一行高度一致,就像给每一行嵌套一个div,这个div嵌套的项目个数取决于设备,多么厉害的布局,这种布局防止页面错乱。
而float每个项目高度不同,可能会导致页面错乱。根据float
的定义,我们知道,它是浮在页面上方,换行时可能不是从页面最左侧开始排列,这取决于上一行最右边项目的高度和宽度等,而flex布局换行都是从最左侧排列。
下面用一个示例解释这个问题,把第1个项目高度改为60px(其他都是50px)。
flex布局示例:
<!DOCTYPE html>
<html>
<head>
<title></title>
<style type="text/css">
ul{
display: flex;
flex-direction: row;
}
ul>li{
width:100px;
height:50px;
background:#ffff00;
border:1px red solid;
display: inline-block;
}
ul>li:first-child{
height: 60px;
}
</style>
</head>
<body>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
</body>
</html>
复制代码
float布局示例:
<!DOCTYPE html>
<html>
<head>
<title></title>
<style type="text/css">
ul>li{
float: left;
width:400px;
height:50px;
background:#ffff00;
border:1px red solid;
display: inline-block;
}
ul>li:first-child{
height: 60px;
}
</style>
</head>
<body>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
</body>
</html>
复制代码
跟float的区别在下面两个图中可以看出来,flex的项目4在1下方,而float的项目4贴在2的下面。如果把项目1高度改为20px,两者没有差别。
3)flex-wrap: wrap-reverse
这个更厉害了,换行且第一行在最下面。我的理解是这样,我们往地上一点点放盒子(这些盒子高度可能不同),一行放满之后放一个挡板,在上面继续放盒子,而flex-wrap:wrap是从上面放,一行放不下时,放个挡板,第二行继续放。
3. flex-flow
flex-flow属性就是flex-direction和flex-wrap的简写形式,默认值为row nowrap。不再多解释。
.box {
flex-flow:row-reverse wrap;
}
复制代码
4. justify-content
justify-content 定义了项目在主轴上的对齐方式,即每一行的排布方式,当每个项目宽度都不相同时设置项目间隔和整体位置。
flex-start
(默认值): 左对齐flex-end
: 右对齐center
: 居中space-between
: 两端对齐,项目之间的间隔都相等。space-around
: 每个项目两侧的间隔相等。所以,项目之间的间隔比项目与边框的间隔大一倍。
1)justify-content: flex-start
左对齐(默认)。
2)justify-content: flex-end
右对齐。
3)justify-content:center
居中。
4)justify-content: space-between
两端对齐,项目之间的间隔都相等。项目与边框无间距。
5)justify-content: space-around
每个项目两侧的间隔相等。项目之间的间隔比项目与边框的间隔大一倍。
5. align-items
align-items属性定义项目在交叉轴上如何对齐,即每一行项目高度不同时设置该属性改变布局。
flex-start
: 交叉轴的起点对齐。flex-end
: 交叉轴的终点对齐。center
: 交叉轴的中点对齐。baseline
: 项目的第一行文字的基线对齐。stretch
(默认值): 如果项目未设置高度或设为auto,将占满整个容器的高度。
1)align-items: flex-start
交叉轴的起点对齐(在本例中是上对齐)。
2)align-items:flex-end
交叉轴的终点对齐(在本例中是下对齐)。
3)align-items:center
交叉轴的中点对齐(居中)。
4)align-items:baseline
项目的第一行文字的基线对齐,本例给项目2增加padding-top,如下图,文字1/2/3对齐。
5)align-items:stretch
如果项目未设置高度或设为auto,将占满整个容器的高度,我们试图把项目3设置height:auto,如下图,它会撑满整个高度,这个也十分有用。
6. align-content
定义了多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用。align-content类似justify-content,只不过justify-content定义主轴对齐方式,而align-content是定义交叉轴的对齐方式。
The align-items property will align the items on the cross axis.
复制代码
flex-start
: 与交叉轴的起点对齐。flex-end
: 与交叉轴的终点对齐。center
: 与交叉轴的中点对齐。space-between
: 与交叉轴两端对齐,轴线之间的间隔平均分布。space-around
: 每根轴线两侧的间隔都相等。所以,轴线之间的间隔比轴线与边框的间隔大一倍。- stretch(默认值): 轴线占满整个交叉轴。
下面所有示例把flex容器高度改为300px,结合上面说到的justify-content的示例,即可明白:
1)align-content:flex-start
与交叉轴的起点对齐。
2)align-content:flex-end
与交叉轴的终点对齐。
3)align-content:center
与交叉轴的中点对齐(面试垂直居中的一种方法)。
4)align-content:space-between
与交叉轴两端对齐,轴线之间的间隔平均分布。
5)align-content:space-around
每根轴线两侧的间隔都相等。所以,轴线之间的间隔比轴线与边框的间隔大一倍。
6)align-content:stretch(默认值)
轴线占满整个交叉轴。这个暂时没想到好的例子说明。
7. flex
设置flex属性,会根据属性的比例进行划分。
布局空白 available space,这几个 flex 属性的作用其实就是改变了 flex 容器中的布局空白的行为。
Where the flex-grow property deals with adding space in the main axis,
the flex-shrink property controls how it is taken away.
If we do not have enough space in the container to lay out our items and
flex-shrink is set to a positive integer the item can become smaller than the flex-basis.
复制代码
包含三个属性:flex-grow flex-shrink flex-basis
flwx-basis
定义了该元素的布局空白(available space)的基准值。flex-grow
若被赋值为一个正整数, flex 元素会以 flex-basis 为基础,沿主轴方向增长尺寸。flex-shrink
若被赋值为一个正整数, flex 元素会以 flex-basis 为基础,沿主轴方向jians尺寸。
flex预定义值:
flex: initial = flex:0 1 auto
flex: auto = flex:1 1 auto
flex: none = flex: 0 0 auto
flex: <positive-number>
复制代码
flex详解:www.w3.org/TR/2017/CR-…
其他
-
设为 Flex 布局以后,子元素的 float、clear 和 vertical-align 属性将失效。
-
主轴的方向不一定是水平的,这个属性就是设置主轴的方向,主轴默认是水平方向,从左至右,如果主轴方向设置完毕,那么交叉轴就不需要设置,交叉轴永远是主轴顺时针旋转 90°。