目前在不考虑IE以及低端安卓机(4.3-)的兼容下,已经可以放心使用flex进行布局了。什么是flex布局以及它的好处,这里就不再赘述。

在这篇文章里,想说说flex布局的属性语法及其细节。那么网上也有不少flex布局的教程,为什么又要再写一篇?

首先,flex布局的迷之属性们,如果一知半解,机械记忆的话,那不到半个月基本忘光光。先感受一下这12个flex布局属性,是不是很“迷”人。

容器属性

  • flex-flow
  • flex-direction
  • flex-wrap
  • justify-content
  • align-items
  • align-content

元素属性

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

就连老外也都在twitter吐槽不好理解,可见还是有一定的学习成本。

而目前很多flex教程主要以列举属性为主,缺乏对比和理解性脉络。

因此,下面会通过我梳理的一个脉络去理解flex布局,包括不同属性的异同以及一些容易造成误解的细节点,彻底弄懂flex布局。

一、flex弹性盒模型

对于某个元素只要声明了display: flex;,那么这个元素就成为了弹性容器,具有flex弹性布局的特性。

  1. 每个弹性容器都有两根轴:主轴和交叉轴,两轴之间成90度关系。注意:水平的不一定就是主轴。
  2. 每根轴都有起点和终点,这对于元素的对齐非常重要。
  3. 弹性容器中的所有子元素称为<弹性元素>,弹性元素永远沿主轴排列
  4. 弹性元素也可以通过display:flex设置为另一个弹性容器,形成嵌套关系。因此一个元素既可以是弹性容器也可以是弹性元素

弹性容器的两根轴非常重要,所有属性都是作用于轴的。下面从轴入手,将所有flex布局属性串起来理解。

二、主轴

flex布局是一种一维布局模型,一次只能处理一个维度(一行或者一列)上的元素布局,作为对比的是二维布局CSS Grid Layout,可以同时处理行和列上的布局。

也就是说,flex布局大部分的属性都是作用于主轴的,在交叉轴上很多时候只能被动地变化

1. 主轴的方向

我们可以在弹性容器上通过flex-direction修改主轴的方向。如果主轴方向修改了,那么:

  1. 交叉轴就会相应地旋转90度。
  2. 弹性元素的排列方式也会发生改变,因为弹性元素永远沿主轴排列
flex-direction:row
flex-direction:column
flex-direction:row-reverse
flex-direction:column-reverse

2. 沿主轴的排列处理

弹性元素永远沿主轴排列,那么如果主轴排不下,该如何处理?

通过设置flex-wrap: nowrap | wrap | wrap-reverse可使得主轴上的元素不折行、折行、反向折行。

默认是nowrap不折行,难道任由元素直接溢出容器吗?当然不会,那么这里就涉及到元素的弹性伸缩应对,下面会讲到。

wrap折行,顾名思义就是另起一行,那么折行之后行与行之间的间距(对齐)怎样调整?这里又涉及到交叉轴上的多行对齐。

wrap-reverse反向折行,是从容器底部开始的折行,但每行元素之间的排列仍保留正向。

3. 一个复合属性

flex-flow = flex-drection + flex-wrap

flex-flow相当于规定了flex布局的“工作流(flow)”

flex-flow: row nowrap;

三、元素如何弹性伸缩应对

flex-wrap: nowrap;不折行时,容器宽度有剩余/不够分,弹性元素们该怎么“弹性”地伸缩应对?

这里针对上面两种场景,引入两个属性(需应用在弹性元素上)

  1. flex-shrink:缩小比例(容器宽度<元素总宽度时如何收缩)
  2. flex-grow:放大比例(容器宽度>元素总宽度时如何伸展)

1. flex-shrink: 缩小比例

来看下以下场景,弹性容器#container宽度是200px,一共有三个弹性元素,宽度分别是50px、100px、120px。在不折行的情况下,此时容器宽度是明显不够分配的。

实际上,flex-shrink默认为1,也就是当不够分配时,元素都将等比例缩小,占满整个宽度,如下图。

#container {display: flex;flex-wrap: nowrap; }

元素收缩的计算方法

真的是等比缩小(每个元素各减去70/3的宽度)吗?这里稍微深究一下它的收缩计算方法。

  1. 弹性元素1:50px→37.03px
  2. 弹性元素2:100px→74.08px
  3. 弹性元素3:120px→88.89px

