flex布局用法整理

2,976 阅读7分钟

前言

如果您对flex布局的基本概念还没有了解的话,建议先看一下阮一峰老师的文章Flex布局.语法篇

阮老师的文章图文并茂,对flex box的基本语法和概念解释的非常清楚。

我的这篇文章只是在此基础上进行了整理归类,flex box 中的一些概念定义得并不是很直观,不太容易记忆,一段时间不使用就会感到陌生。我从日常使用的角度对这些概念进行了归类,并绘制了脑图,出发点是在自己出现遗忘的时候瞟一下脑图就能重新想起来。

1. 重要概念

flex布局意为弹性布局,为盒模型提供最大的灵活性。任何一个容器都可以指定为flex布局。

设置flex布局非常简单:

.container {
    display: flex;
}

flex布局中有几个重要的概念:

用于放置内容的容器container, 水平方向的主轴main axis, 垂直方向的交叉轴cross axis, 还有需要布局的项目item

主轴类似于x坐标轴,交叉轴类似于y坐标轴,可以把container想象成是放置于第四象限中进行布局的。 具体可以参考软来时博客中的图片。

2. 整体container布局

2.1 设置对齐方式

2.1.1 设置主轴方向对齐方式

设置justify-content属性

.container {
    justify-content: flex-start | flex-end | cneter | baseline | strech
}
  • flex-start:从左往右
  • flex-end:从右往左
  • center: 水平居中
  • space-between:两端对齐,项目之间的间隔相等
  • space-around: 项目左右两侧的间隔相等。项目之间的间隔是项目与边框之间间隔的两倍。

几种取值情况的水平对齐方式如下图所示:

2.1.2 设置交叉轴方向对齐方式

2.1.2.1 一根交叉轴的对齐方式

align-items

.container {
    align-items: flex-start | flex-end | center | space-between | space-around
}

2.1.2.2 多根轴线的对齐方式

align-content 对多行item进行对齐时需要使用align-content,该属性对于单行的情形是不适用的。

设置水平垂直居中

设置水平垂直居中对齐

.container {
    display: flex;
    justify-content: center;
    align-items: center;
}

使用flex布局来设置水平垂直居中就非常轻松了,不再需要使用hack技巧。

2.2 设置项目排列方向

flex-direction

.container {
    flex-direction: row | row-reverse | column | column-reverse
}
  • row: 主轴在水平方向,从左往右排列;默认值;
  • row-reverse: 主轴在水平方向,从右往左排列;
  • column: 主轴在垂直方向,从上往下;
  • coumn-reverse: 主轴在垂直方向,从下往上;

2.3 设置换行方式

flex-wrap

.container {
    flex-wrap: nowrap | wrap | wrap-reverse
}
  • nowrap: 不换行;
  • wrap: 换行,第一行在上方,剩下的往下排;
  • wrap-reverse: 换行,第一行在下方,剩下的往上排;

3.单个item设置

前面都是针对整个container容器进行的设置,从全局角度对item的对齐方式、排列走向、换行方式进行统一的的设置。

但是这样的设置不一定能满足所有的需求,有的时候某些item会有与众不同的布局需求,需要对某一个后几个item进行定制化设置。这种情况下你就需要针对具体的item的属性进行设置了。

  • order
  • align-self
  • flex-grow
  • flex-shrink
  • flex-basis

order: 设置单个item的排列顺序,数值越大越靠前;

.item {
  order: <integer>;
}

align-self: 设置单个item的排列方式,可以和整体排列方式不一样;

.item: {
    flex-grow: <number>;
}

后面3个属性 flex-grow | flex-shrink | flex-basis 可以合并成一个属性flex。 这个flex不是很直观,不太好记忆,为了便于理解记忆,我这里用一个可能不是太贴切比喻来解释这个概念。

flex-grow: 定义如果container中有剩余空间,是否放大item,默认值为0,意为即使有剩余空间也不放大。如果全部为1,即为等比例放大;如果一项为2,其他项为1,则前者占据的剩余空间要比后者多一倍。

.item {
    flex-grow: <number>; // 默认为0;即使空间没有使用完,也不填充。
}

这段话如果理解了也就理解了,如果没理解,请看这个例子:

