传统的CSS布局基本是div
+ css
布局,依赖盒子模型,经过position
、float
、display
等方式实现,可是对于一些特殊布局,就不太容易实现,好比垂直居中布局。css
2009年,W3C 提出了一种新的方案----Flex 布局,能够简便、完整、响应式地实现各类页面布局。目前大部分浏览器都已经支持Flex属性。html
我也一直在使用Flex,可是有的属性也只是会用,只知其一;不知其二,甚至有的属性就没用过,好比: order
、flex-grow
等。写这篇文章的目的主要仍是作个总结与梳理,加深印象。web
Flex 是 Flexible Box 的缩写,意为"弹性布局"。CSS 弹性盒子布局是 CSS 的模块之一,定义了一种针对用户界面设计而优化的 CSS 盒子模型。在弹性布局模型中,弹性容器的子元素能够在任何方向上排布,也能够“弹性伸缩”其尺寸,既能够增长尺寸以填满未使用的空间,也能够收缩尺寸以免父元素溢出。子元素的水平对齐和垂直对齐都能很方便的进行操控。经过嵌套这些框(水平框在垂直框内,或垂直框在水平框内)能够在两个维度上构建布局。 —— MDN浏览器
采用 Flex 布局的元素,称为 Flex 容器(flex container),简称"容器"。它的全部子元素自动成为容器成员,称为 Flex 项目(flex item),简称"项目",也叫flex
元素。布局
Flex的两根轴线,分别是主轴
和交叉轴
,能够简单理解为水平
和竖直
两个方向。默认状况下主轴
对应的是水平方向
,交叉轴
对应的是竖直方向
,可是这个对应关系是能够修改的(经过flex-direction
属性),不少状况下咱们也确实要修改,具体怎么修改下面会讲到。flex
以前咱们通常都默认文档书写时从左到右的,可是Flex没有左右的概念,默认状况下,flex-direction
的属性值为row
,意思就是主轴为水平方向,起始线(也就是起点)在左边。flex-direction
属性还有其余属性值,这里先不列举,后面详细说。优化
CSS
属性Flex
布局指定一个元素为Flex
容器很是简单。spa
.box { display: flex; }
行内元素也能够指定为Flex
容器。设计
.box { display: inline-flex; }
Webkit
内核的浏览器。code
.box{ display: -webkit-flex; /* Safari */ display: flex; }
注意,设为 Flex 布局之后,子元素的float、clear和vertical-align属性将失效。
容器能够设置下面6个属性:
flex-direction flex-wrap flex-flow justify-content align-items align-content
先初始化一下咱们的页面
/* HTML */ <div class="container"> <div class="item">one</div> <div class="item">two</div> <div class="item">three</div> </div>
/* CSS */ .container { width: 800px; height: 400px; margin: 100px auto; border: 1px dashed #00f; } .item { border: 1px solid #000; text-align: center; }
此时咱们的页面是这样的
flex-direction
属性flex-direction
属性可让咱们更改 flex 元素的排列方向(即主轴的方向),它有四个值。
.box { flex-direction: row | row-reverse | column | column-reverse; /* row(默认): 主轴为水平方向,起点在左端。 */ /* row-reverse: 主轴为水平方向,起点在右端。 */ /* column: 主轴为竖直方向,起点在上面。 */ /* column-reverse: 主轴为竖直方向,起点在下面。 */ }
注意,当主轴为水平方向时,对应的交叉轴就为竖直方向,反之亦然。
嗯。。。仍是看效果吧,首先把容器设置为flex容器
.container { ... display: flex; }
而后再设置flex-direction
属性。
效果就不一一展现了,太占地方,放一张对比的效果图。
这样就很清晰了,可能有人已经注意到了,项目在交叉轴方向上都被拉伸了,这是由于有另外一个属性的做用,它是align-items
,它的做用是控制容器内项目在交叉轴上的排列方式,后面会介绍,这里先不详细说。
flex-wrap
属性默认状况下,项目都排在一条线(又称"轴线")上。flex-wrap
属性定义,若是一条轴线排不下,如何换行。
.box{ flex-wrap: nowrap | wrap | wrap-reverse; /* nowrap(默认): 不换行 */ /* wrap: 换行,第一行在前面 */ /* wrap-reverse: 换行,第一行在后面 */ }
仍是要写一写,首先把上面的flex-direction
属性改为默认的,或者删除掉,如今效果是这样的
而后,咱们给容器内的项目设置宽度,使内容宽度超过容器的宽度
.item { width: 300px; /* 每一个项目宽度为300px,总共是900px */ ... }
能够看到,每一个项目宽度设置为300px,已经超过容器宽度的800px了,可是项目并无换行,而是被压缩在一行了,接下来看看flex-wrap
的做用,仍是展现对比图。
对比看起来就很明了了,nowrap
其实就是默认的属性值,不换行,压缩在容器内展现,wrap
和wrap-reverse
都是换行,可是不一样行的展现顺序不一样。
flex-flow
属性能够将两个属性 flex-direction
和 flex-wrap
组合为简写属性 flex-flow
。第一个指定的值为 flex-direction
,第二个指定的值为 flex-wrap
。默认值为:row nowrap
justify-content
属性justifity-content
属性定义了项目在主轴上的对齐方式。
justify-content: flex-start; /* 默认值,左对齐 */ justify-content: flex-end; /* 右对齐 */ justify-content: center; /* 居中 */ justify-content: space-between; /* 两端对齐,项目之间的间隔都相等 (首个元素在起点,末尾元素在终点) */ justify-content: space-around; /* 均匀排列每一个元素 每一个元素周围分配相同的空间 */ justify-content: space-evenly; /* 均匀排列每一个元素 每一个元素之间的间隔相等 */
仍是看对比图吧
其中space-around
和space-evenly
要分清楚,两个都是均匀分布,区别在于容器两端与元素之间的距离是否相等。
align-items
属性align-items
属性定义了项目在交叉轴上的对其方式,上面讲flex-direction
属性的最后说到了这个属性,如今就一块儿来看看。
align-items: flex-start; /* 元素向交叉轴的起点对齐 */ align-items: flex-end; /* 元素向交叉轴的终点对齐 */ align-items: center; /* 元素在交叉轴居中对齐。 */ align-items: baseline; /* 项目的第一行文字的基线对齐 */ align-items: stretch; /* 默认,若是项目未设置高度或设为auto,将占满整个容器的高度。 */
能够看到当属性值为stretch
的时候和一开始的效果是同样的,由于这是默认的属性值。
align-content
属性align-content
属性定义了多根轴线在交叉轴上的对齐方式。是轴线
的对齐方式,不是项目
。
align-content: flex-start; /* 与交叉轴的起点对齐 */ align-content: flex-end; /* 与交叉轴的终点对齐 */ align-content: center; /* 在交叉轴居中对齐 */ align-content: space-between; /* 与交叉轴两端对齐,轴线之间的间隔平均分布 */ align-content: space-around; /* 每根轴线两侧的间隔都相等 */ align-content: space-evenly; /* 均匀分布,两端与每条轴线之间距离相等 */ align-content: stretch; /* 默认,轴线占满整个交叉轴 */
这里有个须要注意的地方,当内容高度(也多是宽度)不固定的时候,align-content
默认属性值是stretch
,也就是充满交叉轴的长度,这时候设置align-items
能够看出效果。
可是若是align-content
设置为其余属性,align-items
设置的属性可能就“失效”了。其实不是失效,由于给align-content
设置除了stretch
的属性后,每一个主轴的内容高度(也多是宽度)就被压缩了,这时候再设置align-items
固然就看不出什么效果了。
最后仍是看下对比图
项目能够设置下面几个属性
order flex-grow flex-shrink flex-basis flex align-self
order
属性order
属性定义项目(元素)的排列顺序。数值越小,排列越靠前,默认为0。
仍是先修改一下页面代码
/* HTML */ <div class="container"> <div class="item item1">one</div> <div class="item item2">two</div> <div class="item item3">three</div> </div> /* CSS */ .container { width: 800px; height: 400px; margin: 100px auto; border: 1px dashed #00f; display: flex; align-items: flex-start; } .item { width: 200px; margin: 20px 0; border: 1px solid #000; text-align: center; }
如今效果是这样
增长CSS代码
.item1 { order: 3 } .item2 { order: 2 } .item3 { order: 1 }
能够看到,排列顺序发生了变化,order
值越小,排列越靠前,还能够为负数。
flex-grow
属性flex-grow
属性定义项目的放大比例,默认为0,即若是存在剩余空间,也不放大。
先恢复一下代码,分别添加代码
/* 给全部项目都设置为1 */ .item { flex-grow: 1; } /* 只给item1设置 */ .item1 { flex-grow: 1; } /* 只给item1和item2设置 */ .item1 { flex-grow: 1; } .item2 { flex-grow: 1; }
而后看下对比
能够看到若是只给一个元素设置flex-grow
大于0的属性,那个这个元素会占据剩余空间。
若是给多个元素设置相同的flwx-grow
属性,那么这些元素会平分剩余空间。
还有一种状况我没列举,给不一样元素设置不一样大小的flex-grow
属性,这时候会根据flex-grow
的大小分配不一样大小的空间。
上面说的都是在容器有剩余空间的状况下,若是项目充满了容器,name设置flex-grow
是没效果的。
flex-shrink
属性flex-shrink
属性指定了 flex
元素的收缩规则。flex
元素仅在默认宽度之和大于容器的时候才会发生收缩,其收缩的大小是依据 flex-shrink
的值,默认为1。
.container { width: 400px; /* 容器宽度小于项目宽度之和 */ } .item1 { flex-shrink: 2; }
能够看到第一个元素被压缩的程度是其余两个的2倍。这是由于flex-shrink
默认值为1,第一个元素咱们设置为2。
flex-basis
属性flex-basis
属性指定了 flex
元素在主轴方向上的初始大小。若是不使用 box-sizing
改变盒模型的话,那么这个属性就决定了 flex
元素的内容盒(content-box
)的尺寸。
当咱们设置为auto
时,就是使用项目原本的宽度。
flex
属性flex
属性是flex-grow
, flex-shrink
和 flex-basis
的简写,默认值为0 1 auto
。后两个属性可选。
有几种写法:
单值语法
flex-grow
的属性值。10px
),会被当作flex-basis
的属性值。none
,auto
或initial
。双值语法
第一个值必须为一个无单位数,而且它会被看成 <flex-grow>
的值。第二个值必须为如下之一:
<flex-shrink>
的值。10px
),会被当作flex-basis
的属性值。三值语法
<flex-grow>
的值。<flex-shrink>
的值。<flex-basis>
的值。flex: auto; /* 至关于 flex: 1 1 auto */ flex: none; /* 至关于 flex: 0 0 auto */
align-self
属性align-self
属性能够设置单个项目与其余项目不同的对齐方式,能够覆盖align-items
属性,默认值为auto
,表示继承父元素的align-items
属性。
align-self
的属性值和align-items
是同样的,只不过多了一个auto
。
上图中给容器设置了align-items: flex-start;
,而后单独给第一个元素设置了align-self: flex-end;
能够看到该元素和其余的元素排列方式不一样。
ok,概念和语法的东西大概就说这么多,也参考了不少资料,有什么补充和错误之处还请斧正,很是感谢!!!
以为有用的话能够点赞 + 收藏哦!
参考资料: