移动端布局神器-Flex

准备写着这篇博客很久了,最近两个月都在公司实习,都没空搭理博客了:(。这两个月在公司实习学习了很多移动web相关的知识点,有空从了wiki里面搬出来。

言归正传, 为什么要强调移动端呢,这是因为flex(弹性盒布局)是css3提出的新属性,所以应用到PC端可能并不太适用。Flex布局,可以简便、完整、响应式地实现各种页面布局,为盒状模型提供最大的灵活性

如果使用flex

需要使用flex布局的时候,我们只需要在其父元素上设置他的display属性即可,下面是新旧flex的使用介绍:

  • display:box,或者是一个属性box-*;那么你看到的是2009年以前的Flexbox
  • display:flexbox,或者是一个函数flex(),那么你看到的是2011这个中间版本的Flexbox。(很少用到)
  • display:flex,或者其他flex-*的属性,那么你看到的是当前最新的规范

新旧flex属性千万不要混用,不然问题很奇葩。

flex有这不同的三个版本自然而然也会有他的兼容性问题。具体兼用性可以上Can I use查询。这里主要说一下弹性盒子布局在移动端的兼容情况:安卓4.4以后才支持了较新的用法,所以说在iOS和Android浏览器中,可能老版语法的flex仍应用广泛。

常用属性介绍

flex相关的属性很多,具体应用还得多查一下api,下面我就罗列两个常见的用法。

以下内容给出的都是老版本的用法,以及新版的属性名称。新版本提供的属性更为丰富。

box-flex/flex

作用在子元素上,设置子元素按照什么样的比例分配父元素空间。

html结构如下:

1
2
3
4
5
6
<ul class="box">
<li>我占剩余空间1分</li>
<li>我占剩余空间1分</li>
<li>我占剩余空间2分</li>
<li>我占100px</li>
</ul>

使用flex来实现上面的需求

1
2
3
4
.box li:nth-child(1){box-flex:1;}
.box li:nth-child(2){box-flex:1;}
.box li:nth-child(3){box-flex:2;}
.box li:nth-child(4){width:100px;}

box-align/align-items

作用在父元素上,来设置子元素是顶部对齐还是底部对齐等问题。可以通过box-align:stretch来解决经典问题:如何设置所有子元素高度一致的问题。

  • start:设置伸缩盒对象的子元素从开始位置对齐
  • center:设置伸缩盒对象的子元素居中对齐
  • end:设置伸缩盒对象的子元素从结束位置对齐
  • baseline:设置伸缩盒对象的子元素基线对齐
  • stretch:设置伸缩盒对象的子元素自适应父元素尺寸

box-pack/justify-content

作用在父元素上,用来实现子元素的左对齐,右对齐,分散对齐等方式。

  • start:设置伸缩盒对象的子元素从开始位置对齐
  • center:设置伸缩盒对象的子元素居中对齐
  • end:设置伸缩盒对象的子元素从结束位置对齐
  • justify:设置或伸缩盒对象的子元素两端对齐

还有很多属性,就不一一介绍了,用到的时候可以多看一下文档。其实当你用熟了之后,你会发现多种属性组合起来就会很方便的实现水平垂直居中等效果

小技巧-解决旧版本flex不平均分现象

问题来源:如果我们想要子元素等分父元素空间,我们只要在父元素上设置flex布局后,在每个子元素上都设置flex的伸缩比为同一个值就ok了。但是当某一子元素的内容较多,等分给他的空间不够时,他的宽度会变大,其他元素会缩小。这就不是我们想要的效果。 示例如下:

1
2
3
4
5
<div class="box">
<div class="content-normal">A我是第一个div</div>
<div class="content-normal">B</div>
<div class="content-normal">C</div>
</div>

下面是css样式,我们把父元素的空间设置的比较小

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
.box{
display: box;
display: -webkit-box;
width: 150px;
height: 50px;
border: 1px solid #000;
}
.content-normal{
box-flex:1;
-webkit-box-flex:1;
/*width: 1%;*/ // 解决旧版本flex不均分的问题
border: 1px solid blue;
margin: 5px;
}

我们可以看到,第一个div占据很宽的位置,而其余两个空间都被压缩了。
flex不等分情况
这其实并不是我们想要的,解决这个问题办法就是在每个子元素上设置一个相同的宽度即可。

这个问题只有在旧版本的flex布局上会出现。如果你使用新版本的flex,其实你会发现,新版本已经提供了其余两个参数来解决flex布局收缩问题。

这是新版的参数,可以好好研究一下:flex:none | <’ flex-grow ‘> <’ flex-shrink >’? || <’ flex-basis ‘>

flex布局兼容性写法

考虑到要兼容新旧版本,新旧版本的flex都得用,写法上就出现了分歧,到底要怎么写才合理呢?与小组讨论了一下这个问题,得出下面结论(可能并不对,仅供参考):

  • 移动端大多是webkit内核,所以需要加上webkit厂商前缀
  • 兼容安卓4.4以前的版本
  • 最标准的写法放到后面
    这样子的话能够兼容到绝大部分的移动浏览器,浏览器会根据自身情况解析自己认识的写法。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    .box{
    display: -webkit-box; // 兼容安卓4.4以下
    display: -webkit-flex; // 新版本加厂商前缀
    display: flex; // 标准写法
    }
    .child{
    -webkit-box-flex:1;
    -webkit-flex:1;
    flex:1;
    }

总结

总之一句话,移动端用flex相当合适,布局方便、简洁。从此布局更轻松了。

参考资料
其他资料倒没有,推荐瑶姐的css参考手册,不会就去上面查:http://css.doyoe.com/