先抛结论:flex-shrink: 1并非严格等比缩小,它还会考虑弹性元素本身的大小

  • 容器剩余宽度:-70px
  • 缩小因子的分母:1*50 + 1*100 + 1*120 = 270 (1为各元素flex-shrink的值)
  • 元素1的缩小因子:1*50/270
  • 元素1的缩小宽度为缩小因子乘于容器剩余宽度:1*50/270 * (-70)
  • 元素1最后则缩小为:50px + (1*50/270 *(-70)) = 37.03px

加入弹性元素本身大小作为计算方法的考虑因素,主要是为了避免将一些本身宽度较小的元素在收缩之后宽度变为0的情况出现。

2. flex-grow: 放大比例

同样,弹性容器#container宽度是200px,但此时只有两个弹性元素,宽度分别是50px、100px。此时容器宽度是有剩余的。

那么剩余的宽度该怎样分配?而flex-grow则决定了要不要分配以及各个分配多少。

(1)在flex布局中,容器剩余宽度默认是不进行分配的,也就是所有弹性元素的flex-grow都为0。

(2)通过指定flex-grow为大于零的值,实现容器剩余宽度的分配比例设置。

元素放大的计算方法

放大的计算方法并没有与缩小一样,将元素大小纳入考虑。

仅仅按flex-grow声明的份数算出每个需分配多少,叠加到原来的尺寸上。

  • 容器剩余宽度:50px
  • 分成每份:50px / (3+2) = 10px
  • 元素1放大为:50px + 3 * 10 = 80px

无多余宽度时,flex-grow无效

下图中,弹性容器的宽度正好等于元素宽度总和,无多余宽度,此时无论flex-grow是什么值都不会生效。

同理,对于flex-shrink,在容器宽度有剩余时也是不会生效的。因此这两个属性是针对两种不同场景的互斥属性。

四、弹性处理与刚性尺寸

在进行弹性处理之余,其实有些场景我们更希望元素尺寸固定,不需要进行弹性调整。设置元素尺寸除了width和height以外,flex还提供了一个flex-basis属性。

flex-basis设置的是元素在主轴上的初始尺寸,所谓的初始尺寸就是元素在flex-growflex-shrink生效前的尺寸。

1. 与width/height的区别

首先以width为例进行比较。看下下面的例子。#container {display:flex;}

<div id="container"><div>11111</div> <div>22222</div> </div>

(1) 两者都为0

  • width: 0 —— 完全没显示
  • flex-basis: 0 —— 根据内容撑开宽度

(2) 两者非0

  • width: 非0;
  • flex-basis: 非0

—— 数值相同时两者等效

—— 同时设置,flex-basis优先级高

(3) flex-basis为auto

flex-basis为auto时,如设置了width则元素尺寸由width决定;没有设置则由内容决定

(4) flex-basis == 主轴上的尺寸 != width

  • 将主轴方向改为:上→下
  • 此时主轴上的尺寸是元素的height
  • flex-basis == height

2. 常用的复合属性 flex

这个属性应该是最容易迷糊的一个,下面揭开它的真面目。

flex = flex-grow + flex-shrink + flex-basis

复合属性,前面说的三个属性的简写。

一些简写

  • flex: 1 = flex: 1 1 0%
  • flex: 2 = flex: 2 1 0%
  • flex: auto = flex: 1 1 auto;
  • flex: none = flex: 0 0 auto; // 常用于固定尺寸 不伸缩

flex:1 和 flex:auto 的区别

其实可以归结于flex-basis:0flex-basis:auto的区别。

flex-basis是指定初始尺寸,当设置为0时(绝对弹性元素),此时相当于告诉flex-growflex-shrink在伸缩的时候不需要考虑我的尺寸;相反当设置为auto时(相对弹性元素),此时则需要在伸缩时将元素尺寸纳入考虑。

因此从下图(转自W3C)可以看到绝对弹性元素如果flex-grow值是一样的话,那么他们的尺寸一定是一样的。

五、容器内如何对齐

前面讲完了元素大小关系之后,下面是另外一个重要议题——如何对齐。可以发现上面的所有属性都是围绕主轴进行设置的,但在对齐方面则不得不加入作用于交叉轴上。需要注意的是这些对齐属性都是作用于容器上。

1. 主轴上的对齐方式

justify-content

2. 交叉轴上的对齐方式

主轴上比较好理解,重点是交叉轴上。因为交叉轴上存在单行和多行两种情况。

