快速掌握flex布局

前言

flex布局简化了前端布局问题,例如垂直居中,水平居中等,且目前为止主流浏览器都支持了这种布局,特别是移动端的浏览器,支持度更好。下面是在can i use上查询的结果。从查询的结果来看,支持IE10及以上浏览器,移动端几乎全线支持!

image.png

一、flex布局是什么?

flex布局意思是“弹性布局”,块级元素和行内元素都可以设置为flex布局。

DOM结构

<div class="flex-container">
  <div class="flex-item">1</div>
  <div class="flex-item">2</div>
  <div class="flex-item">3</div>
  ...
</div>

块级元素设置flex布局

.flex-container{
   display:flex;
   display: -webkit-flex; /* Safari */
   display: -ms-flex; /* IE10+ */
}

行内元素设置flex布局

.flex-container{
   display:-webkit-inline-box;
   display:-ms-inline-flexbox;  /* IE10+ */  
   display:inline-flex;  /* Safari */
}

二、flex布局基本概念

flex布局一般包含容器(flex-container)和若干个子元素(flex-item),布局上分为主轴和交叉轴。默认情况下,水平方向为主轴,垂直方向为交叉轴,可以通过设置flex-direction切换主轴和交叉轴(稍后会讲解如何切换)。flex布局的属性比较多,但可以归类为 容器属性子元素属性,教程会先讲解容器的属性,然后讲解子元素的属性,这样比较容易理解和记忆!

图片来源于网络,侵权请告知删除

三、flex容器的属性

flex有6个属性可以设置,它们分别是:

  1. flex-direction
  2. flex-wrap
  3. flex-flow
  4. justify-content
  5. align-items
  6. align-content

3.1 flex-direction属性

DOM结构

<div class="flex-container">
  <div class="flex-item">1</div>
  <div class="flex-item">2</div>
  <div class="flex-item">3</div>
</div>

CSS样式

.flex-container{
  display:flex;
  flex-direction: row | row-reverse | column | column-reverse | initial | inherit;
}
  • row(默认值),水平方向为主轴,垂直方向为交叉轴,起点在左边。
image.png
  • row-reverse: 水平方向为主轴,垂直方向为交叉轴,起点在右边。
image.png
  • column,垂直方向为主轴,水平方向为交叉轴,起点在上边。
image.png
  • column-reverse,垂直方向为主轴,水平方向为交叉轴,起点在下边。
image.png
  • initial,初始值,和默认值效果一样,这里不再贴图。

  • inherit,继承父容器的值,主要在嵌套使用flex布局会用到,父容器设置什么,它就是什么,效果和上面的其中一种相同,这里不再贴图

3.2 flex-wrap属性

DOM结构

<div class="flex-container">
  <div class="flex-item">1</div>
  <div class="flex-item">2</div>
  <div class="flex-item">3</div>
  <div class="flex-item">4</div>
  <div class="flex-item">5</div>
  <div class="flex-item">6</div>
  <div class="flex-item">7</div>
  <div class="flex-item">8</div>
</div>

CSS样式

.flex-container{
  display:flex;
  flex-wrap : nowrap | wrap | wrap-reverse | initial | inherit;
}
  • nowrap(默认值),即使子元素总宽高超出也不换行(列)。
image.png
  • wrap,当子元素总宽高超出时自动换行(列)。
image.png
  • wrap-reverse,换行,第一行在下方(列的情况自行探索,不再贴图)。
image.png
  • initial、inherit的效果和上面介绍的一样,不再赘述!

3.3 flex-flow属性

flex-flow 属性是 flex-direction 和 flex-wrap 属性的复合属性,用于设置或检索弹性盒模型对象的子元素排列方式。flex-direction 属性规定方向, flex-wrap 属性规定是否拆行或拆列。

DOM结构

<div class="flex-container">
  <div class="flex-item">1</div>
  <div class="flex-item">2</div>
  <div class="flex-item">3</div>
  <div class="flex-item">4</div>
  <div class="flex-item">5</div>
  <div class="flex-item">6</div>
  <div class="flex-item">7</div>
  <div class="flex-item">8</div>
</div>

CSS样式

.flex-container{
  display:flex;
  flex-flow: flex-direction flex-wrap  | initial | inherit;
}
  • row wrap,表示水平方向,超出换行。
image.png
  • row nowrap,表示水平方向,超出不换行。
image.png
  • 其他情况也是一样的,就是 flex-direction 和 flex-wrap 组合,这里不做过多赘述。

3.4 justify-content属性

