想象一双结实而富有弹性的大腿:理解 Flexbox 布局

说明

本站不支持 CodePen 的脚本插入,可以到我的博客阅读直接显示示例代码的版本。


Flexbox 让人困惑

有很多谈及 Flexbox 的文章,但依然有不少前端对此感到困惑。一方面,flex 相关的 CSS 属性繁多,影响到的具体效果也包含多个方面;另一方面,CSS 可以使用 Shorthand properties 风格的写法(例如最常见的 background: url(images/bg.gif) no-repeat left top;),很容易让新手弄不清具体含义。

这篇文章要讲的 Flexbox 当然还是 CSS3 规范中的弹性盒模型,不过写出前面一段,是因为我希望这篇文章可以解决那些问题——简单说,就是 Flexbox 让人困惑这样的问题。解决的方法,就是理解它


什么时候,我们会想到弹性

为了理解弹性盒模型,先要从古龙的笔法开始。古龙是台湾的武侠小说大师,成就仅次于金庸。古龙描写的一些人物,非常深入人心,其犀利以及令人难忘的程度,甚至超过金庸。比如,有一位中年男性,在整部小说里,他的手非常重要,古龙对此有多次描写——“他的手指修长而有力”。而在不止一本书中,不止一两个情节中,有几位青年女性,她们的腿非常重要,古龙的描述是——“大腿结实而富有弹性”,或者“修长结实而富有弹性”。

轻呼一口气,思考一下,为什么描写手指的时候要说“修长而有力”,而描写大腿却是“结实而富有弹性”?这真是一个非常值得思考的问题。实际上,人的腿也可以是“修长而有力”的;而且,人的手指也是有弹性的。但古大师的描写绝非随意为之,其中的道理,可以随便找些包含大腿的人物画看一看,或者只是想象一下——一幅人物画中,手指的面积有多大?除非为了强调手部而加了特技,否则手指所占的面积是很小的;而大腿,在一幅正常的人物画中,是充满空间的。这里说的充满,当然并不是指完全占满空间,也不是上下左右一定没有空隙。

记住这种“充满”,现在思考一下 Flexbox。什么时候,我们会想到或者说需要弹性这件事情?答案是当我们需要“充满”一个容器的时候。带着这种思考,再回到人物画。手指只是在画面的特定位置,解决这种问题,我们可以简单地用 position: absolute; 或 float: left; 这些属性搞定。而大腿是“充满”画面的,当我们需要“充满”容器的时候,弹性就很重要!要解决这类问题,我们应该思考的就不是某个局部的空间,而是空间的分配。包括如何分配容器内的所有盒子,如果空间过大怎么办,如果空间过小怎么办;而在移动端,设备的屏幕尺寸有很多种,问题就变成了空间有时候大、有时候小怎么办。

读者应该已经能够想到,弹性盒模型就是为了更方便地解决这些问题而产生的。那么先看一看非弹性的盒子遇到这些场景会有哪些不便。


百分比网格

See the Pen understanding-css-flexbox 1: percentage by Alpha Bao (@AlphaBao) on CodePen.

上面是用浮动和百分比的方式写的横向网格,由于直接给其中一个设置了不同的高度,很明显,可以看出,四个格子的高度是不同的。如果格子的高度变化是由其中的内容引起,也会存在同样的问题。

另外,示例之中是四个格子,所以设置每个格子为 width: 25%; 就可以让它们横向充满父级容器,而且大小变化也没有影响。但如果需要渲染的数据是动态的,写成具体某个百分比显然就不行了。即元素个数变化时每个元素的百分比也需要变化,就需要修改 CSS。

这些问题都是因为这样的盒模型是没有“弹性”的,如果有弹性,就可以让布局按照我们希望的方式渲染。


Flex 网格

.container {display: flex;
}

弹性盒模型带来了 Flexbox 布局,像上面这样,给充当 container 的盒子设置 display: flex;就可以让它的子元素弹性排列,默认是横向的,因为 flex-direction: row; 是默认值,我们先不关心它。先看一下最常用的属性 flex-grow


flex-grow

See the Pen understanding-css-flexbox 2: flex-grow by Alpha Bao (@AlphaBao) on CodePen.