交叉轴上的单行对齐

align-items

默认值是stretch,当元素没有设置具体尺寸时会将容器在交叉轴方向撑满。

align-items不为stretch时,此时除了对齐方式会改变之外,元素在交叉轴方向上的尺寸将由内容或自身尺寸(宽高)决定。

注意,交叉轴不一定是从上往下,这点再次强调也不为过。

交叉轴上的多行对齐

还记得可以通过flex-wrap: wrap使得元素在一行放不下时进行换行。在这种场景下就会在交叉轴上出现多行,多行情况下,flex布局提供了align-content属性设置对齐。

align-contentalign-items比较类似,同时也比较容易迷糊。下面会将两者对比着来看它们的异同。

首先明确一点:align-content只对多行元素有效,会以多行作为整体进行对齐,容器必须开启换行。

align-content: stretch | flex-start | flex-end | center | space-between | space-around align-items: stretch | flex-start | flex-end | center | baseline

在属性值上,align-contentalign-items多了两个值:space-betweenspace-around

align-content与align-items异同对比

align-items一样,align-content:默认值也是stretch。两者同时都为stretch时,毫无悬念所有元素都是撑满交叉轴。

#container {align-items: stretch;align-content: stretch; }

当我们将align-items改为flex-start或者给弹性元素设置一个具体高度,此时效果是行与行之间形成了间距。

#container {align-items: flex-start;align-content: stretch; } /*或者*/ #container { align-content: stretch; } #container > div { height: 30px; }

为什么?因为align-content会以整行为单位,此时会将整行进行拉伸占满交叉轴;而align-items设置了高度或者顶对齐,在不能用高度进行拉伸的情况下,选择了用间距。

尝试把align-content设置为顶对齐,此时以行为单位,整体高度通过内容撑开。

align-items仅仅管一行,因此在只有第一个元素设置了高度的情况下,第一行的其他元素遵循align-items: stretch也被拉伸到了50px。而第二行则保持高度不变。

#container {align-items: stretch;align-content: flex-start; } #container > div:first-child { height: 50px; }

两者的区别还是不明显?来看下面这个例子。

这里仅对第二个元素的高度进行设置,其他元素高度则仍保持内容撑开。

以第一个图为例,会发现align-content会将所有行进行顶对齐,然后第一行由于第二个元素设置了较高的高度,因此体现出了底对齐。

两者差异总结:

  • 两者“作用域”不同
  • align-content管全局(所有行视为整体)
  • align-items管单行

能否更灵活地设置交叉轴对齐

除了在容器上设置交叉轴对齐,还可以通过align-self单独对某个元素设置交叉轴对齐方式。

  1. 值与align-items相同
  2. 可覆盖容器的align-items属性
  3. 默认值为auto,表示继承父元素的align-items属性
#container {display: flex;align-items: flex-start; } #container > div:first-child { align-self: stretch; } #container > div:nth-child(3) { align-self: center; } #container > div:nth-child(4) { align-self: flex-end; }

六、其他

order:更优雅地调整元素顺序

#container > div:first-child {order: 2; } #container > div:nth-child(2) { order: 4; } #container > div:nth-child(3) { order: 1; } #container > div:nth-child(4) { order: 3; }

order:可设置元素之间的排列顺序

  1. 数值越小,越靠前,默认为0
  2. 值相同时,以dom中元素排列为准

七、总结

参考阮老师博文中的骰子练习,我做了张图,大家不妨可以各自实现下,理解之后应该能够比较轻松地写出来。codepen

转载于:https://www.cnblogs.com/zhilin/p/10497584.html

