学好Flex布局并不容易

1. Flex布局介绍

CSS的传统布局解决方案,基于盒状模型,依赖display属性、position属性、float属性,对于一些特殊的布局,例如垂直居中,往往要想很多hack的方法来解决。

2009年,W3C提出了一种新的方案--Flex布局,可以简便、完整、响应式地实现各种页面布局。目前,它已经得到了所有浏览器的支持,这意味着,现在就能很安全地使用这项功能。Flex布局的主要思想是为容器赋予控制容器内元素的高度、宽度以及如何分割容器空间的能力。

Flex是Flexible Box的缩写,表示“弹性布局”的意思,能够为盒状模型提供最大的灵活性。任何一个容器都可以指定为flex布局,使用flex布局以后,子元素的floatclearvertical-align元素都将失效。

.box {
    display: flex;
}

行内元素也可以使用Flex布局。

.box {
    display: inline-flex;
}

Webkit内核的浏览器,必须加上-webkit前缀。

.box{
  display: -webkit-flex; /* Safari */
  display: flex;
}

2. 基本概念

采用Flex布局的元素,称为Flex容器(flex container),简称”容器”。它的所有子元素自动成为容器成员,称为Flex项目(flex item),简称”项目”。容器默认存在两根轴:水平的主轴(main axis)和垂直的交叉轴(cross axis)。主轴的开始位置(与边框的交叉点)叫做main start,结束位置叫做main end;交叉轴的开始位置叫做cross start,结束位置叫做cross end。项目默认沿主轴排列。单个项目占据的主轴空间叫做main size,占据的交叉轴空间叫做cross size。

1baaa865d658f00e45697c2a61fa4ab3.png

下面对这几个概念作简要介绍:

  • 主轴 main-axis,flex容器的主轴是容器内项目 flex item的排列方向。主轴方向并不一定是水平的,这个由flex-direction属性决定。
  • main-start | main-end ,容器内项目的排列是从main-start到main-end。
  • main-size
  • 交叉轴 cross axis 与主轴垂直的交叉轴,它的方向由主轴的方向决定
  • cross-start | cross-end
  • cross-size

3. Flex容器的属性

Flex容器具有以下六个属性。

  • display 该属性决定flex布局的容器,display:flex;
  • flex-direction 该属性决定主轴的方向(即项目的排列方向)
  • flex-wrap 该属性决定flex元素的换行方式,默认情况下容器内项目总是倾向于排列在一行内
  • flex-flow 该属性是directionwrap的组合属性,默认值是row nowrap
  • justify-content 该属性定义容器中项目在主轴上的对齐方式
  • align-items
  • align-content

3.1 flex-direction

flex-direction属性决定主轴的方向(即容器元素的排列方向),有四个取值。

  • row(默认值),主轴为水平方向,起点在左端。
  • row-reverse,主轴为水平方向,起点在右端。
  • column,主轴为垂直方向,起点在上沿。
  • column-reverse,主轴为垂直方向,起点在下沿。
.box {
  flex-direction: row | row-reverse | column | column-reverse;
}

3.2 flex-wrap

熟悉wrap的同学应该知道,这个属性是决定如何处理一行显示不下的情况,有三个属性:

  • nowrap 不换行
  • wrap 换行,第一行在上,往下折行
  • wrap-reverse 换行,第一行在下,往上折行
.box {
    flex-wrap: nowrap | wrap | wrap-reverse;
}

3.3 flex-flow

flex-flowflex-directionflex-wrap组合属性的简写,默认值为row nowrap

.box {
    flex-flow: <flex-direction> || <flex-wrap>;
}

3.4 justify-content

