参考资料:http://c7sky.com/dive-into-flexbox.html
转载请注明出处:http://www.cnblogs.com/yansi/p/3335916.html
恩,这两日做了一个小小的项目,只需要做chrome上的效果就好,喜大普奔啊,果断就用上了仰慕已久的flexbox,弹性布局。
但是事实上,使用起来还是需要实现有一定的理解的,因为有的地方稍稍有些和传统布局不一样
恩,这篇文章是基于chrome的写法,firefox的话差不多,ie10和ie11可以在http://msdn.microsoft.com/zh-cn/library/ie/hh673531(v=vs.85).aspx找到相关资料,不过大体原理是一致的。
恩,先看下弹性布局的基础:
在这里有2个轴:
主轴:从左到右
侧轴:从上到下
请务必记住主轴副轴初始方向,因为轴位置和方向都是可变的
好了,现在我们开始第一步
display:-webkit-flex;display:flex;注意,早期版本的chrome(28及以前支持的版本)是使用前缀写法,但是最新的chrome(29)已经作为标准属性值了,包括相关的flexbox布局属性也删除了-webkit-前缀,这里需要注意下
开始我们第一个例子:类似float&inline-block效果
这样实现的效果很赞,既不用像float布局要清除浮动并且有一大堆bug,也不用像inline-block一样考虑最小字体(safari),哦,对了,我们管中间的蓝色小框叫“伸缩项目”,但是,如果我们需要
竖着布局
还记得上面提到的主轴侧轴吗?这里就是使用的时候了——flex-direction 伸缩流的方向,参数为:
-
- row-reverse: 主轴起点和主轴终点交换。如果书写模式是从左至右,伸缩项目则是从右往左显示。
- column: 主轴和侧轴交换。如果书写系统是垂直的,那么伸缩项目也是垂直显示的。
- column-reverse: 和 column 一样,但是方向相反。
- row:默认的,从左到右,从上到下
ps:书写方向可以改,direction:rtl就是显示是从右往左,类似float:right或者右对齐,文字排列还是从左到右的,不是从右往左读的,但是个人赶脚很鸡肋,没有真正改变文字排列,像古文一从上到下,从右到左这种功能不能实现
ps:要注意的是,这里改的不是伸缩项目的排列方向,而是主轴和侧轴方向,伸缩项目排列的方向是沿着主轴侧轴延伸的,所以如果主轴侧轴变换了位置,那么主轴对齐(justify-content)和侧轴对齐(align-items)所指的实际方向也会变换(对调),恩,别担心,下面会提到
多行布局
默认的情况下不论我们写多少的伸缩项目,都只有一行,因为伸缩项目会自动适应宽度,如果要换行的话——flex-wrap,参数:
- nowrap (默认)
- wrap
- wrap-reverse
wrap很简单,就是普通的换行,wrap-reverse的话是倒转侧轴(注意,在这里侧轴方向就被改变了),直接上例子吧(这是个普通换行的例子)
左排列,右排列,居中排列(主轴布局)
要实现主轴方向(默认是水平,从左到右)对齐——justify-content 主轴对齐,参数:
-
- flex-start (默认)
- flex-end
- center
- space-between:
- space-around
来个例子:
直接上图就很好解释了:
space-between:between的话会“顶左贴右”,第一个和最后一个伸缩项目分别贴着主轴的起点和终点,中间部分等价于center
space-around:around的话就是在between基础上在两边加上中间的空闲位置的一半;
上排列,下排列,基线排列(侧轴布局)
要实现侧轴方向(默认从上到下)排列——align-items&align-self&align-content
,参数:
- flex-start (默认)
- flex-end
- center
- baseline
- stretch
align-items的效果图:
然后再来个可以调戏的例子
恩,那我们还有一个align-self是做什么用的呢?就是覆盖align-items的,这个属性是添加给收缩项目的(目前提到的其他属性都是针对伸缩容器的,即包裹收缩项目外面的一层),属性和上面一样,多了个auto属性,auto就是不覆盖的意思,写上去没效果
再来个例子:
那么最后一个属性,align-content——它对齐的是伸缩行(主轴),这个属性只有在多行的情况下才起作用(换行需要 flex-wrap属性)
效果图:
属性值和之前一样,按照上面的模式写就好了
经典的垂直居中
在flexbox的布局模式中,很容易就实现了垂直居中,而且有2种方式:margin自动分配和主轴侧轴居中:
margin居中:
怎样?只需要margin:auto就可以做到垂直水平都居中,是不是很厉害啊?如果使用 align-items:center;justify-content:center;也可以实现哦,不过需要注意的是这个属性是加在伸缩容器上,不是加在伸缩项目上,要稍微注意下。
另一点需要注意的是,如果伸缩项目溢出伸缩容器的话,上面2种方式表现不一样:
前面是margin居中,后面的是justify-content:center居中模式(在参考资料中也有这图,但是配的说明文字是:align-self,解释下,默认情况下,algin-self是侧轴,我们需要先改变flex-direction:column,这时伸缩项目就是从上而下排布了,这时设置align-self:center就相当于给对应的伸缩项目水平居中了,表现的和默认的justify-content:center是一致的,只不过是只有这个伸缩项目才会有这个属性)。真正的居中行为可能更符合我们的预期(ps:为了实现可以溢出,需要添加flex:none属性,下面会提到,默认情况下,伸缩项目会自动伸缩,不会超出伸缩容器)
三栏布局神器:指定显示次序
曾几何时,我们需要实现
这种传统的三栏布局要使用负margin+float布局,麻烦要死不说,还有可能因为需求改动,一点点微调就要出一堆的bug,现在好了,有了——order属性,order属性可以直接指定显示的顺序,即使我们把article写在html内的第一位,我们依旧可以指定显示在nav之后,上个简单的例子:
更棒的是,nav,article,aside是等高的(align-items:stretch),而且因为自动伸缩的原因,article也会自动适应屏幕~~~
伸缩项目的伸缩性
前面我们提到了,伸缩项目一般而言都是会自动伸缩的,从而导致一个问题——如何控制伸缩项目的伸缩大小?如何使得伸缩项目不伸缩?有些情况下需要伸缩,有些情况不需要怎么办?
别急,我们将用到控制伸缩性的属性——flex
其实flex属性是3个属性的合体:flex: [flex-grow] [flex-shrink] [flex-basis],第一个控制有剩余空间的空间情况下如何伸缩,第二个控制溢出情况下如何伸缩,第三个控制基本宽度(ps:收缩方向都是主轴),比如上面的溢出情况(垂直居中的那个)实际上就是需要flex的第二个值为0,代表超出溢出之后就不会伸缩,而这个值默认是1,溢出之后会自动伸缩。我为了方便,直接设置了flex:none,
等价于:flex: 0 0 auto;宽度auto就是默认宽度,和display:inline-block类似,会自动缩小到需要用到的大小
常用的flex简略写法:
「flex: 0 auto
」 「flex: initial
」==「flex: 0 1 auto
」:不会自动延展,但是溢出时会自动收缩,
「flex: auto
」==「flex: 1 1 auto
」:完全自动延伸和收缩(像流水一样)
「flex: none
」==「flex: 0 0 auto
」:完全不能收缩,类似display:inline-block
「flex: <positive-number>
」==「flex: <positive-number> 1 0px
」:通过数值指定收缩比例,下面会举例子
最后一个值其实很好理解,就是为了实现按比例分布收缩空间的,直接上例子:
直接就是按比例分配,ps:使用了flex属性之后(准确说是[flex-basis],宽度将以[flex-basis]为准,而不是width,如果要用width,保持[flex-basis]为auto,这也是默认值)。而这个比例的基准是剩余空间,也就是说,如果有定宽的伸缩项目出现的话,这个剩余空间就是剩下的那部分
特别强调一下,flexbox布局的方向只有“主轴”,“侧轴”方向,是不分上下左右的。所以上面的伸缩性的拓展和收缩以及宽度都是在主轴方向的,如果主轴变成垂直的,那么这个“宽度”在页面上的表现就会成为”高度“,这点要非常注意。
最后的总结
和传统布局不一样,flexbox布局的时候并没有left,top,right,bottom这样的方向值,因为flexbox的方向都是以轴为基础的,都是”沿着主轴“,”沿着侧轴“,”逆着主轴“,”逆着侧轴“这样的属性(flex-start,flex-end,wrap-reverse等等),所以,大家在使用flexbox布局的时候一定要清楚自己的”轴“的状态,比如flex-wrap:wrap-reverse就会导致侧轴倒转方向,抛弃以往布局对方向的依赖,因为当轴改变之后,默认状态的”从左到右“”从上到下“就会改变,justify-content:flex-start;完全可以代表伸缩容器的上下左右的任意一个位置,所以,在使用flexbox的布局的时候一定要注意”轴“的状态