可以看到其中一个是 flex-grow: 2;,其他都是 1,意思是这些子元素将充满容器,它们将容器分成了若干份,每个 flex-grow: 1; 元素占据一份,flex-grow: 2; 的占两份,因为它的 flex-grow 值是其他元素的两倍。也就是说,flex-grow 决定子元素如何膨胀。在 Flexbox 的充满/填充策略中,flex-grow 影响的是元素膨胀到多大。注意这其实是如何分配父级容器空间的问题,而且是容器大小会改变的情形下,所以具体子元素的大小是取决于空间剩余情况的,并不是 flex-grow 越大,元素就一定会越大。


flex-basis

再看 flex-basis 属性,它是指元素的初始大小,上一个例子中,只设置了 flex-grow,所以初始大小就是元素内容决定的,如果元素没有内容,大小就是零。

See the Pen understanding-css-flexbox 3: flex-basis by Alpha Bao (@AlphaBao) on CodePen.

flex-basis 的默认值是 auto,是指元素的大小(本文中指的是元素横向的长度,因为 flex-direction 默认值是 row,这决定了 main axis(主轴)是横向的,即容器的子元素横向排列)根据元素的长度属性或者由内容决定。可以是具体长度值也可以是百分比。

.c3 {width: 15em;flex-basis: auto;
}

此时初始宽度是 15em,也可以写为下面这样:

.c3 {flex-basis: 15em;
}

两种写法效果相同。

计算完初始大小,再根据容器空间剩余情况,继续完成“充满”容器这件事情。如果先只考虑空间还有剩余的情况,前面提到的 flex-grow 属性就开始起作用,使元素膨胀,直到充满容器。


flex-shrink

前面考虑的都是空间还有剩余的情况,接下来考虑一下空间不足的情况。首先要弄清楚,具体怎样会导致空间不足。

See the Pen understanding-css-flexbox 4: flex-shrink by Alpha Bao (@AlphaBao) on CodePen.

可以看到,通过设置宽度或者由内容填充,此时可能导致空间不足。此时 flex-shrink 会起作用。首先计算初始大小,再考虑空间不足的情况,这时候根据 flex-shrink 的值决定如何收缩各个元素,数值越大,相对其他元素的收缩倍数就越大。flex-shrink 默认值是 1,即不改变这个属性值的情况下,空间不足时每个元素的收缩程度相同。如果改为 0,则不收缩。


flex

flex 是上面三者的简写形式(这类写法的属性就是 Shorthand properties)。

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

See the Pen understanding-css-flexbox 5: flex by Alpha Bao (@AlphaBao) on CodePen.

上面的每个子元素都设置了 flex: 1 1 100px;,即初始宽度值是 100px,如果空间剩余,每个元素平均分配,如果空间不足,每个元素同等程度的收缩。flex: 0 1 auto; 是 flex 属性的默认值,表示不膨胀(如果都不膨胀,那么有剩余空间也不会充满),收缩因数是 1,元素在主轴方向上的长度取决于长度值或者元素内容。

通过上面几个例子,可以看得出在大小会动态变化的父级容器里面,这种分配空间的策略优势很明显,这就是弹性带来的便利。flex 是实际开发中常用的写法,它的内容其实就是如何“充满”容器空间的策略,是 Flexbox 中最重要的部分。


结束语

本文只谈及了 flex-grow flex-shrink flex-basis,关于 Flexbox,还有很多内容。比如决定缠绕方式的 flex-wrap,它的效果类似 float,还有 justify-content,它决定元素在 main axis(主轴)方向的对齐方式,align-self则决定 cross axis(垂直的交叉轴)方向(在例如主轴是水平方向,而各个元素具有不同的高度这类情况下起作用)。属性名有点乱,不过它们都是围绕充满弹性扩展开的。只要结合对“充满”空间这件事情的想象,理解了弹性的含义,就弄清了目标与方法,应该能比较容易地学会并运用 Flexbox 了。

如上所见,本文所谈的,并不是大腿这件事情,如果你想看“真正的”大腿,可以读一读古龙的《多情剑客无情剑》、《午夜兰花》、《长生剑》以及《萧十一郎》。

