文章目录
Flex弹性布局概述
存在即有道理,为什么Flex弹性布局会大行其道,这是因为网页传统布局是基于盒模型,为了实现复杂的页面效果,需要结合着浮动、相对定位、绝对定位、display属性,这样做会使布局工作相当繁琐,还有一个困扰切图狗的问题,就是各种垂直居中问题。
2009年css3为display增加了一个新的属性值flex,定义了display:flex的元素(容器)的直接子元素默认成了父元素的flex-item(项目),项目具有了弹性,并且float、clear和vertical-align属性将失效。
目前大部分现在浏览器都支持flex布局,但是…你应该猜到了,对IE的问题,IE10开始支持flex布局,但我在IE11中测试过,使用flex布局的元素有跑位现象,在PC端布局的时候请谨慎取舍,移动端布局的时候可以放心大胆的使用啦!
父元素的项目不管从前是块级元素还是行内元素一律成为了弹性盒子,本文统一称父元素为容器,容器的弹性子元素为项目,flex布局的特点是:在容器内项目具有弹性,可以根据内容或设定放大缩小而不会溢出容器;请注意:这句话的意思是容器内的项目通过自身弹性来适应盒子
,项目在容器中横向和纵向的对齐方式具有很大的灵活性;项目在主轴上的排列顺序可以突破标准文档流进行灵活定义。
本文会通过一些例子来演示这些特性:
<div class="box" >
<div>1</div>
<div>2</div>
<span>3</span>
</div>
为了便于观察,我给四个盒子一些简单样式进行区分,把box定义为弹性盒子容器后,项目1,2,3默认会在同一行显示,看起来1和2不再是块级元素,3不再是行内元素,他们都是弹性盒子元素。
.box{ display:flex }
一、与弹性相关
1、容器的flex-direction属性,定义主轴和方向
flex容器默认存在两根轴:主轴和交叉轴。实际上类似于几何中的x轴和y轴,但x轴并不一定是主轴,因为flex容器的主轴和方向可以用flex-direction属性定义。
.box { display:flex; flex-direction:row }
属性值 | 描述 |
---|---|
row | 默认值,项目从左到右排列,向下折行 |
row-reverse | 项目从右到左排列,向下折行 |
column | 项目从上到下排列,向右折行 |
column-reverse | 项目从下到上排列,向左折行 |
通过这个图片,我们已经验证了项目的4种排列方式,另外还能发现,项目在容器主轴方向的尺寸(左上、右上是宽度,坐下右下是高度)是由内容撑开的,在容器交叉轴方向撑满容器。
这涉及两个属性:
项目的flex-basis属性
flex-basis属性用于定义项目在容器主轴方向的尺寸,如果同时定义了宽度或高度,flex-basis的定义优先,默认值为0,即根据内容撑开宽度,flex-basis为auto时,如设置了width/height则元素尺寸由width/height决定;没有设置则由内容决定。
容器的align-items属性
- 默认值是stretch,当容器包含的弹性项目没有设置具体尺寸时会将容器在交叉轴方向撑满。如果项目尺寸设置了auto/width/min-height/height/min-height等属性,会遵照这些定义。
- 当align-items不为stretch时,此时除了对齐方式会改变之外,元素在交叉轴方向上的尺寸将由内容或自定义尺寸(宽高)决定。
下面的例子中,我给项目1定义了flex-basis: 100px,容器定义了align-items: center,具体的属性值后面还会讲到。
2、flex-wrap属性设置不折行、折行、反向折行
上面的例子中没有出现折行的例子,上面我已经说了可以用flex-basis来定义主轴方向的尺寸,那么我们现在来研究主轴方向上的折行吧,说明一点还是可以用原来的width,height属性来定义项目的宽高。
flex布局又叫弹性布局,项目有弹性,不会出现从前我们布局时出现的溢出跑位的情况,在主轴排列不下项目的时候,通过flex-wrap属性定义项目在主轴上排列不下时的应对方式。
flex-wrap使得主轴上的元素不折行、折行、反向折行:
.box { display:flex; flex-direction:row:flex-wrap:wrap }
属性值 | 描述 |
---|---|
nowrap | 默认值,不折行,若容器宽度<项目总宽度时,项目会缩小比例,缩小的比例参考项目的flex-shrink属性 |
wrap | 在必要的时候折行 |
wrap-reverse | 在必要的时候方向折行 |
我们最常用的布局是从左到右、从上到下,那么以左上的例子,让项目沿着交叉轴的起点排列(align-items:flex-start),并给项目1一个大于容器宽度的值,来验证一下:
实际上在3种情况下,项目1都被缩小了,为了适应flex-wrap的设置,缩小的程度不同而已,弹性、弹性、弹性,一定记住这一点。
3、项目如何弹性伸缩应对
上面的例子中,项目1都缩小了,实际上,在flex布局中,我们还可以对项目进行放大,在项目中有两个属性可以定义:
flex-shrink:缩小比例(容器尺寸<项目总尺寸时如何收缩)
flex-grow:放大比例(容器尺寸>项目总尺寸时如何伸展)
(1)缩小比例 flex-shrink
在弹性布局中,缩小比例我们还要考虑能不能缩小这个问题,上例中,2、3的尺寸是内容决定的,不能再缩小,所以在需要缩小时只有1缩小,假设本例中有很多项目要求不折行,每个项目已经缩小到极限容易宽度还是不够分配,后面的项目将被隐藏。
除此之外,默认情况下,flex-shrink值是1,缩小时是等比例缩小,占满整个宽度。见下图:
图中的容器是个300px*300px的矩形
(2)放大比例 flex-grow
上面的很多例子中,我们已经看到了容器尺寸有剩余的情况。
弹性布局的flex-grow属性可以设置要不要分配剩余尺寸以及怎么分配。默认情况下flex-grow的值是0,即容器剩余尺寸不进行分配。
在容器有剩余的时候flex-grow才起作用,项目的最终宽度(或高度),等于设定宽度+额外分配的剩余尺寸,分配多少根据flex-grow的值确定,上图中已经很清楚的表达了这种关系,容器剩余30像素,项目3,分到了6(3+2+1)份中的一份,5像素,项目3的宽度是180px+5px。
二、容器内对齐
flex布局中的对齐太完美了,为我们带来的不仅仅是代码量的减少,更多的是你不再需要去思考、去计算、去权衡,只需要告诉浏览器我要怎样怎样就OK了,布局的工作量大大减少,使我们有精力去解决更加复杂的问题。
前文中,我们说容器有两个轴,对齐很明显就是设定主轴和交叉轴两个方向如何对齐。
- 主轴上的对齐方式:justify-content
- 交叉轴上的对齐方式 :align-items(单行对齐)和align-content(多行对齐),align-self(项目单独对齐)
1、主轴上的对齐 justify-content
justify-content属性起作用的前提是:项目在主轴方向没有铺满容器,那么剩余的尺寸要怎样分布在主轴中。
justify-content: flex-start|flex-end|center|space-between|space-around
值 | 描述 |
---|---|
flex-start | 默认值。项目在容器主轴上向起点对齐。 |
flex-end | 项目在容器主轴上向终点对齐。 |
center | 项目在容器主轴上向中间点对齐。 |
space-between | 第一个项目向起点对齐,最后一个项目向终点对齐,其他项目平均分布。 |
space-around | 每个项目两侧的间隔相等。所以,项目之间的间隔比项目与边框的间隔大一倍。 |
下面的例子是 flex-direction为row的情况:
2、交叉轴上的单行对齐 align-items
align-items: stretch|center|flex-start|flex-end|baseline
值 | 描述 |
---|---|
stretch | 默认值。元素被拉伸以适应容器。 |
center | 沿交叉轴中间点对齐 |
flex-start | 沿交叉轴起点对齐 |
flex-end | 沿交叉轴终点对齐 |
baseline | 沿交叉轴上各项目第一行文字的基线对齐 |
以横轴为主轴,左起的情况下:
3、交叉轴上的多行对齐 align-content
align-content属性起作用的前提是:1、flex容器内包含折行的项目,并且容器交叉轴上有多余空间。align-content对单行是没有效果的。
在属性值上,align-content比align-items多了两个值:space-between和space-around。
值 | 描述 |
---|---|
stretch | 默认值。元素被拉伸以适应容器。 |
center | 沿交叉轴中间点对齐 |
flex-start | 沿交叉轴起点对齐 |
flex-end | 沿交叉轴终点对齐 |
baseline | 沿交叉轴上各项目第一行文字的基线对齐 |
space-between | 与交叉轴两端对齐,轴线之间的间隔平均分布 |
space-around | 每根轴线两侧的间隔都相等 |
PS:在项目为多行时,align-items和align-content区别请见下图:
4、交叉轴上的项目单独对齐 align-self
值 | 描述 |
---|---|
stretch | 默认值。元素被拉伸以适应容器。 |
center | 沿交叉轴中间点对齐 |
flex-start | 沿交叉轴起点对齐 |
flex-end | 沿交叉轴终点对齐 |
baseline | 沿交叉轴上各项目第一行文字的基线对齐 |
三、容器内项目排序 order
项目的order属性可设置项目之间的排列顺序
- 数值越小,越靠前,默认为0
- 值相同时,以dom中元素排列为准
附录一、容器的属性
属性名 | 作用 | 属性值 |
---|---|---|
flex-direction | 定义主轴及其方向 | row/row-reverse/column /column-reverse |
flex-wrap | 定义项目在主轴上排列不下时的应对方式 | nowrap /wrap wrap-reverse |
flex-flow | 复合属性,flex-flow = flex-drection + flex-wrap | |
justify-content | 定义主轴上的对齐方式 | flex-start/flex-end/center/space-between/space-around |
align-items | 定义交叉轴上的单行对齐方式 | stretch/center/flex-start/flex-end/baseline |
align-content | 定义交叉轴上的多行对齐方式 | stretch/center/flex-start/flex-end/baseline/space-between/space-around |
附录二、项目的属性
属性名 | 作用 | 属性值 |
---|---|---|
order | 定义容器内项目之间的排列顺序 | 数值 |
flex-grow | 定义弹性容器内项目的放大比例 | 数值 |
flex-shrink | 定义弹性容器内项目的缩小比例 | 数值 |
flex-basis | 定义项目在主轴上的初始尺寸 | |
flex | 复合属性,flex = flex-grow + flex-shrink + flex-basis | |
align-self | 单独定义某个项目在交叉轴上的对齐方式 |