Flex布局原理【转载】
引言
CSS3中的 Flexible Box,或者叫flexbox,是用于排列元素的一种布局模式。
顾名思义,弹性布局中的元素是有伸展和收缩自身的能力的。 相比于原来的布局方式,如float、position,根据盒子模型,就可以计算出元素的展示尺寸(长宽非百分比),除非溢出,否则不依赖于父容器的大小。
而弹性布局中元素的大小是高度依赖父容器的大小的。因为,它所具有的“伸缩性”,目标就是为了撑满父元素。当然这是在任其“野蛮生长”的情况下,你也可以通过相关css属性控制其是否撑满、撑满什么轴。
弹性布局是一种全新的思维方式,让很多实现复杂的问题有了更好的理解方式(如垂直居中)。只需要给直接父容器设置为display: flex;,duang~ 子元素就默认具有了可收缩性。
Flex的语法规范也曾经有很多版本:
- 最新版本是display: flex;
- 中间版本是display: flexbox;
- 最老版本display: box;
本篇文章侧重于flex难理解的点,适合于已经了解过flex的api的童鞋观看。(api其实就下图这么多,橙色是常用的)

为何要引入主轴、交叉轴、轴线的概念
我们首先看一下,CSS布局的发展历程:

翻开flex的入门教程,首先映入眼帘且比较难懂的就是主轴和交叉轴(对,就是下面这张图),这是前几种布局方式都没有的。

前几种布局都可以按照人类书写的方式理解:“从左到右写,写不下就往下换行”。
但是flex特点是可以重新定义这种“书写方式”,你还可以从下到上写、从右到左写(见flex-direction属性),换行也可以从两个相反的方向换行(见flex-wrap属性)。所以引入了这个几个概念方便理解。
沿着主轴的方向依次排列,如果要换行,则沿着交叉轴的方向进行换行,每行代表一条轴线。但是,我们可以使用子元素的order属性对元素进行重新排序。由此可见,flex给子元素提供了很大的灵活性。
主轴、交叉轴可以帮助我们理解这些概念:
- 重新定义浏览器“书写方式”。
- flex-direction 改变主轴方向;
- flex-wrap 改变交叉轴方向
如下图,主轴和交叉轴的排列组合有4*2 =8 种。

比如,可以像写对联一样,从上到下竖着书写,从右到左换行。
(2017新年快乐~)

.container {
flex-direction: column;
flex-wrap: wrap-reverse;
}
为了方便表达,本篇文章都使用默认的轴方向。
轴上的元素的排列方式(justify-content, align-items)。
- justify-content 定义了元素在主轴轴上如何对齐;
- align-items 定义了元素在交叉轴上如何对齐
- flex-start: 对齐轴起点;
- flex-end: 对齐轴终点;
- center:在轴线上居中;
- space-between:两端不带间距的轴线两端对齐;
- space-around: 两端带间距的轴线两端对齐, 且每个子元素之间的间距相同(假设为x)。两端元素离父元素间距为(x/2)。 注意这个间距既不是margin也不是padding,盒子模型来计算展示方式已经不适用了。
- baseline:交叉轴特有,基线对齐。
- stretch:交叉轴特有,有占满整个主轴高度的意向。当设置了子元素高度为非auto时不生效。
多根轴线时,轴线之间的排列方式(align-content)。align-content的参照轴是交叉轴。其属性也和上面的justify-content、align-items大同小异:flex-start、flex-end、center、space-between、space-around、stretch。不多做解释。
元素宽度如何伸缩
能决定元素展示宽度的属性有: flex-shrink,flex-grow,flex-basis,width,min-width
flex为前三个属性的缩写方式,所以常用写法是flex-shrink,flex-grow,flex-basis统一用flex设置。
常见的flex设置:
| 序号 | 样式 | flex-grow | flex-shrink | flex-basis |
|---|---|---|---|---|
| ① | flex默认值 | 0 | 1 | auto |
| ② | flex: 1; | 1 | 1 | 0% |
| ③ | flex: auto; | 1 | 1 | auto |
| ④ | flex: none; | 0 | 0 | auto |
那么,flex-grow和flex-shrink的值会对元素造成什么影响呢?
如下图所示,当元素允许缩小时,最终展示的效果会是正好撑满主轴。