有一天小明和小强加完班后坐末班地铁,地铁上很空位置很多。小明和小强找了一排位置坐下了,一排一共有6个座位,小明坐第一个,小强坐第二个,剩下4个座位都是空着的。那么布局如下:

然后小明很困了,小强也眯着眼睛在座位上快睡着了。看到还有很多空余位置,小明便对小强说,你往那边挪挪,咱们都躺下眯一会儿吧。于是小强挪到了第4个位置上,他们把剩下的位置平均分了。

于是属性设置便是这样的:

.itemMing, .itemQiang {
    flex-grow: 1; // 剩余空间被等比例分配了
}

但是后来他们发现剩余的位置需要重新分配,因为小明身材非常高大,小强比较矮小。于是善良的小强往后挪了挪,又腾了1/3个位置给小明,这样剩下的4个位置中,小明分了2.6个,小强1.3个,小明是小强的2倍。

于是属性设置变成了这样:

.itemMing {
    flex-grow: 2;
}

.itemQiang {
    flex-grow: 1;
}

位置的分配变成了这样:

flex-shrink: 定义单个item的缩小比例,可以避免内容从父容器中溢出;

.item {
    flex-shrink: <number> // 默认为1;空间不足时item将缩小,避免溢出容器。
}

如果所有的item该属性都为1,那么空间不足时,将等比例缩小;如果有一项为0,其他项都为1,那么前者不缩小,其他项目等比例缩小。

理解的就理解了,没理解的看看例子:

有一天小明小强和同事们一起出去团建,大家选择了地铁出行。 大家幸运的发现了一排空座位,但不巧的是座位有6个,但是小明同事一行有7个人,空间不足了,有一个同学没位置坐。 于是谦虚的小强同学说,你们坐吧,我站一会儿就行,于是小明从容器中溢出了。这怎么好意思呢?好基友小明同学说,大家挤挤吧,给小强腾个位置。于是大家腾出了一点位置,小强同学坐下了。

这个例子中,大家占据的位置等比例缩小了,item设置是这样的:

.item {
    flex-shrink: 1; // 空间不足时,大家一起shrink, 溢出问题得到解决。
}

但是问题来了,大家突然想起来小花同学是个孕妇,怎么能让她跟大家一起挤呢?于是小明又发话了,小花你坐到孕妇专座上别动,不要跟大家一起挤。

于是设置变成了这样:

.item:not(#itemHua) {
    flex-shrink: 1;
}

#itemHua {
    flex-shrink: 0;
}

flex-basis: 设置分配多余空间之前单个item占据的主轴空间。

.item {
  flex-basis: <length> | auto; // 默认值为auto,即项目本来的大小
}

后面三个属性可以合并为一个属性flex; 后面两个属性可选。

.item {
    flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
}

该属性有几个快捷值:

  • flex: initial;
  • flex: auto;
  • flex: none;
  • flex:

flex: initial; 等同于flex: 0 1 auto;

全部使用默认值。空间不足时缩小,有余时不变;

flex: auto; 等同于 flex: 1 1 auto;

空间有剩余时放大,空间不足时缩小;

flex: none; 等同于 flex: 0 0 auto; // 不论剩余空间大小,始终保持不变;

flex: 1; 等同于 flex: 1 1 0;

.item {flex: 1;}
// 等同于
.item {
    flex-grow: 1;
    flex-shrink: 1;
    flex-basis: 0%;
}

建议优先使用合并属性,不推荐分开写。 flex值的这种缩写可以参考segmentfault的这篇文章

4.总结

见脑图。

另外归纳一下水平和垂直对齐属性的特点: 水平对齐的属性比较单纯,只有一个,justify-content;

垂直方向的对齐属性有三个:

  • align-items: 最常用,针对单行单列的布局设置垂直对齐方式;
  • align-content: 针对多轴线(交叉轴)的布局设置垂直方向的对齐方式,也就是用于多行多列的布局中,只有一根轴线的情况下是不适用的。
  • align-self: 针对单个item设置垂直方向的对齐方式。

5.参考

Flex布局.语法篇

30分钟彻底搞懂flex布局

A guide to flexbox

CSS指南