Flex知识小结

1,867 阅读8分钟

简介

flex布局是一种弹性布局,也可以把它理解为一种格式,使用了display:flex的div具有某种整体特质,就像word的格式刷,你刷了某种格式之后,相应的文档段落就具有了相同的特质:相同的字体样式、相同的字体大小、相同的行间距、相同的。。。flex布局也是这样,使用了display:flex的div称为flex容器,紧挨着该容器的子元素称为项目,这些项目的排列方式具有整体特质:排列方向、换行方式、每行的排列方式。。。是用flex的7个属性设置的。下图的框框是flex容器

flex 容器默认存在两根轴,主轴交叉轴,主轴是项目的排列方向,主轴确定之后,它90度的方向为交叉轴。默认情况,主轴是水平(row)的,也就是沿着水平方向排布的。当设置flex-direction:column时,主轴沿着垂直方向。当flex-direction含有reverse时,start和end交换位置。

Flex布局一共有7个样式属性,设置在flex容器上,分别是:

flex-direction: row | row-reverse | column |column-reverse
flex-wrap: nowrap| wrap | wrap-reverse
flex-flow: row wrap| ...
justify-content: flex-start | flex-end | center | space-between | space-around
align-items: flex-start | flex-end | center | baseline | stretch
align-content: flex-start | flex-end | center | space-between | space-around

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)row 默认

从左边向右依次排开(截图中红色框指空白部分)。

2)row-reverse

从右边向左依次排开。

3)column

从上边向下依次排开。

4)column-reverse

从下边向上依次排开。

2. flex-wrap

项目默认都排在主轴上,如果一行排不下,如何换行?可用flex-wrap属性设置。

  • nowrap: 不换行
  • wrap: 换行,第一行在上方
  • wrap-reverse: 换行,第一行在下方

1)nowrap

每个项目依次排开不换行(每个项目宽度固定时,按照宽度依次放置,如果项目过宽一行放不下,且内部元素不会撑开容器时,会导致压缩,如果内部元素撑开容器会出现滚动条,如果上个例子li的宽度改为600px,实际只有400++px , 压缩原因参考7.flex属性 )。

2)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)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)flex-start 默认

左对齐(默认)。

2)flex-end

右对齐。

3)center

居中。

4)space-between

两端对齐,项目之间的间隔都相等。项目与边框无间距。

5)space-around

每个项目两侧的间隔相等。项目之间的间隔比项目与边框的间隔大一倍。

5. align-items

align-items属性定义项目在交叉轴上如何对齐,即每一行项目高度不同时设置该属性改变布局。

  • flex-start: 交叉轴的起点对齐。
  • flex-end: 交叉轴的终点对齐。
  • center: 交叉轴的中点对齐。
  • baseline: 项目的第一行文字的基线对齐。
  • stretch(默认值): 如果项目未设置高度或设为auto,将占满整个容器的高度。

1)flex-start

交叉轴的起点对齐(在本例中是上对齐)。

2)flex-end

交叉轴的终点对齐(在本例中是下对齐)。

3)center

交叉轴的中点对齐(居中,面试垂直居中的一种方法)。

4)baseline

项目的第一行文字的基线对齐,本例给项目2增加padding-top,如下图,文字1/2/3对齐。

5)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)flex-start

与交叉轴的起点对齐。

2)flex-end

与交叉轴的终点对齐。

3)center

与交叉轴的中点对齐。

4)space-between

与交叉轴两端对齐,轴线之间的间隔平均分布。

5)space-around

每根轴线两侧的间隔都相等。所以,轴线之间的间隔比轴线与边框的间隔大一倍。

6)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

  1. flwx-basis定义了该元素的布局空白(available space)的基准值。
  2. flex-grow 若被赋值为一个正整数, flex 元素会以 flex-basis 为基础,沿主轴方向增长尺寸。
  3. 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-…

其他

  1. 设为 Flex 布局以后,子元素的 float、clear 和 vertical-align 属性将失效。

  2. 主轴的方向不一定是水平的,这个属性就是设置主轴的方向,主轴默认是水平方向,从左至右,如果主轴方向设置完毕,那么交叉轴就不需要设置,交叉轴永远是主轴顺时针旋转 90°。