CSS中的Flex弹性布局和定位


在移动端的开发中,为了方便起见,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布局是最便捷的


Author: Casey Lu
Reprint policy: All articles in this blog are used except for special statements CC BY 4.0 reprint polocy. If reproduced, please indicate source Casey Lu !
评论
 Previous
WebSocket的原理、实现和应用 WebSocket的原理、实现和应用
webSocket是一项可以让服务器将数据主动推送给客户端的技术,无论前后端都会接触。在实际的项目开发中,webSocket在用于双向传输和推送消息方面能做到灵活、简便、高效,发挥着不可或缺的作用。 一、什么是webSocket webSo
2020-03-15
Next 
Vue项目中的上拉加载和下拉刷新 Vue项目中的上拉加载和下拉刷新
在移动端的项目中,由于显示器容量的限制,经常会有许多滚动场景的需求,因此Vue项目中实现列表的上拉加载和下拉刷新是非常频繁的事情,但是在真正项目中前端对于这个的实现有非常多的坑,今天主要介绍Vue项目中插件cube-scroll、bette
2020-03-12
  TOC