在父容器中有三个元素A1,A2,A3,他们都有一个初始宽度(比如设置了width且flex-basis不为0%)。初始宽度在下一小节会详细讲。
如果按照初始宽度放入普通父容器中,那么他们会溢出x个像素(见初始尺寸行)。
当父元素display: flex;,
且A1flex-shrink:1,A2flex-shrink:1,A3flex-shrink:1时,
A1、A2、A3都具有可收缩的特性。
flex-shrink的值表示需要收缩的宽度占总溢出宽度的比例,因此展示尺寸这么算:
将x平均分为(1+1+2) = 4份,每份宽度为i = x/4
A1的展示尺寸为:A1默认宽度 - i × 1;
A2的展示尺寸为:A1默认宽度 - i × 1;
A3的展示尺寸为:A1默认宽度 - i × 2;
同理,当元素不够撑满父元素时,需要伸展的宽度也是按照这种方式计算的。只是比例基数变成了剩余空间的宽度。
**如果你希望元素不能伸缩,那么需要设置相应的属性为0。
如: flex-shrink: 0
flex-basis和width的关系
flex-basis 用于计算上一小节中元素的“初始宽度”。
- flex-basis为auto时, 初始宽度为元素内容大小或者设置的宽度值(盒子模型中的占用宽度)。
- flex-basis为像素值时,初始宽度为flex-basis的值。
- flex-basis为百分比时,初始宽度为占父容器的比例。
- flex-basis为0或0%时,初始宽度为0。
虽然flex-basis的优先级大于width,但是最后计算的展示尺寸受限于min-width或者max-width。
比如,元素A算出来的展示宽度为100px,但是它有个css属性min-width: 200px;
, 那么最后的展示宽度仍然为200px。但是计算的初始尺寸仍然是由flex-basis决定。
兼容性
从caniuse上可以查到,通过加上各种前缀,flex可以兼容到ie10以及以上。
16年年初在实际使用过程中,发现UC的支持性很不好。这次又重新试了一次,新版的UC也能很好的支持flex了。看来flex正在慢慢占领移动端。
几个案例
通过上面几小节的描述,可以发现flex用了一种全新的思路来布局。列出几个常见的案例,以下案例的代码统一在我的codepen可查看。
1.垂直居中

.container {
display: inline-flex;
align-items: center;
justify-content: center;
}
2.一侧固定,一侧自适应


.container {
display: flex;
.sidebar {
width: 100px;
}
.content {
flex: 1;
}
}

3.多列等高

