样式篇 - Flex弹性盒子布局(建议收藏)

1、引言

传统的CSS布局基本是div + css布局,依赖盒子模型,经过positionfloatdisplay等方式实现,可是对于一些特殊布局,就不太容易实现,好比垂直居中布局。css

2009年,W3C 提出了一种新的方案----Flex 布局,能够简便、完整、响应式地实现各类页面布局。目前大部分浏览器都已经支持Flex属性。html

我也一直在使用Flex,可是有的属性也只是会用,只知其一;不知其二,甚至有的属性就没用过,好比: orderflex-grow等。写这篇文章的目的主要仍是作个总结与梳理,加深印象。web

2、什么是Flex布局

Flex 是 Flexible Box 的缩写,意为"弹性布局"。

CSS 弹性盒子布局是 CSS 的模块之一,定义了一种针对用户界面设计而优化的 CSS 盒子模型。在弹性布局模型中,弹性容器的子元素能够在任何方向上排布,也能够“弹性伸缩”其尺寸,既能够增长尺寸以填满未使用的空间,也能够收缩尺寸以免父元素溢出。子元素的水平对齐和垂直对齐都能很方便的进行操控。经过嵌套这些框(水平框在垂直框内,或垂直框在水平框内)能够在两个维度上构建布局。 —— MDN浏览器

3、基本概念

3.一、容器

采用 Flex 布局的元素,称为 Flex 容器(flex container),简称"容器"。它的全部子元素自动成为容器成员,称为 Flex 项目(flex item),简称"项目",也叫flex元素。布局

3.二、两根轴线

Flex的两根轴线,分别是主轴交叉轴,能够简单理解为水平竖直两个方向。默认状况下主轴对应的是水平方向交叉轴对应的是竖直方向,可是这个对应关系是能够修改的(经过flex-direction属性),不少状况下咱们也确实要修改,具体怎么修改下面会讲到。flex

3.三、起始线和终止线

以前咱们通常都默认文档书写时从左到右的,可是Flex没有左右的概念,默认状况下,flex-direction的属性值为row,意思就是主轴为水平方向,起始线(也就是起点)在左边。flex-direction属性还有其余属性值,这里先不列举,后面详细说。优化

4、CSS属性

4.一、使用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属性将失效。

4.二、容器的属性

容器能够设置下面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其实就是默认的属性值,不换行,压缩在容器内展现,wrapwrap-reverse都是换行,可是不一样行的展现顺序不一样。

flex-flow属性

能够将两个属性 flex-directionflex-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-aroundspace-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固然就看不出什么效果了。

最后仍是看下对比图

4.三、项目的属性

项目能够设置下面几个属性

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-shrinkflex-basis的简写,默认值为0 1 auto。后两个属性可选。

有几种写法:

单值语法

  • 一个不带单位的数值,会被当作flex-grow的属性值。
  • 一个有效的宽度值(如:10px),会被当作flex-basis的属性值。
  • 关键字noneautoinitial

双值语法

第一个值必须为一个无单位数,而且它会被看成 <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,概念和语法的东西大概就说这么多,也参考了不少资料,有什么补充和错误之处还请斧正,很是感谢!!!

以为有用的话能够点赞 + 收藏哦!

参考资料:

相关文章
相关标签/搜索