justify-content属性用于设置主轴上元素的排列方式。

DOM结构

<div class="flex-container">
  <div class="flex-item">1</div>
  <div class="flex-item">2</div>
  <div class="flex-item">3</div>
</div>

CSS样式

.flex-container{
  display:flex;
  justify-content: flex-start | flex-end | center | space-between | space-around | initial | inherit;
}
  • flex-start(默认值),子元素靠容器开头排列。
image.png
  • flex-end,子元素靠结尾排列。
image.png
  • center,子元素居中排列。
image.png
  • space-between,两端对齐,子元素之间的间隔相等。
image.png
  • space-around,子元素的两边间隔相等。
image.png

3.5 align-items属性

justify-content属性用于设置交叉轴上元素的排列方式。

DOM结构

<div class="flex-container">
  <div class="flex-item">1</div>
  <div class="flex-item">2</div>
  <div class="flex-item">3</div>
</div>

CSS样式

.flex-container{
  display:flex;
  height: 300px; /* 设置高度,才能看到效果 */
  align-items: stretch | center | flex-start | flex-end | baseline | initial | inherit;
}
  • stretch (默认值),子元素被拉伸以适应容器(1和2设置了高度,3没有设置高度,下同)。
image.png
  • center ,子元素在交叉轴上居中对齐。
image.png
  • flex-start 子元素在交叉轴上靠起始边对齐。
image.png
  • flex-end 子元素在交叉轴上靠结束边对齐。
image.png
  • baseline 子元素在交叉轴上根据字体的baseline对齐(1、2、3字体大小分别为20px、40px、60px)。
image.png

3.6 align-content属性

align-content规定flex-container有剩余空间时,如何分配给子元素。这个属性设置的是所有子元素的对齐方式,需要设置flex-wrap(wrap或wrap-reverse),并且指定flex-container的高度(或宽度)才会生效。

DOM结构

<div class="flex-container">
  <div class="flex-item">1</div>
  <div class="flex-item">2</div>
  <div class="flex-item">3</div>
  <div class="flex-item">4</div>
  <div class="flex-item">5</div>
  <div class="flex-item">6</div>
  <div class="flex-item">7</div>
  <div class="flex-item">8</div>
</div>

CSS样式

.flex-container{
  display: flex;
  background: #eeeeee;
  align-content: center;
  height: 300px;
  flex-wrap: wrap | wrap-reverse;
  align-content:  stretch | center | flex-start | flex-end | space-between | space-around | initial | inherit;
}
  • stretch(默认值),子元素被拉伸以适应容器(临时去掉了flex-item的高度)。
image.png
  • center,子元素(整体)在交叉轴上居中对齐(恢复flex-item的高度为100px,下同)。
image.png
  • flex-start,子元素(整体)向交叉轴起始位置对齐。
image.png
  • flex-end,子元素(整体)向交叉轴结束位置对齐。
image.png
  • space-between ,子元素行(列)向交叉轴两边对齐(建议亲自尝试,文字功底不好,描述得不好~)。
image.png
  • space-around ,子元素行(列)两边均分容器剩余空间(建议亲自尝试,文字功底不好,描述得不好~)。
image.png

四、子元素(容器)的属性

flex子属性有6个属性可以设置,它们分别是:

  1. order
  2. flex-grow
  3. flex-shrink
  4. flex-basis
  5. flex
  6. align-self

4.1 order属性

order属性定义项目的排列顺序。数值越小,排列越靠前,默认为0。

DOM结构

<div class="flex-container">
    <div class="flex-item">1</div>
    <div class="flex-item">-1</div>
    <div class="flex-item">0</div>
    <div class="flex-item">未设置order</div>
</div>

CSS样式

.flex-container{
  display:flex;
}
.flex-item{
  order: number | initial | inherit;
}
  • number,可以设置任意数字,数字越小越靠前(和DOM的位置无关)。
image.png

4.2 flex-grow属性

  • flex-grow属性定义子元素的放大比例,默认为0,即如果存在剩余空间,也不放大;

DOM结构

<div class="flex-container">
  <div class="flex-item">0</div>
  <div class="flex-item">1</div>
  <div class="flex-item">2</div>
  <div class="flex-item">3</div>
</div>

CSS样式

.flex-container {
  display: flex;
  background: #eeeeee;
}
.flex-item {
  flex-grow: flex-grow: number | initial | inherit;
}
  • number,可以设置任何大于等于0的数字,数字越大,分到的剩余空间比例就越大。
image.png

