FLEX布局的⼀些问题和解决⽅法
前⾔
露珠最近研究了⼀下flex的布局⽅式,发现项w3c推出的这套布局解决⽅案对于⽇益复杂的前端开发布局来说是确实是⼀利器,并且在不同的屏幕上实现了真正的响应式布局:不再单纯地依赖百分⽐和float的强拼硬凑来达到设计需求,在各个屏幕上显⽰效果友好,弹性的伸缩元素,简洁易维护的代码。只可惜,这位⽼兄有⼀位致命的缺点----除了chrome外⼏乎所有⼿机上浏览器都没有兼容它!!,或者⽀持程度⼤不⼀样!这样开发⼈员头疼的问题就来了,刚刚在⼿机上忽略掉IE这个强盗的兼容问题,⼜来⼀个?!。flex的优势那么多,但是如果浏览器不兼容的话也是没法⼦⽤的。很多⼈会选择放弃它。在最初⾯对这样的问题的时候我是拒绝的,他们说要加兼容特技,我说我不⽤,还是absoute布局爽。但是!duang⼀下,露珠怀着⼈不学不知义的想法,想到google旗下产品(chrome、安卓等)在前端界的地位,相信不久各⼤浏览器⼚商都会像标准靠齐。所以flex是要学习的,不过在这之前我们可以⽤替代⽅案解决它。本篇⽂章将对新(felx)旧(flex-box)两种布局⽅式对⽐。由于⽹上关于flex布局⽅式的介绍已经很多,本⽂不会对flex做详细介绍,主要分享⼀下⽤旧⽅式(box)解决flex移动端的兼容问题。⾸先我们写⼀个flex的例⼦,展⽰⼀下他的部分属性。
⼀个⼩⽰例
⼿机端⼀张卡⽚列表,⾼度100像素,全屏宽,左边圆⾓图⽚(box1),中间三⾏介绍,上中下均分卡⽚⾼度,中间(box2)⾃适应分配剩余长度,最右边按钮(box3)。我们分别⽤⼏个盒⼦代表定位的元素来简单实现该需求。HTML结构的代码如下:
<div class="box">
<div class="box1">red</div>
<div class="box2">
<div class="item1">green</div>
<div class="item2">blue</div>
<div class="item3">gray</div>
</div>
<div class="box3">orange</div>
</div>
实现效果⼤概是下⾯那样的:
普通定位的实现
思路⼤概是这样的:由于要实现中间的盒⼦box2长度适应拉伸,百分⽐是不可以做到的。所以采⽤box1和box3绝对定位,box2不设置宽度,分别设置左边距(box1的宽度+box1到外框的宽度+box1到box2的间距)和右边距(box3宽度+box3到外框的宽度+box3到box2的间距);由于三个box都需要垂直居中,所以为最外⾯的box设置⼀个百分⽐padding,即使如此也很难再外框⾼度拉伸的时候让所有元素垂直居中。况且每个盒⼦的⾼度是固定(不是按照百分⽐)的⽽且是不⼀样的。所以这样的⽅式只能只有尽可能的接近效果,前提是外框⾼度不变情况下。如果需要垂直居中,可以⽤table布局,但是,诸位并不像因为⼀个这样的居中属性⽽去改变整个块的布局⽅式吧?⾄于⾥⾯的三块⼦盒⼦,则是按照外边距来平均分布在box2中,下⾯是⼤概的伪代码,不全列出来:
.box {
position: relative;/*外框定位*/
padding: x% 0;
}
.box1 {
position: absolute;
left: 10px;
}
.box2 {
padding-left: box1.width + box1.left + box2.margin-left;/*box2的左内边距*/
padding-right: box3.width + box3.right + box2.margin-right;/*box的右边距*/
}
.box2.div{
margin-bottom: x%;/*box2内的元素排列*/
}
.
box3 {
position: absolute;/*外框定位*/
right: 10px;/*外框定位*/
}
⽤普通的⽅式最难解决的是⾼度适应的问题,也就是在⾼度固定时元素垂直居中的问题。其次是中间元素剩余空间的分配。这还只是个很简单的例⼦,如果遇上更加复杂的布局,要兼容调整的就不只⼀点代码能解决了。
flex布局解决⽅案:
felx采⽤的是弹性布局,在声明⼀个元素的display属性为flex的时候,浏览器在元素内计算两天轴来,两条⽅向轴根据flex-direction属性的值决定是纵轴位主轴还是横轴为主轴。在这⾥,我们给box 设置felx属性,并且将其X轴设置为主轴。然后让⾥⾯的元素在副轴上(Y轴纵轴)
上居中。为了设置box2分配剩余空间,我们给box2的flex属性设置为auto:意思是扩⼤和缩放都在box2上。然后我们将box2的display属性也设置为flex,为了均匀排列⾥⾯的元素,可以将box2的主轴设置为Y轴,然后再Y轴上设置均分属性:justify-content: space-between;我们看下伪代码:
.box {
display: flex;/*申明布局⽅式*/
flex-direction:row;/*声明主轴的⽅向*/
justify-content:flex-start;/*主轴的排列*/
align-items:center;/*副轴排列*/
}
.box2 {
flex-direction: column;
justify-content: space-between;
align-items: flex-start;
flex: auto;/*⾃适应填充⽅式*/
}
简简单单⼏⾏代码,实现了普通布局花了2倍的代码量完成的需求。⽽且不管⾼度宽度如何变化,⾥⾯的元素排列⼀直整整齐齐。当然在复杂的布局中省掉的不仅仅使代码量,⽽且还有维护成本等⼀系列的开销。这就是flex的优势所在。但是致命缺陷马上就要暴露,在⼿机端查看,却出现了另⼀个⿁样⼦(完全错乱的排列顺序)。这让露珠很失望很失望。欣喜若狂的赶脚马上烟消云散。下⾯我们就要寻兼容的解决的⽅案。
兼容版本box布局margin属性值可以为百分比
据露珠所知,box布局⽅式是flex的前辈了,属于⽼⼀代的解决⽅案。在w3c⾥⾯已经列为了标准。也就是说只要加上前缀,它就能被各个浏览器⽀持。下⾯我们就⽤此⽅法兼容⼀下⼿机浏览器。
.box{
display: -webkit-box;/*布局⽅式相当于display:flex*/
-webkit-box-align: center;/*box的对齐⽅式 align-items:center;*/
}
.box2{
display: -webkit-box; -webkit-box-orient: vertical;/*排列⽅式flex-direction: column*/
-webkit-box-pack: justify;/*box2的纵向排列⽅式 justify-content: space-between;*/
-webkit-box-flex:1; /*box2的伸缩⽐例 flex:auto;*/
}
以上代码就是⽼旧版本的兼容写法,虽然说它⽼,但是却被各种浏览器兼容。通过测试,在chrome、安卓、ios上样式和排列都是正常的。到此为⽌,我们做的⼩⼩的兼容⽰例就完成了!
⼩结
这是⽬前露珠在使⽤flex上遇到的⼀些兼容问题和解决的⽅案。实际上在实施过程中遇到的情况⽐此处更复杂。露珠也借助了flex学习了⼀下box布局,发现box布局早已有之,在国外已经被普遍使⽤,⽽吾等竟全然不知。每念及此,⽆不垂⾜顿胸,蹲守顿⾜啊。同时,希望露珠这篇⽂章能激发你学习新布局技术的动⼒。在前端这条路上,即使原地不动也算是退步。
参考⽂档
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论