justify-content定义项目在主轴上的对齐方式,还能够帮助我们分配容器项目以外的剩余空间,即便是没有剩余空间。有以下属性:

  • flex-start(默认值): 主轴的起点对齐
  • flex-end: 主轴的终点对齐
  • center: 沿主轴居中对齐
  • space-between: 两端对齐,项目之间的间隔相等
  • space-around: 每个项目两侧的间隔相等,所以项目之间的间隔比左右两边的间隔大一倍
  • space-evenly: 每个项目的间隔以及两侧的间隔都相等
  • start: 容器内的项目堆在书写方向writing-mode的开始
  • end: 容器内的项目堆在书写方向writing-mode的结束
  • lfet: 容器内的项目堆在容器的左边
  • right: 容器内的项目堆在容器的右边
  • safe:
  • unsafe:

注意不同浏览器对这些属性的支持程度还不太一样,space-between从未在Edge浏览器上获得过支持,最安全的几个属性是flex-startflex-endcenter

image.png
.box {
    justify-content: flex-start | flex-end | center | space-between | space-around;
}

3.5 align-items

align-items 该属性决定项目在交叉轴上如何对齐,有以下属性:

  • flex-start 交叉轴的起点对齐
  • flex-end 交叉轴的终点对齐
  • center 交叉轴的中间对齐
  • start 书写方向的起点对齐
  • end 书写方向的终点对齐
  • baseline 项目的第一行文字的基线对齐
  • stretch(默认值) 如果项目未设置高度或设为auto,项目将占满整个容器的高度,这样做两列布局再也不用发愁高度不一致了。

在flex布局中有主轴和侧轴的区分,和我们一般认为的横轴为主轴、纵轴为侧轴的固定认知不同,flex布局中主轴和侧轴会发生变化,这是由之前flex-direction属性决定的。当flex-direction:row的时候,主轴就是横轴,要调整元素在横轴的排列就需要使用justify-content属性。当flex-direction:column的时候,主轴就是纵轴,要调整元素在横轴的排列就需要使用align-items属性。

3.6 align-content

这个属性决定当容器在交叉轴方向还有剩余空间时,项目的排列方式。

这个属性在只有一行容器内项目时无效,在设置了nowrap时也无效。

  • flex-start
  • flex-end
  • center
  • space-between
  • space-around
  • space-evenly
  • stretch
  • baseline

4. 项目的属性

项目包括6个属性

  • order 该属性定义项目的排列顺序。数值越小,排列越靠前,默认为0。通过css就能控制DOM元素的顺序,简直太方便了。
  • flex-grow 该属性定义项目放大的比例,默认为0,也就是项目的大小不会发生缩放。
  • flex-shrink
  • flex-basis
  • flex
  • align-self

4.1 order

order 属性定义项目的排列顺序。数值越小,排列越靠前,默认为0。通过css就能控制DOM元素的顺序,简直太方便了。

.item {
    order: <integer>;
}

4.2 flex-grow

flex-grow属性定义项目相对于其他项目进行扩展的量,默认为0。注意:如果项目不是flex item,则 flex-grow 属性不起作用。如果所有的项目都设置为1,则每个项目分到的空间都一样。如果有一个设置为2,则它分到的空间要比其他项目多一倍。负数无效。

.item {
    flex-grow: <number>;

4.3 flex-shrink

flex-shrink 属性定义项目相对于其他项目缩小的比例。负数无效。

.item {
    flex-shrink: <number>
}

4.4 flex-basis

flex-basis 属性定义了在分配多余空间之前,项目占据的主轴空间(main size)。浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为auto,即项目的本来大小。

.item {
    flex-basis: <length> | auto;
}

4.5 flex

flex属性是flex-grow,flex-shrink,flex-basis组合,默认值为0 1 auto后两个属性可选。

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

4.6 align-self属性

align-self属性允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性。默认值为auto,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch。属性支持的值包括:

  • auto
  • flex-start
  • flex-end
  • center
  • baseline
  • stretch

5. 浏览器支持

flexbox从出现到现在经历了多个版本,下图new的含义表示现在的语法display:flex;tweener表示2011年后出现的一个非官方的写法display:flexbox;old表示2009年出现后的旧语法display:box;

image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,802评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,109评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,683评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,458评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,452评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,505评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,901评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,550评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,763评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,556评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,629评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,330评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,898评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,897评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,140评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,807评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,339评论 2 342