.container {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
align-content: stretch;
}
总结
flex布局是围绕父元素和轴来进行布局的。这种全新的思路巧妙地只需要简单几行代码就可以实现曾经头疼的效果,其思路的建立过程非常值得借鉴。
转自:https://alisec-ued.github.io/2017/01/03/Flex%E5%B8%83%E5%B1%80%E5%8E%9F%E7%90%86%E4%BB%8B%E7%BB%8D/
Flex布局原理【转载】的更多相关文章
- Flex 布局教程转载
Flex 布局教程:语法篇 http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html Flex 布局教程:实例篇 http://www.ruan ...
- Flex布局(转载)
网页布局(layout)是 CSS 的一个重点应用. 布局的传统解决方案,基于盒状模型,依赖 display 属性 + position属性 + float属性.它对于那些特殊布局非常不方便,比如,垂 ...
- flex布局使用
什么是flex布局 flex是flexible Box的缩写,意味"弹性盒子",用来为盒子状模型提供最大的灵活性 任何一个盒子都可以指定为flex布局 .box{ display: ...
- flex布局(弹性布局)
1. 传统布局与 flex 布局比较 传统布局 兼容性好 布局繁琐 局限性,不能在移动端很好的布局 flex 弹性布局 操作方便,布局极为简单,移动端应用很广泛 PC端浏览器支持较差 IE 11 或 ...
- 移动 WEB 开发布局方式 ---- flex 布局
一.flex布局体验 1.1 传统布局 flex 布局 1. 2 初体验 1. 搭建 HTML 结构 <div> <span>1</span> <span&g ...
- 转载: Flex 布局教程
demo:页面二等分 .flex-box { display: -webkit-flex; /* Safari */ display: flex; flex-direction: row; justi ...
- sticky footer 和 flex布局的原理
Sticky footers设计是最古老和最常见的效果之一,大多数人都曾经经历过.它可以概括如下:如果页面内容不够长的时候,页脚块粘贴在视窗底部:如果内容足够长时,页脚块会被内容向下推送. 一.使用f ...
- CSS的flex布局(转载)
我们之前已经学过一些布局模型,比如说浮动,绝对定位等等,但是这些布局方式一是不够简洁,而是使用的范围确实是太窄了. flex模型拥有比较多的属性,来设置多样的布局方式,接下来我们就详细介绍各种属性对布 ...
- 三大Flex布局用法(转载)
Flex布局基础 对于Flex 初学者,在Hello World之后,Flex布局便是下一站学习要的要义.若是从传统的Html转变而来,总希望找到类似于Div/Table/UL等之类的控件,也希望在 ...
- 转载《Flex 布局》
网页布局(layout)是 CSS 的一个重点应用. 布局的传统解决方案,基于盒状模型,依赖 display 属性 + position属性 + float属性.它对于那些特殊布局非常不方便,比如,垂 ...
随机推荐
- 迭代器简易用法Iterator
1 public static void main(String[] args) { 2 List<String> list = Arrays.asList("111" ...
- c语言实现单链表的倒叙
bool upsidedown_list(LinkList L) { Lnode *head, *tmp, *oldhead; head = L; tmp = L->next; oldhead ...
- Selenium+Python上传文件方法大全
转自:https://www.jianshu.com/p/fba37cc5d5e2
- 06 显示fps帧频
需要看fps就用下面这段代码即可 var FPS = {};FPS.time = 0;FPS.FPS = 0; FPS.startFPS = function (stage){ FPS.shape = ...
- jmeter dubbo测试
一.环境准备 1.安装jmeter 2.安装dubbo插件,下载地址jmeter-plugins-dubbo, 将jar包放入${JMETER_HOME}\lib\ext路径下,重启即可 二.添加一个 ...
- oracle 存过调试 stepinto stepover stepout
step into:单步执行,遇到子函数就进入并且继续单步执行(简而言之,进入子函数): step over:在单步执行时,在函数内遇到子函数时不会进入子函数内单步执行,而是将子函数整个执行完再停止, ...
- nuxt中处理跨域
一.安装 npm install @nuxtjs/axios @nuxtjs/proxy -S 二.nuxt.config.js进行配置 modules:[ '@nuxtjs/axios' ' ...
- 记一次线上DB被打挂
这周刚新上了需求,在慢慢写代码的时候,突然报警群的消息多了,组长让我看看咋回事. 一开始没当回事,因为faas任务的错误日志一直很多,但是发现新的日志和以前大不相同,显示的是上游faas实例的连接被m ...
- 消息队列 RocketMQ4.x介绍和新概念讲解
消息队列 RocketMQ4.x介绍和新概念讲解 Apache RocketMQ作为阿里开源的一款高性能.高吞吐量的分布式消息中间件 RocketMQ4.x特点 支持Broker和Consumer端消 ...
- vue-封装组件-结合vant实现点击按钮弹出泡泡(Popover)事件控制多个泡泡出现时,弹出对应的泡泡
<template> <div class="sale-share-box"> <span class="sale-share-btn&qu ...