想象一双结实而富有弹性的大腿:理解 Flexbox 布局相关推荐

  1. HTML5+CSS3小实例:富有弹性的导航栏标签

    HTML5+CSS3实现富有弹性的导航栏标签,切换如此Q弹的标签栏,你确定不手敲一遍?没有用到JavaScript哦! 效果: 源码: <!DOCTYPE html> <html&g ...

  2. html5弹性盒子的作用,flexbox弹性盒子,真正意义上的布局样式

    前段时间接手了一个基于cef1的项目,由于其特别限定的场景,在查询了对html5的支持后,整站都采用了flexbox布局,也从头熟悉了一遍该布局的使用方法.故分享出来,供参考. 背景 Flexbox ...

  3. (转)详解css3弹性盒模型(Flexbox)

    今天刚学了css3的弹性盒模型,这是一个可以让你告别浮动.完美实现垂直水平居中的新特性. Flexbox是布局模块,而不是一个简单的属性,它包含父元素和子元素的属性. Flexbox布局的主体思想是似 ...

  4. 从零开始学前端:弹性盒模型(flex布局) --- 今天你学习了吗?(CSS:Day19)

    从零开始学前端:程序猿小白也可以完全掌握!-今天你学习了吗?(CSS) 复习:从零开始学前端:字体图标的引入 - 今天你学习了吗?(CSS:Day18) 文章目录 从零开始学前端:程序猿小白也可以完全 ...

  5. 弹性盒布局(如何弹性管理你的页面布局)---自适应布局

    弹性盒布局(flexbox) 一.弹性盒布局介绍 1)弹性盒也叫伸缩布局盒模型 它是**css3引入的一种新的布局模式--flexbox**布局,即伸缩布局盒模型,用来提供一个更有效的方式制定.调整和 ...

  6. 弹性盒子(移动端布局)

    弹性盒子(移动端布局) 1.任何一个容器都可以指定为 Flex 布局. .box{display: flex; //形成弹性盒 } //display:inline-flex行内元素形成弹性盒 //d ...

  7. 理解Flexbox弹性盒子

    http://www.w3cplus.com/css3/understanding-flexbox-everything-you-need-to-know.html参考文档 1:要开始使用Flexbo ...

  8. 互联网快讯:京东公布“双11”节奏;猿辅导、掌门教育布局素质教育

    零售电商 1.京东公布"双11"节奏:10月20日晚8点正式开启预售,10月31日晚8点提前开抢 2.达达快送发布即时配送SaaS系统"达达智配",赋能配送服务 ...

  9. CSS之弹性盒子模型(Flex布局)

    文章目录 一.Flex布局是什么? 二.基本概念 三.容器的属性 3.1 flex-direction属性 3.2 justify-content属性 3.3 flex-wrap属性 3.4 alig ...

最新文章

  1. 递归式的时间复杂度的计算
  2. 服务器收集错误信息0不动,win10系统提示“我们只收集某些错误信息”的解决方案...
  3. Akka Cluster原理与应用
  4. linux mysql无符号整型_Mysql基础
  5. 昂贵的聘礼(poj 1062)
  6. MobileIMSDK怎样将Java服务端运行起来以及打成jar包运行
  7. python写小说阅读器_用python实现自己的小说阅读器!
  8. python mysql library popular_python之mysql入门详解(四)
  9. [翻译] 比较 Node.js,Python,Java,C# 和 Go 的 AWS Lambda 性能
  10. python逆序数怎么求_怎么算逆序数?急~~~!!!
  11. Java运行时的数据区域
  12. Oracle里面的用户user无法登录 LOCKED(TIMED)
  13. python自动化测试实战 虫师_Page Object 1 百度搜索实例 (虫师《selenium3自动化测试实战--基于Python语言笔记40》)...
  14. 孙鑫VC学习笔记:第十一讲 (四) 图形重绘方法三 利用兼容DC
  15. adobe acrobat pro字体很怪,有点发虚,不整齐,调整方法
  16. 日志收集 Graylog
  17. word文档误删怎么恢复
  18. win7 windows update 无法更新错误代码80072EF
  19. 生鲜行业数字化采购管理系统:助力生鲜企业解决采购难题,全程线上化采购执行
  20. 上下协同,用友IPD的研发管理之道(下)

热门文章

  1. 集成学习2:Boosting算法:AdaboostGBDT
  2. 踩坑系列之使用jQuery移除元素
  3. 2022加氢工艺题库及模拟考试
  4. python|Flaskbootstrapecharts简单应用
  5. c语言进程创建、等待和退出
  6. 计算机网络-4-网络层原理与技术
  7. 实现js节流函数throttle
  8. PLSql 动态SQL应用理解
  9. 网页php如何判断登录手机串号_php判断手机段登录,以及phpcms手机PC双模板调用...
  10. Beanstalkd原理、安装、常用命令