之前的业务以移动端web app为主,页面结构基本上差不多,大概的思路是,横向流动布局,自动铺满宽度,纵向不做限定,由页面元素自上向下堆砌,然后在容器设置滚动就好了。其中,横向布局我花了点时间研究。
例如一个很常见顶栏组件,分左(按钮)中(标题)右(按钮)三个部分:
在不知道flex布局之前,我的方法是:中间铺满父元素,左右按钮做绝对定位,这样能够保持两边按钮组的定位,中间内容铺满,应付这种布局虽说不够严谨,但也能接受。
但是在处理下面这种表单的时候,这个布局就没用了:
首先,这个组件有着明确的边界区分,不能再像上面一样模糊边界,另外,左右两个元素宽度是不确定的,也就是说左边是“刚性的”,宽度由内容决定,而右边是“弹性的”,占据除了左边元素宽度以外的父元素的宽度,整个过程需要是自动的,无需手动改写结构和样式。这样的话,传统的定位和百分比就很难做到,为了适应这种布局,W3C推出了新的CSS属性:flex。
flex布局分两个部分,父元素设定子元素的布局规则,子元素决定自己的布局规则:
父元素:
display : flex//声明该父元素为弹性布局
flex-direction : row | row-reverse | column | column-reverse//控制子元素排列方向:从左到右(默认),从右到左,从上到下,从下到上
flex-wrap : nowrap | wrap | wrap-reverse//控制子元素换行情况:不换行(默认),换行(下一行在下方),换行(下一行在上方)
flex-flow : flex-direction||flex-wrap//direction和wrap的简写属性
justify-content : flex-start | flex-end | center | space-between | space-around//控制子元素的对齐方式(以从左到右为例):左对齐(默认),右对齐,居中,两端对齐,项目间间隔相等
align-items : flex-start | flex-end | center | baseline | stretch//控制交叉方向上(水平->垂直)的对齐方式,其中stretch为默认值,子元素将占满交叉方向的全部高度/宽度
align-content : flex-start | flex-end | center | space-between | space-around | stretch//当出现换行的时候,这个属性控制多行之间的对齐方式(与justify-content相似)
子元素:
order : number//控制排位顺序,数字越小越靠前(可以是负数)
flex-grow : number//控制放大比例
flex-shrink : number//控制缩小比例,与shrink类似
flex-basis : length|auto//控制元素弹性处理前的原大小,可设置为CSS的length属性,默认为auto
flex : flex-grow || flex-shrink || flex-basis//简写属性,默认为0 1 auto
align-self : auto | flex-start | flex-end | center | baseline | stretch//这个属性可以使当前子元素脱离父元素的对齐规则,单独设定自己的对齐规则
举个例子来说:
.wrap{display:flex;display:-webkit-flex;}
.div1{flex-grow:1;}
.div2{flex-grow:1;}
.div3{flex-grow:2;}
.div4{width:100px;}
首先父元素wrap设置display:flex,使其子元素进行弹性布局,其中子元素变为类似inline-block的状态,块级元素的默认with:100%会失效,float,clear,vertical-align也会失效。在上面这个水平(默认)布局当中,存在三个带grow属性的div,和一个固定宽度的div,这种情况,浏览器会先算出父元素宽度,然后减去固定宽度100px,再根据grow比例去分配剩下的宽度,总grow的和是1+1+2=4,则div1的宽度占据剩余宽度的1/4,div3占据1/2,如此类推(当grow属性设为0的时候,元素的宽度不会发生改变,当作固定宽度处理)。如果子元素中只有一个元素拥有grow属性且不为0,则该元素将占据剩余的所有宽度,说到这里,之前说到的表单布局问题就迎刃而解了:
.wrap{display:flex;display:-webkit-flex;}
.left{width:auto;}
.right{flex-grow:1;}
这个时候,左边的标题宽度将会根据标题的实际内容而改变,而右边的内容将会占据除了标题以外的所有宽度,实现弹性布局。
同样flex布局也可以用来优化上面的顶栏布局。