弹性布局flex
是一个几年前的CSS属性了,说它解放了一部分生产力不为过。至少解放了不少CSS布局相关的面试题 :)
之前网上流行的各种XX布局,什么postion: absolute
+margin
,float
+padding
,各种都可以使用flex
来取代之。
早两年在使用的时候,还是会担心有兼容性问题的,某些手机在使用了auto-prefixer
以后依然会出现不兼容的问题。
好在现在已经是2018年了,不必再担心那些老旧的设备,希望这篇文章能帮你加深对flex
的认识。
准备工作
首先,flex
被称为一个弹性盒模型,也有称弹性布局的。
总之,盒子也好、布局也罢,我们总是需要有一个容器Container
的:
<div class="container"></div>
以及如果单纯的只是一个容器的话,是没有任何意义的。
所以我们还需要有一些内容:
<div class="contianer"> <div class="item"></div> <div class="item"></div> </div>
下边的所有例子基本都是基于以上DOM结构来做的。
基本语法
现在我们已经有一个可以用来写flex
布局的html
结构。
接下来就是一个最基础的flex
布局的实现:
<style> .container { display: flex; height: 50px; color: #fff; border: 1px solid #03a9f4; } .item { flex: 1; text-align: center; background: #03a9f4; } </style> <div class="contianer"> <div class="item"></div> <div class="item"></div> </div>
我们在容器上使用display: flex
来告诉浏览器,这是一个flex
布局的开始。
然后给所有的item
添加一个flex: 1
的属性,来表明,我们这里边的元素都是flex
布局中的内容,
我们会沿着主轴来平分所有的区域,就这样,我们已经实现了一个多列等宽布局。
关于flex
,最重要的就是要记住他有两条轴线(主轴、交叉轴),绝大部分属性都是依赖于轴线的方向。
图片来自MDN
因为flex
布局分为了容器和内容两块,各自有各自的属性,所以就先从容器类的说起。
容器相关的flex属性
实现上边的需求,是依赖于很多默认属性值。
比如,为什么我们的子元素会横向的进行分割空间,而不是竖向的,这里就用到了一个属性的默认值:
flex-direction
flex-direction
用于定义flex
布局中的主轴方向。
默认取值为row
,是横向的,表示从左到右,也就是说我们的所有子元素会按照从左到右的顺序进行排列。
我们可以通过设置值为column
来改变主轴的方向,将其修改为从上到下。(改变flex-direction
的值会影响到一些相关的属性,会在下边说到)
flex-direction
共有四个有效值可选:
row
默认值,从左到右row-reverse
从右到左column
从上到下column-reverse
从下到上
P.S. 在React-Native中默认的主轴方向为column
所以说flex-direction
的作用就是:定义容器中元素的排列方向
flex-wrap
该属性用于定义当子元素沿着主轴超出容器范围后,应该按照怎样的规则进行排列。
该属性只有简单的三个取值:
wrap
超出主轴范围后换行显示,换行方向按照交叉轴的方向来(默认情况下就是折行到下一行)wrap-reverse
超出主轴范围后换行显示,但是方向是交叉轴的反向(也就是默认情况下第一行会出现在最下边)nowrap
即使超出容器也不会进行换行,而是尝试压缩内部flex元素的宽度(在下边的子元素相关的属性会讲到)
三种取值的示例:
flex-flow
flex-flow
是一个简写的属性,适用于上边提到的flex-direction
和flex-wrap
语法:
selector { flex-flow: <flex-direction> <flex-wrap>; }
justify-content
这个会定义我们的子元素如何沿着主轴进行排列,因为我们上边是直接填充满了父元素,不太能看出效果。
所以我们对代码进行如下修改:
<style media="screen"> .container { display: flex; width: 400px; color: #fff; border: 1px solid #03a9f4; } .item { /* flex: 1; */ width: 100px; text-align: center; background: #03a9f4; } </style> <div class="container"> <div class="item">Item 1</div> <div class="item">Item 2</div> <div class="item">Item 3</div> </div>
将所有的子元素都改为固定的宽度,也就是说,如果父元素有剩余空间的话,就会空在那里。
justify-content
的默认取值为normal
,也可以认为就是start
了,也就是根据主轴的方向(flex-direction
)堆在起始处。
几个常用的取值:
center
必然首选的是center
,能够完美的实现沿主轴居中flex-start
沿着主轴从行首开始排列flex-end
沿着主轴从行末开始排列
以及几个不太常用的取值:
space-between
将剩余空间在子元素中间进行平分,保证沿主轴两侧不会留有空白。space-around
将剩余空间均匀的分布在所有的子元素沿主轴方向的两侧,也就是说,主轴两侧也会有空白,但是必然是中间空白的1/2
大小。space-evenly
将剩余空间在所有元素之间平均分配,主轴两侧的空白面积也会与中间的面积相等。
六种效果的示例:
Warning
有一点需要注意,justify-content
的取值都是依照flex-direction
所定义的主轴方向来展示的。
也就是说,center
在默认情况下用于水平居中,在flex-direction: co