4.3 flex-shrink属性

  • flex-shrink属性定义了子元素的缩小比例,默认为1,即如果空间不足,该项目将缩小。负值对该属性无效;

DOM结构

<div class="flex-container">
  <div class="flex-item">0</div>
  <div class="flex-item">1</div>
  <div class="flex-item">2</div>
  <div class="flex-item">3</div>
  <div class="flex-item">4</div>
  <div class="flex-item">5</div>
  <div class="flex-item">6</div>
  <div class="flex-item">7</div>
</div>

CSS样式

.flex-container {
  display: flex;
  background: #eeeeee;
}
.flex-item {
  background: #b48882;
  flex-shrink: number | initial | inherit; 
}
  • number, 数值越大,缩小比例就越大。
image.png

4.4 flex-basis属性

flex-basis属性用于设置子元素的伸缩基准值,默认值为auto,即元素本身的大小。如果子元素同时设置宽高和flex-basis属性,flex-basis的优先级更高。

DOM结构

<div class="flex-container">
  <div class="flex-item">width:100px</div>
  <div class="flex-item">flex-basis: 200px;</div>
  <div class="flex-item">flex-basis: 300px;</div>
  <div class="flex-item">flex-basis: 400px;</div>
</div>

CSS样式

.flex-container {
  display: flex;
  background: #eeeeee;
}
.flex-item{
  flex-basis: auto | number | initial | inherit;
}
  • number,子元素设置的数值越大,占用剩余空间的比例越大。
image.png

4.5 flex属性

flex属性是flex-grow、flex-shrink 和 flex-basis的简写,默认值为0 1 auto。后两个属性可选。flex支持缩写,例如经常用到的:flex: 1,等价于flex: 1 1 0%

DOM结构

<div class="flex-container">
  <div class="flex-item">1</div>
  <div class="flex-item">2</div>
  <div class="flex-item">3</div>
</div>

CSS样式

.flex-container {
  display: flex;
  background: #eeeeee;
}
.flex-item{
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100px;
  height: 100px;
  margin: 5px;
  flex: flex-grow [flex-shrink] [flex-basis]  | auto | none | 1 | 0 | initial | inherit;
}
  • flex:1,等价于flex: 1 1 0%
image.png
  • flex: 0,等价于 flex: 0 1 0%
image.png
  • flex: auto ,等价于flex: 1 1 auto
image.png
  • flex: none,等价于flex: 0 0 auto
image.png
  • 当取值为一个具体值或百分比时,例如:flex: 0%等价于flex: 1 1 0%,设置的是flex-basis的值
image.png
  • 当 flex 取值为两个非负数字,则分别视为 flex-grow 和 flex-shrink 的值,flex-basis 取 0%,例如:flex:2 3 等价于flex 2 3 0%(下图给第一个子元素设置flex:2 3)。
image.png
  • 当 flex 取值为一个非负数字和一个长度或百分比,则分别视为 flex-grow 和 flex-basis 的值,flex-shrink 取 1。例如:flex: 2 200px 等价于 flex: 2 1 200px(下图给第一个子元素设置flex:2 200px)。
image.png

4.6 align-self属性

align-self 允许单个子元素设置与其他项目不一样的对齐方式,默认值:auto。
DOM结构

<div class="flex-container">
  <div class="flex-item">1</div>
  <div class="flex-item">2</div>
  <div class="flex-item">3</div>
</div>

CSS样式

.flex-container {
  display: flex;
  background: #eeeeee;
  height:300px;
}
.flex-item{
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100px;
  height: 100px;
  margin: 5px;
  align-self: auto | stretch | center | flex-start | flex-end | baseline | initial | inherit;
}
  • auto(默认值),元素继承了它的父容器的 align-items 属性。如果没有父容器则为 "stretch"
image.png
  • stretch ,元素被拉伸以适应容器(子元素2高度设置为auto,align-self设置为stretch)。
image.png
  • center,元素位于容器的中心(子元素2的align-self设置为center)。
image.png
  • flex-start,元素位于容器的起始位置(子元素2的align-self设置为center)。
image.png
  • flex-end,元素位于容器的结束位置(子元素2的align-self设置为end)。
image.png
  • baseline ,元素以自身文字基线为对齐方式,对齐到主轴中(子元素2align-self设置为baseline ,font-size:60px;height:auto
image.png

最后,奉献一个九宫格布局的例子:https://codepen.io/linlif/pen/zYYRejb,效果图如下:

flex实现九宫格布局

本文完

参考资料:
30 分钟学会 Flex 布局
Flex 布局语法教程

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