本文共 6976 字,大约阅读时间需要 23 分钟。
CSS3为display
属性增加了一个新值flex
,于是诞生了一种新的布局方式:flexbox布局。flexbox布局的优点是可以根据需要自动修改元素的间距和大小。利用这点,可以在不借助任何框架的情况下,只用短短几行代码就实现响应式布局。
比如:
点击查看demo
最近看到大漠翻译的一篇博客(原文:),学习了一下flexbox布局。下面是整理之后的学习笔记。
一、基本概念 要使用flexbox布局,只需将容器元素的display
属性设置为flex
。
对于一个container容器,它的子元素既可以沿x轴排列,也可以沿y轴排列。在flexbox布局中,若子元素沿x轴排列,则称x轴为主轴,y轴为副轴,反之亦然。为容器设置flex-direction
属性,可以指定其主轴和副轴:值为row
时元素沿x轴排列,即x为主轴,y为副轴;值为column
时则相反。为了方便起见,下面讨论的都是flex-direction:row(主轴为x轴)
的情况。
二、容器上的属性子元素在主轴上的排列是由justify-content(作用于主轴方向,此处将的都是以x轴为主轴)
属性控制的。这个属性的值和它们的效果如下:
justify-content: flex-start;
justify-content: flex-end;
justify-content: center;
justify-content: space-between;
justify-content: space-around;
前三项是布局中常用的左右对齐和居中。引入flexbox,就可以在避免使用float
的情况下轻松实现左右对齐。后两项的区别是:space-between
会让子元素撑满容器(当然,这里指的是在主轴方向),而space-around
会让所有子元素的两侧都拥有相等的margin
值。需要注意的是,这两种情况下子元素的margin
值都是根据容器大小自动计算出来的,这就为响应式布局提供了方便。
子元素在行内的排列是由align-item(作用于纵轴方向)
属性控制的。所谓在行内的排列(如果flex-direction
值为column
,则为列内的排列),其实就是子元素上下margin
值的分配问题。这样一来,很容易猜到想让子元素上下对齐和居中的话,应分别设置align-item
的值为flex-start
、flex-end
和center
。与justify-content
不同的是,align-item
并没有space-between
和space-around
,因为对于行内元素而言,这两者和center
的效果其实是一样的,都是使元素居中。除此之外,align-item
还有一个stretch
值,效果就是元素沿副轴撑满容器:
| justify-content:flex-start;//作用于主轴方向 align-items:stretch; //作用于纵轴方向 |
说完了子元素在行内的排列,该说说它们在行间的排列了。不过在此之前,要先设置一下flex-wrap
属性,这个属性控制当子元素过多时是否允许换行显示。允许换行的话设为wrap
,否则设为no-wrap
。这样就有多行元素了,而控制它们在行间的排列,需要用到align-content
属性。从名字就可以看出来,这才是与justify-content
相对应的属性,因此,后者拥有的值,它也都有。另外,它还有一个stretch
值。具体效果如下:
| justify-content: space-around; //作用于主轴方向 align-content: flex-start; //作用于纵轴方向 |
| justify-content:space-around;//作用于主轴方向 align-content:flex-end;//作用于纵轴方向 |
| justify-content: space-around; //作用于主轴方向 align-content: center; //作用于纵轴方向 |
| justify-content:space-around; align-content:space-between; |
| justify-content: space-around; align-content: space-around; |
| justify-content:space-around; |
最后一个例子里,记得要把align-item
也设置成stretch
才会有效果。
需要说明的是,除了stretch
外,将align-content
设为flex-start
、flex-end
、center
、space-between
和space-around
中的任何一个值,align-item
都会无效。可以这么理解:前面说过,align-item
控制的是子元素上下margin
的分配,而后面这几个值使得子元素在副轴方向上只能固定在某个特定的位置,所以可以认为此时它们的上下margin
都只能为0,就不存在分配的问题了;而设为stretch
的话,每个子元素可以撑满容器高度/n(n为子元素行数)的范围,这样它们就能在这个范围里上下自由移动了。 最后要注意align-content
属性在子元素只有一行时无效。这是废话。
三、子元素上的属性 其实说到这里,flexbox布局已经能够实现了。但是子元素上还可以设定一些属性,使得我们能够对它们进行个性化的控制。 首先,flex-grow
属性用来控制子元素沿主轴方向的大小。它的默认值是0
,若将某个子元素的值设为大于0
的数,那么它就会变得比同行的其他元素更宽。
这个demo可以看出下面两点:(1)一旦某行出现一个flex-grow
大于0
的元素,那么该行会被撑满(图里的间隙是因为我在前面显式地给每个元素设置了一个5px
的margin
)。(2)某个元素flex-grow
的值只与同行的其他元素比较。3号和6号不在同一行,所以即使3号的值比6号大,最后的结果也是6号更宽。那么,给同一行某两个元素的flex-grow
分别设置为3
和2
,是不是二者的宽度比值就是1.5呢?并不是这样。请看下面的例子:
该行元素默认的宽度为122px,而3号元素的宽度为194px,4号元素的宽度为171px。显然194并不是171的1.5倍。经过简单的计算发现,3号元素被加宽了72px,4号元素被加宽了49像素,而72恰好(其实没有恰好了,因为马克鳗四舍五入的关系)是49的1.5倍。这就是同一行不同元素flex-grow
相对比值的意义了。Demo在,大家可以自己去验证。
再说一个order
属性。顾名思义,这个属性控制元素在布局中出现的顺序。该属性默认值是0
,可以为负数,值小的排在前面,值大的排在后面。可以把几个元素的order
设为同一个数,这样的话它们会根据在HTML结构中出现的顺序排列:
align-items (适用于父类容器上)
设置或检索弹性盒子元素在侧轴(纵轴)方向上的对齐方式。
语法
align-items: flex-start | flex-end | center | baseline | stretch
- flex-start:弹性盒子元素的侧轴(纵轴)起始位置的边界紧靠住该行的侧轴起始边界。
- flex-end:弹性盒子元素的侧轴(纵轴)起始位置的边界紧靠住该行的侧轴结束边界。
- center:弹性盒子元素在该行的侧轴(纵轴)上居中放置。(如果该行的尺寸小于弹性盒子元素的尺寸,则会向两个方向溢出相同的长度)。
- baseline:如弹性盒子元素的行内轴与侧轴为同一条,则该值与'flex-start'等效。其它情况下,该值将参与基线对齐。
- stretch:如果指定侧轴大小的属性值为'auto',则其值会使项目的边距盒的尺寸尽可能接近所在行的尺寸,但同时会遵照'min/max-width/height'属性的限制。
实例
html:
align-items:flex-start
align-items:flex-end
align-items:center
align-items:baseline
align-items:strecth
css:
.box{ display:-webkit-flex; display:flex; width:200px;height:100px;margin:0;padding:0;border-radius:5px;list-style:none;background-color:#eee;}.box li{margin:5px;border-radius:5px;background:#aaa;text-align:center;}.box li:nth-child(1){padding:10px;}.box li:nth-child(2){padding:15px 10px;}.box li:nth-child(3){padding:20px 10px;}#box{ -webkit-align-items:flex-start; align-items:flex-start;}#box2{ -webkit-align-items:flex-end; align-items:flex-end;}#box3{ -webkit-align-items:center; align-items:center;}#box4{ -webkit-align-items:baseline; align-items:baseline;}#box5{ -webkit-align-items:strecth; align-items:strecth;}
结果如下: flex (适用于弹性盒模型子元素)
复合属性。设置或检索伸缩盒对象的子元素如何分配空间。
如果缩写flex:1, 则其计算值为:1 1 0
语法
flex:none | [ flex-grow ] || [ flex-shrink ] || [ flex-basis ]
- none:none关键字的计算值为: 0 0 auto
- [ flex-grow ]:定义弹性盒子元素的扩展比率。
- [ flex-shrink ]:定义弹性盒子元素的收缩比率。
- [ flex-basis ]:定义弹性盒子元素的默认基准值。
说明:
- 上例中,定义了父容器宽(即主轴宽)为800px,由于子元素设置了伸缩基准值flex-basis,相加300+500+600=1400,那么子元素将会溢出1400-800=600px;
- 由于同时设置了收缩因子,所以加权综合可得300*1+500*2+600*3=3100px;
- 于是我们可以计算a,b,c将被移除的溢出量是多少:
- a被移除溢出量:300*1/3100*600=3/31,即约等于58px
- b被移除溢出量:500*2/3100*600=10/31,即约等于194px
- c被移除溢出量:600*3/3100*600=18/31,即约等于348px
- 最后a,b,c的实际宽度分别为:300-58=242px, 500-194=306px, 600-348=252px
HTML代码
- flex:1 0 100px;
- flex:2 0 100px;
- flex:3 0 100px;
- flex:1 1 400px;
- flex:1 2 400px;
- flex:1 2 400px;
CSS代码: .box{ display:-webkit-flex; display:flex; max-width:400px;height:100px;margin:10px 0 0;padding:0;border-radius:5px;list-style:none;background-color:#eee;}.box li{background:#aaa;text-align:center;}.box li:nth-child(1){background:#999;}.box li:nth-child(2){background:#aaa;}.box li:nth-child(3){background:#ccc;}#box li:nth-child(1){-webkit-flex:1;flex:1;}#box li:nth-child(2){-webkit-flex:1;flex:1;}#box li:nth-child(3){-webkit-flex:1;flex:1;}#box2 li:nth-child(1){-webkit-flex:1 0 100px;flex:1 0 100px;}#box2 li:nth-child(2){-webkit-flex:2 0 100px;flex:2 0 100px;}#box2 li:nth-child(3){-webkit-flex:3 0 100px;flex:3 0 100px;}#box3{max-width: 800px;}#box3 li:nth-child(1){-webkit-flex:1 1 300px;flex:1 1 300px;background:#999;}#box3 li:nth-child(2){-webkit-flex:1 2 500px;flex:1 2 500px;background:#aaa;}#box3 li:nth-child(3){-webkit-flex:1 3 600px;flex:1 3 600px;background:#ccc;}
CSS order 属性
order:
number|initial|inherit;
属性值
值 | 描述 |
number | 默认值是 0。规定灵活项目的顺序。 |
initial | 设置该属性为它的默认值。请参阅 。 |
inherit | 从父元素继承该属性。请参阅 。 |
适用于 :flex子项和flex容器中的绝对定位子元素,设置或检索弹性盒模型对象的子元素出現的順序。 实例:
注意:Internet Explorer 和 Safari 不支持 order 属性。
要查看更多flex布局相关内容,点击
本文转自: