博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
CSS3的flexbox布局
阅读量:4132 次
发布时间:2019-05-25

本文共 6976 字,大约阅读时间需要 23 分钟。

CSS3为display属性增加了一个新值flex,于是诞生了一种新的布局方式:flexbox布局。flexbox布局的优点是可以根据需要自动修改元素的间距和大小。利用这点,可以在不借助任何框架的情况下,只用短短几行代码就实现响应式布局。

比如:

demo

点击查看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-startflex-endcenter。与justify-content不同的是,align-item并没有space-betweenspace-around,因为对于行内元素而言,这两者和center的效果其实是一样的,都是使元素居中。除此之外,align-item还有一个stretch值,效果就是元素沿副轴撑满容器:

说完了子元素在行内的排列,该说说它们在行间的排列了。不过在此之前,要先设置一下flex-wrap属性,这个属性控制当子元素过多时是否允许换行显示。允许换行的话设为wrap,否则设为no-wrap。这样就有多行元素了,而控制它们在行间的排列,需要用到align-content属性。从名字就可以看出来,这才是与justify-content相对应的属性,因此,后者拥有的值,它也都有。另外,它还有一个stretch值。具体效果如下:

最后一个例子里,记得要把align-item也设置成stretch才会有效果。

需要说明的是,除了stretch外,将align-content设为flex-startflex-endcenterspace-betweenspace-around中的任何一个值,align-item都会无效。可以这么理解:前面说过,align-item控制的是子元素上下margin的分配,而后面这几个值使得子元素在副轴方向上只能固定在某个特定的位置,所以可以认为此时它们的上下margin都只能为0,就不存在分配的问题了;而设为stretch的话,每个子元素可以撑满容器高度/n(n为子元素行数)的范围,这样它们就能在这个范围里上下自由移动了。

最后要注意align-content属性在子元素只有一行时无效。这是废话。

三、子元素上的属性

其实说到这里,flexbox布局已经能够实现了。但是子元素上还可以设定一些属性,使得我们能够对它们进行个性化的控制。
首先,flex-grow属性用来控制子元素沿主轴方向的大小。它的默认值是0,若将某个子元素的值设为大于0的数,那么它就会变得比同行的其他元素更宽。

这个demo可以看出下面两点:

(1)一旦某行出现一个flex-grow大于0的元素,那么该行会被撑满(图里的间隙是因为我在前面显式地给每个元素设置了一个5pxmargin)。
(2)某个元素flex-grow的值只与同行的其他元素比较。3号和6号不在同一行,所以即使3号的值比6号大,最后的结果也是6号更宽。
那么,给同一行某两个元素的flex-grow分别设置为32,是不是二者的宽度比值就是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

  • a
  • b
  • c

align-items:flex-end

  • a
  • b
  • c

align-items:center

  • a
  • b
  • c

align-items:baseline

  • a
  • b
  • c

align-items:strecth

  • a
  • b
  • c

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;
  • flex:1;
  • flex:1;
  • 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布局相关内容,点击

本文转自:

你可能感兴趣的文章
架构设计三原则
查看>>
复杂度来源
查看>>
架构设计流程
查看>>
高性能架构模式
查看>>
单服务器高性能模式
查看>>
高性能负载均衡
查看>>
高可用架构-CAP定理
查看>>
高可用框架-FMEA方法
查看>>
高可用存储架构
查看>>
二叉树和二叉树的遍历
查看>>
二叉堆构建
查看>>
堆排序
查看>>
TopK问题
查看>>
计数排序
查看>>
桶排序
查看>>
求链表是否有环,求链表环的长度和入环点
查看>>
Java最小栈
查看>>
Java求两个数的最大公约数
查看>>
java使用栈实现队列
查看>>
java判断一个数是否为2的整数次幂
查看>>