30分钟彻底弄懂flex布局相关推荐

  1. 彻底弄懂flex布局

    目前在不考虑IE以及低端安卓机(4.3-)的兼容下,已经可以放心使用flex进行布局了.什么是flex布局以及它的好处,这里就不再赘述. 在这篇文章里,想说说flex布局的属性语法及其细节.那么网上也 ...

  2. 台式电脑怎么连wifi,1分钟轻松弄懂

    电脑已经成为了各位小伙伴日常生活中经常会使用的工具.笔记本电脑连接wifi很简单,相信很多小伙伴都会,可是面对台式电脑,很多小伙伴就不知道怎么连wifi了.台式电脑怎么连wifi?别担心,1分钟教你轻 ...

  3. 前端笔记(03)——一文看懂flex布局

    文章目录 前言 一.flex基本介绍. 二.父容器属性介绍 1.父容器属性概述 2.flex-direction属性 3.flew-wrap属性 4.flex-flow复合写法 5.justify-c ...

  4. 【Java】还不懂this关键字?一分钟彻底弄懂this关键字

    博主简介:努力学习的预备程序媛一枚~ 博主主页: @是瑶瑶子啦 所属专栏: Java岛冒险记[从小白到大佬之路] 前言 问题:为什么会存在this? 在上一篇[JavaSE]一文看懂构造器/构造方法( ...

  5. 详解正则表达式,30分钟彻底搞懂正则

           最近做的项目需求中,部分表单输入框验证需要用到正则表达式用于保证输入数据的正确性.考虑到平时爬虫也需要正则表达式,故晚上花费一点时间学习下正则表达式.直接看内容,加上在线练习,30min ...

  6. 什么是分布式微服务架构?三分钟彻底弄懂什么是分布式和微服务

    一.微服务简介 1. 微服务的诞生 微服务是基于分而治之的思想演化出来的.过去传统的一个大型而又全面的系统,随着互联网的发展已经很难满足市场对技术的需求,于是我们从单独架构发展到分布式架构,又从分布式 ...

  7. 十分钟彻底弄懂浏览器缓存机制原理

    前言 Http 缓存机制作为 web 性能优化的重要手段,对于从事 Web 开发的同学们来说,应该是知识体系库中的一个基础环节,同时对于有志成为前端架构师的同学来说是必备的知识技能. 但是对于很多前端 ...

  8. 30 分钟学会 Flex 布局

    30 分钟学会 Flex 布局 关注公众号 风色年代(itfantasycc) 更多好玩的前端资料等你拿~~ 林东洲 30 分钟学会 Flex 布局 - 知乎 (zhihu.com) 为什么我要写这一 ...

  9. 一篇让你弄懂是什么是flex布局

    一.flex布局与传统布局 传统布局:兼容性好.布局繁琐且不能较好地在移动端布局 flex布局:布局简单方便,很适合在移动端布局,但存在版本兼容支持问题 二.flex布局原理 flex 是 flexi ...

最新文章

  1. 【PC工具】更新免费文库文档下载器,破解文库下载器,免费下载文库文档
  2. 网易智慧企业亮相TOP 100 Summit,以创新和匠心探索行业前沿
  3. boost::mp11::mp_bind_front_q相关用法的测试程序
  4. 【Linux】基于Openfile的multipath测试
  5. HDU-2473 Junk-Mail Filter(并查集的使用)
  6. 微信小程序云开发-时间存储、转换、比较
  7. java web参考文献_javaweb外文参考文献
  8. 《商务与经济统计》练习:案例8-1:杂志订阅者问卷调查分析
  9. U盘启动 WinPE系统维护工具 任意安装GHO/WIM/ESD系统映像 无广告专业版
  10. AE快速输出GIF动图格式插件:GifGun for Mac(支持ae2022)
  11. python中的round
  12. mac为什么不支持ntfs,mac读取ntfs移动硬盘软件有哪些
  13. 用完加速器国内的网址打不开了?
  14. 教师资格证面试试讲规律!
  15. vb访问服务器文件,VB6打开远程服务器文件
  16. Windows和Xyplorer的完美结合
  17. 战争教育策略游戏 MiracleGame,开启新阶段重塑生态和玩法
  18. 消息队列-beanstalkd
  19. iostream与iostream.h乱弹琴
  20. 一键备份脚本backup.sh

热门文章

  1. netback于kthread遇到cpu affinity问题
  2. Ranorex中Global变量的使用
  3. 问题 A: 编写函数:比较三个数大小 (Append Code)
  4. 同一个电脑安装几个MATLAB,同一个版本的matlab、同一个.m文件,为何一个顺利执行、另一个出错?...
  5. python字符串取消转义_python取消转义,除了r还有什么?可以调用函数取消转义吗?...
  6. android studio如何设置输出值的小数点_C语言基础知识:printf的输出格式,C/C++语言编程讲解...
  7. ros开发语言python效率_Python 的开发效率真的比 Java高吗?
  8. Python接口自动化之动态数据处理
  9. 今日恐慌与贪婪指数为72 贪婪程度与昨日持平
  10. Amber Group与1Token达成合作,引入CAM系统加码机构级财务方案