弹性布局
本文是在学习阮一峰大神的《Flex 布局教程:语法篇》之后写成的,去年系统的学了一遍,但没有总结成博文,这次算是弥补一下,并对一些错误加以修正。
使用范围
块级元素和内联元素都可以使用,但当声明了弹性布局后,其子元素的float、clear和vertical-align属性将无效。
.block-el{
display: flex;
}
.inline-block-el{
display: inline-flex;
}
基本概念
被声明了弹性布局的元素叫做弹性容器(flex container),其子元素被称作弹性项目(flex item)。
其中整个弹性容器默认存在两个轴,水平的叫做主轴(main axis),垂直的叫做侧轴(cross axis)
主轴的起始端点称为主轴起点(main start),结束端点称为主轴终点(main end)
侧轴的起始端点称为侧轴起点(cross start),结束端点称为侧轴终点(cross end)
注:主轴的起点终点不一定是在左右,同理侧轴的起点终点不一定是在上下,因为弹性盒子的方向有可能是垂直的,下面会说到。
容器属性
整个外容器有6个属性,一个一个来:
- flex-direction
-
flex-wrap
-
flex-flow
-
justify-content
-
align-items
-
align-content
flex-direction属性
.container {
flex-direction: row | row-reverse | column | column-reverse;
}
flex-direction决定主轴的方向,这也解决了上面那个注的问题。其中:
-
row(默认值):主轴为水平方向,起点在左端。
-
row-reverse:主轴为水平方向,起点在右端。
-
column:主轴为垂直方向,起点在上端。
-
column-reverse:主轴为垂直方向,起点在下端。
flex-wrap属性
这里每个item占70px(margin+width),我让container的宽度为140px。
当 flex-wrap: nowrap时,三个item不准许换行,因此每个item只有被挤压的份儿了,经计算每个应该是26.666666px。注意:这里的每个元素是按等比例缩小的。如示例,我将第一个item的宽度设为100px,其余两个还是50px,140px减去横向的margin值(一共60px),此时剩下80px,100x+50x+50x=80,得到缩小比例是40%,因此第一个item变成40px,其余两个是20px
当flex-wrap: wrap时,第三个正好被挤了下去
当flex-wrap: wrap-reverse时,原本应该在第一行的跑到了最下边去,最后一行得到了最上边,三个元素不见得好理解,下图写了7个item,这样就好理解了。
.container {
flex-wrap: nowrap | wrap | wrap-reverse;
}
flex-flow属性
flex-flow属性是flex-direction属性和flex-wrap属性的简写形式,默认值为row nowrap。
.container {
flex-flow: <flex-direction> || <flex-wrap>;
}
justify-content属性
justify-content属性定义了项目在主轴上的对齐方式。
.container {
justify-content: flex-start | flex-end | center | space-between | space-around;
}
align-items属性
align-items属性定义项目在交叉轴上如何对齐。
.container{
align-items: flex-start | flex-end | center | baseline | stretch;
}
align-content属性
align-content属性定义了多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用。因此应给container这歌class增加flex-wrap:wrap;
.container {
align-content: flex-start | flex-end | center | space-between | space-around | stretch;
}
项目属性
项目有6个属性,一个一个来:
- order
-
flex-grow
-
flex-shrink
-
flex-basis
-
flex
-
align-self
order属性
order属性定义项目的排列顺序。权值越小,排列越靠前,默认为0。
.item {
order: <integer>;
}
flex-grow属性
flex-grow属性定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大。当每个item的flex-grow都设为1时,他们将平均分配剩余空间(如果存在剩余空间的话)。
.item {
flex-grow:
}
flex-shrink属性
flex-shrink属性定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小。该属性要与容器属性flex-wrap: nowrap;配合使用。当对某个item的flex-shrink:0;时,这个项目将不会等缩小(在容器空间不足的情况下),这样就会导致元素溢出。
.item {
flex-shrink: <number>;
}
flex-basis属性
flex-basis属性定义了在分配多余空间之前,项目占据的主轴空间(main size)。浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为auto,即项目的本来大小。也可以设置一个长度值,感觉就像是重定义了这个项目的尺寸。
.item {
flex-basis: <length> | auto;
}
flex属性
flex属性是flex-grow, flex-shrink 和 flex-basis的简写,默认值为0 1 auto。后两个属性可选。在大多数情况下,应使用下列几个简写值:
-
auto 等价于 flex: 1 1 auto
-
initial 等价于 flex: 0 1 auto
-
none 等价于 flex: 0 0 auto
align-self属性
align-self属性允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性。默认值为auto,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch。
.item {
align-self: auto | flex-start | flex-end | center | baseline | stretch;
}
小示例
简单模拟BootStrap栅格系统
HTML
<div class="container">
<div class="col-lg-8 col-xs-12">
<div class="item item-1">80%</div>
</div>
<div class="col-lg-4 col-xs-12">
<div class="item item-2">20%</div>
</div>
</div>
<p class="cur-width">当前宽度:<span class="cur-width-val"></span></p>
CSS
.container {
display: flex;
border: 1px solid #000;
width: 100%;
}
.col-lg-8 {
flex: 0 0 66.66666666%;
}
.col-lg-4 {
flex: 0 0 33.33333333%;
}
.item {
background-color: #ccc;
height: 50px;
flex: 1;
margin: 10px;
}
@media (max-width: 768px) {
.container {
flex-flow: wrap;
}
.col-xs-12 {
flex: 0 0 100%;
}
}
JS
$('.cur-width-val').text($(window).width());
$(window).on('resize', function () {
$('.cur-width-val').text($(this).width());
if ($(this).width() <= 768) {
$('.item-1').text('我现在占一行');
$('.item-2').text('我现在占一行');
} else {
$('.item-1').text('我现在占80%');
$('.item-2').text('我现在占20%');
}
})
写在最后
flex布局确实学起来有些复杂,用熟了就好了。还有很多属性没有涉及到,不过常用的貌似就那么几个。
以上、よろしく。
PREVIOUS POST
各种垂直居中总结
NEXT POST
HTML5.2 新特性