在移动端的开发中,为了方便起见,Flex弹性布局成为最常见的布局方式,单纯地使用普通定位以及不能满足我们的设计需要。
一、传统的元素定位
传统布局上,对于元素的定位,我们主要从三方面来设置display、position 和 float,此外还有z-index
1. display的属性:
- none: 不显示,隐藏一个元素
- inline(默认): 默认显示内联元素,前后没有换行符
- inline-block: 行内块元素
- block:块级元素,前后有换行符
- list-item:此元素作为列表显示
- run-in:根据上下门作为块级或者内联元素显示
表格单元格的显示: - table/inline-table/table-row-group/table-header-group/table-footer-group
- table-row/table-column-group/table-column/table-cell/table-caption
※display:none 和 visibility:hidden的区别:
display:none
(看不见,摸不着)可以隐藏某个元素,且不会占用空间。不但被隐藏布局,占据空间也会从布局消失visibility:hidden
(看不见,摸得着)可以隐藏某个元素,但隐藏的元素仍需占用空间。元素虽然被隐藏,但依旧影响布局。
2. position的属性:
- static(default)——默认定位:无定位,元素出现在正常流中(忽略top、left、bottom、right、z-index等)
- absolute ——绝对定位:相对于最近的已定位的父元素,若不存在,则相对于。与文档流无关,不占空间,与其他元素重叠。
- relative ——相对定位:出现在所在位置上,设置垂直、水平位置(top、bottom、left、right
),让这个元素相对于自己的起点移动。无论移动与否,都占据原来空间,移动元素可能导致他覆盖其他框。
- fixed ——固定定位:相对于浏览器的窗口是固定位置,不随窗口滚动而移动。与文档流无关,不占据空间,与其他元素重叠。
- sticky ——粘性定位:相对于该元素在流中的***flow root(BFC)和containing block(最近的块级祖先元素)***定位。按照普通文档流定位,而后元素定位表现为在跨越特定阈值之前为相对定位,之后为固定定位。
- inherit:父元素处继承position属性值
3. float属性
float指定一个盒子是否可以浮动:
- left: son.width = som.padding + son.content
- right:
- none: 空隙 = son.margin + father.padding
- inherit:
clear指定不允许元素周围有浮动元素:left、right、both、none、inherit
4. z-index: 指定一个元素的堆叠顺序,调整定位时重叠块的上下位置
关于float还有一个非常常见的问题——清除浮动
现象: 未给父元素设置高度时,内部元素不浮动会撑开它,但是浮动时,父元素会变成一条线
本质: 为了解决父元素因为子元素浮动引起的内部高度为0的问题
4. ※如何清除浮动?
一、额外标签法(不推荐)
在浮动元素后面添加带clear的空白标签,例如:<div class="clear">、<br/>、<hr/>
之类的空元素,设置属性:
.clear {
clear:both
}
二、父级使用overflow属性(不推荐)
通过触发BFC
方式,实现清除浮动的效果,给浮动元素的父容器添加overflow:hidden
或者overflow:auto
可清除浮动
.father {
width: 400px;
border: 1px solid deeppink;
overflow: hidden;
}
BFC,块级格式化上下文,用于清除浮动,防止margin重叠,BFC是一个独立的渲染区域,有一定的布局规则
1)BFC区域不会和float box重叠
2)BFC是页面上的一个独立容器,子元素不会影响到外面
3)计算BFC的高度时,浮动元素也会参与计算
Q:哪些元素生成BFC?
- float不为none的元素
- position为absolute和fixed的元素
- display为inline-block、table-cell、table-caption、flex、inline-flex的元素
- overflow不为visible的元素
此外在IE6中还需要触发hasLayout
,例如为父容器设置宽高或者设置zoom:1
三、使用:after伪元素
给浮动元素的父容器添加一个clearfix
的class,然后给这个class添加一个:after
伪元素,实现元素末尾添加一个看不见的块元素(Block)清理浮动。:after伪元素和IEhack可以完美兼容当前的各大浏览器,这里的IEhack是指触发hasLayout
.
使用示例:
父容器:<div class="father clearfix"></div>
.clearfix:after{ /* 伪元素是行内元素,正常浏览器清除浮动的方法 */
content: ""; /* content里面的内容尽量不带点 */
display: block;
height: 0;
clear: both;
visibility: hidden;
}
.clearfix{ /*IE6清除浮动的方式,*只有IE6-7执行,其他浏览器不执行*/
*zoom: 1;
}
:after方式实际上是方法一中空元素的升级版,但好处是不需要添加额外的标签
四、使用:before和:after双伪元素
类似上一个方法,给父亲添加clearfix,对父类容器的定义依旧是:<div class="father clearfix"></div>
.clearfix:after,.clearfix:before {
content: "";
display: table;
}
.clearfix:after {
clear: both;
}
.clearfix{
*zoom: 1; /*原因同上*/
}
对于这几种清除方式的优缺点,cc也做表整理大致这样:
以上都是对常见的定位类型和属性的分析,实际上,传统的布局解决方案对于特殊布局是十分不便的。比如常见的垂直居中布局并不易实现。这个时候Flex布局就可以很好地解决这个问题。
二、Flex弹性布局
css中的盒模型包括IE盒子模型和标准W3C盒子模型。两者的区别在于width的包含范围,标准的盒子模型width=content
的宽度,IE盒子模型width = content+padding+border
控制盒模型范围则需要:box-sizing属性(content-box | padding-box | border-box)
盒子模型限制下的布局不易调整,Flex (Flexible Box)的出现就是为盒状模型提供最大的灵活性。
关于Flex布局,可以划分为:
1. 容器的属性
- flex-direction: 决定主轴的方向(子item的排列方式)
flex-direction: row | row-reverse | column | column-reverse
- flex-wrap: 决定换行的规则,
flex-wrap: nowrap | wrap | wrap-reverse
- flex-flow:
flex-flow: <flex-direction > || <flex-wrap>
- justify-content: 对齐方式,水平主轴对齐方式
- align-items: 对齐方式,竖直轴线方向
2. 元素(项目)的属性
- order: 定义项目的排列顺序,顺序越小,排列越靠前,默认为0
- flex-grow:定义项目的放大比例,即使存在空间,也不会放大
- flex-shrink: 定义了项目的缩小比例,当空间不足的时候会等比例缩小,item的
flex-shrink=0
时表示不缩小 - flex-basis: 定义了在分配多余的空间,项目占据的空间
- flex:
[flex-grow, flex-shrink, flex-basis]
的简写,默认值0 1 auto
- align-self: 允许单个项目与其他项目不一样的对齐方式,可以覆盖
align-items
,默认属性为auto
,表示集成父元素的align-items
三、实现垂直居中布局
垂直居中布局虽然是我们比较常见的一种布局方式,很多时候我们需要子元素在父元素内实现垂直居中,实际并不容易,接下来总结下实现垂直居中的几种方式。
1. margin:auto法
案例:实现图像在div内的垂直居中
css:
div {
width: 400px;
height: 400px;
position: relative;
border: 1px solid #2e2e2e;
}
img {
position: absolute;
margin: auto;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
定位上下左右为0,margin:auto,可以实现脱离文档流的居中。
2. margin负值法
.container{
width: 500px;
height: 400px;
border: 2px solid #6e6e6e;
position: relative;
}
.inner{
width: 480px;
height: 380px;
background-color: #4699ee;
position: absolute;
top: 50%;
left: 50%;
margin-top: -190px; /* height的一半 */
margin-left: -240px; /* width的一半 */
}
上方的margin负值也可以替换为: transform: translateX(-50%)
和 transform: translateY(-50%)
3. table-cell(未脱离文档流)
设置父元素的display:table-cell
,并且vertical-align:middle
,这样子元素可以实现垂直居中。
div{
width: 300px;
height: 300px;
border: 3px solid #555999;
display: table-cell;
vertical-align: middle;
text-align: center;
}
img{
vertical-align: middle;
}
4. flex布局
设置父元素为:dispay:flex
,并且设置align-items:center
;justify-content:center;
.container{
width: 300px;
height: 200px;
border: 3px solid #56ff56;
display: flex;
-webkit-align-items: center;
align-items: center;
-webkit-justify-content: centent;
justify-content: center;
}
.inner{
border: 3px solid #656565;
padding: 20px;
}
5. css3属性transform
.inner{
position: absolute
left: 50%
top: 50%
transform: translate(-50%, -50%)
}
对比多种布局方式也发现,在开发中使用flex布局是最便捷的