flexbox基本原理

新版的flexbox规范分两部分:一部分是container,一部分是 items。

flexbox是一整套布局规范,包含了多个css属性,所以学习起来比`float: left;` 这样简单的布局要复杂很多。

基本原理

容器上有 主轴和纵轴的概念,默认主轴(main-axis)是横向,从左到右,纵轴是竖向,从上到下。其中所有的孩子的布局都会受到这两个轴的影响。后面会讲到,有很多相关的css属性就是通过改变主轴和纵轴的方向来实现不同的布局效果的。

div上设置 `display: flex` 或者 `display: inline-flex` 来变成一个flex容器。然后给其中的每一个孩子设置 `flex: [number]` 来让他们按比例分配容器的宽度。

比如三个item分别设置了 `flex: 1` `flex: 2` `flex: 1` 则他们是按照 1-2-1 的比例来分配宽度的。

如果有item没有设置 `flex` 而是设置了宽度,比如 `width: 100px` 那么它的宽度就不受flex容器的影响,但是其他的设置了 `flex: [number]` 的容器会按比例平分剩下的部分。即使通过 `width: 100px` 的方式定死宽度,除了和 flex: 1 的宽度计算方式不同之外,其他并没有不同。

其实应该说,如果一个孩子没有通过 flex: 1的方式来定义宽度,那么会根据非flex的方式来优先计算它的宽度,然后其他的声明了flex的孩子再按比例分配剩下的宽度。

如下图所示,其中只有第一个孩子声明了 `flex:1` ,后面的都没有申明宽度,那么在flexbox容器中,后面的7个孩子都是由他们中的文字撑开的宽度,剩余的宽度全部分配给第一个孩子。

后面还会仔细讲 `flex: 1` 定义孩子宽度的细节。

container

display

`display: flex` 或者 `display: inline-flex` 来声明一个flexbox容器

flex-direction

items的排列方向,其实就是改变了上面所说的 主轴方向,所以这个属性会其他属性产生影响,因为整个flexbox的布局都是由主轴和纵轴决定的。

row: 从左到右

row-reverse: 从右到左

colum: 从上到下

colum-reverse: 从下到上

下面分别是这四个值的结果

flex-wrap

当内容超出之后是否折行。

nowrap:不换行,而是通过收缩每一个孩子的宽度来挤在一行。

wrap: 换行。

wrap-inverse: 换行,但是折行方向相反,(比如默认是折到下一行,但是这个属性会导致折到上一行)。

如下图所示,分别是上述的三个值的效果,其中每一个孩子宽度为 40px,8个孩子已经超出了容器的 200px宽度。

flex-flow

flex-direction 和 flex-wrap 的组合写法。

justify-content

不知道如何准确翻译 justify 这个词。它的作用是定义了如何分配剩余的空白区域。

flex-start:主轴方向

flex-end: 主轴反方向

center: 挤在中间

space-between: 中间有空白。

space-around: 中间和两边都有空白。其中两侧的空白是中间的一半宽度,可以理解为每个孩子两侧都有相同宽度的空白,并且空白不合并。

上面说过,flex-direction 会改变主轴方向,下面我们看看 flex-direction 为默认情况下(从左到右)这五个不同值的区别:

发现一个bug,在chrome下,在调试器下直接切换space-between  space-around 是不生效的。

然后我们设置一下 `flex-direction: column`,会发现他们的主轴已经变成从到上下了:

align-items

孩子的对齐方式,这个比较好理解。就是孩子的对齐方式。

注意,这里的“对齐”指的是纵轴上的对齐方式,所以,这个属性也是受 `flex-direction` 影响的。

比如我有一个高度为100 px的容器,那么默认情况下,是scratch,就是在纵轴上填满容器。

如上图所示,只定义了容器高度,默认情况下孩子的高度就会填满容器。

如果我改成`align-items: flexstart`  就会是这样

align-items 所有属性值如下:

flex-start: 纵轴开始

flex-end: 纵轴结束

center: 纵轴居中

baseline: 纵轴的baseline

scratch: 填满容器。

align-content

当有多行内容的时候,这个属性决定了如何对多行内容进行对齐。

注意,上面的每一个属性都是以每一个item为单位进行布局,而这个属性是以一行为单位进行布局。感觉这个属性应该叫 align-lines 比较合适。

如果只有一行的话,这个属性是不生效的,所以一定要配合 `flex-wrap: wrap` 来使用。

items

order

很简单,排列顺序,没什么好讲的。

flex-grow

定义了主轴上,孩子分配剩余空白区域的比例。

比如现在有三个孩子,宽度是 40px,并且`margin: 2px`,容器宽度 200px,那么默认情况下,有 `(200-44)/3=68` 空白的宽度。

如果你给每个孩子都定义了 `flex-grow: 1`,那么他们平分剩余的空白区域,就是这样:

这时候,如果我给第二个孩子定义 `flex-grow: 2`,那么它的宽度是怎么计算的?

其实就是把 68px 的空白按照`1:1:2` 的比例分配给他们,也就是 `17:17:34` 的大小来分配,所以三个孩子的宽度分别为 `57,57,74`:

如果你给一个孩子设置为 `flex-grow: 0` 那么它不会参与剩余空白的分配。

flex-shrink

如果孩子的总宽度超过了容器宽度(主轴),那么这个属性定义了如何把超过的那部分平分到每个孩子身上,然他们按比例来缩小一定的宽度从而可以在容器中装得下。

假设我们现在有一个容器,宽度为 `200px`,有三个孩子宽度为 `100px`,并且每个海泽有 `margin: 2px`,那么三个孩子总宽度 `(100+2*2)*3 = 312px` ,超过了 112px。

所以我们从这三个孩子身上砍下 `112px` 宽度,以让他们能装进容器中。

默认情况下,是 按 `1:1:1` 的比例来砍,也就是每个孩子各砍下 “112/3=37.3“,所以默认每个孩子宽度是 100-37.3=62.7。

那么现在我们定义第二个孩子 `flex-shrink: 2`,其他两个为 1,那么他们会把 `112px` 的宽度按 `1:2:1` 来平分。于是第二个孩子宽度为 `100-(112/4*2)=44px` 宽度,另外两个为`100-(112/4*1)=72px`:

flex-basis

在分配空白之前,孩子的宽度,默认是 `auto`,也就是孩子本身的宽度,如果你定义了 `flex-basis: 50px;` ,那么它就会覆盖掉孩子的宽度。

flex

他是 flex-grow, flex-shrink, flex-basis三个属性的快捷方式。默认是 0, 1, auto。

强烈建议用这个属性,而不是分别设定三个属性,因为这个属性可以“聪明地”设定三个属性来达到你要的效果。

你可以认为 flex 属性就是定义了每个孩子分隔父容器宽度的比例。

比如容器 200px,三个孩子设置了 flex 分别是 1-2-1,那么他们实际上宽度是 50px 100px 50px。

如果你比较较真,这个flex属性到底是如何工作的?

实际上他是自动设置了三个属性:flex-grow, flex-shrink, flex-basis。

而且为什么强烈推荐用flex,而不是分别设定三个属性,是因为 flex 属性会自动计算 flex-basis 属性的值。

比如容器宽度为 200px,然后你给三个孩子分别设置了

.item1 { flex: 1;}

.item2 { flex: 2;}

.item3 { flex: 1;}

那么他们的宽度将是 50-100-50

如果你想单独设置每一个孩子的三个属性,你会发现竟然无法按照 1-2-1 的比例平分了。

因为flexbox的计算每个孩子的宽度分两部分:

1,计算出孩子本身的宽度

2,将剩余的空白按比例平分给每一个孩子。

所以你如果这样定义:

.item1 { flex-grow: 1;flex-shrink:1;}

.item2 { flex-grow: 2;flex-shrink:2;}

.item3 { flex-grow: 1;flex-shrink:1;}

你会发现孩子不是 50-100-50 的宽度,因为他们是按照 1-2-1 平分了剩余的空白。

假设每个孩子本身是 20px 宽度,那么这么定义之后,他们其实按 1-2-1 平分了 140px 的空白。加上自身宽度之后比例 显然不是 1-2-1。

所以你还需要把它们的flex-basis也设置成 1-2-2,这么写才行:

.item1 { flex-grow: 1;flex-shrink:1;flex-basis: 20px;}

.item2 { flex-grow: 2;flex-shrink:2;flex-basis: 40px;}

.item3 { flex-grow: 1;flex-shrink:1;flex-basis: 20px;}

而这样就很麻烦,不如直接用 flex 属性来定义。而事实上,你可以认为 flex 属性就是帮你做了上面的计算。

align-self

单独在当前孩子上覆盖了 align-items 属性。

时间: 2024-09-18 10:25:44

flexbox基本原理的相关文章

Robocode基本原理之坐标锁定

导论 前面我们了解了Robocode中的绝对方向,相对方向及整个方向系统.相信大 家对此深有体会了.但是问题又来了,单知道方向似乎不能完全达到了解敌人的 目的.怎样去探测敌人的距离?怎样精确的锁定目标呢?对于移动中的目标我们 又如何处理?在这里我们将利用Java.lang 基本类库中的Math类及一些基本三角 函数方法为你揭开这些迷雾.对于那些快被遗忘的三角几何知识在本文的最后 Skyala.Li有比较详细的讲解. 坐标基本概念 首先我们还是来看看Robocode API中的一段文字翻译. Al

跨浏览器的Flexbox:CSS Flexible盒模型3

文章简介:CSS Flexible盒模型3又简称为Flexbox.摒弃我们传统上使用的一些hack和组件,Flexbox给网络的发展带来了很多正能量和兴奋济,让我们一起把复杂的网站布局变得简易和快速. 简介 CSS Flexible盒模型3又简称为Flexbox.摒弃我们传统上使用的一些hack和组件,Flexbox给网络的发展带来了很多正能量和兴奋济,让我们一起把复杂的网站布局变得简易和快速.早前在Flexbox: fast track to layout nirvana?一文中介绍了Flex

解决Flexbox跨浏览器兼容Bug

早在2013年9月,我在测试我的Solved by Flexbox项目时,在IE10和IE11中发现了一个Bug,就是Sticky footer实际上不会粘贴在页面的底部.我花了很多时间来解决这个问题,但始终没有成功. 起初,我真的很生气.在Flexbox出现之前,如果在不知道页脚的确切尺寸情况之下,要使用纯CSS来实现Sticky Footer的效果是不太可能.Flexbox改变了这一切,可以使用CSS解决这个问题. 失望之后,我最终得出一个结论,这不是什么大不了的事情.我的意思是,从渐进增强

旧CSS Flexbox语法案例和新CSS Flexbox语法案例

文章简介:2011年Richard Shepherd在Smashingmagazine.com写了篇文章.文章附带的提到了2011年版本的语法,但更侧重于2009年旧版本的语法. 大家都清楚的知道:"Flexbox"(全称:CSS Flexible Box Layout Module)在过去的三年中经历了许多变化.变化都达到了规范以及什么样的浏览器支持Flexbox. 如何辨别 如果你使用google搜索Flexbox,你会发现很多过时的信息.这里将告诉你如何迅速的辨别你需要的信息.

Flexbox新语法旧语法混用让浏览器完美的展示

文章简介:使用Flexbox:新旧语法混用实现最佳浏览器兼容. Flexbox非常的棒,肯定是未来布局的一种主流.在过去的几年这之中,语法改变了不少,这里有一篇"旧"和"新"新的语法区别教程(如果你对英文不太感兴趣,可以移步阅读中文版本).但是,如果我们把Flexbox新语法.旧语法和中间过渡语法混合在一起使用,我们就可以让浏览器得到完美的展示.尤其是对一个简单的和最可能常见的实例:控制网格顺序. HTML结构 一个具有语义化的容器"page-wrap&q

IE10中的Flexbox布局属性使用具体详解

文章简介:IE10中的Flexible Box("Flexbox")布局. 经过这一系列对Flexbox的介绍,我想大家对Flexbox在布局中的使用以及其强大功能特性给我们布局带来的方便性都有所了解.话又说回来,虽然Flexbox功能强大(特别是弹性布局),但还是很多同学不敢使用,也不想尝试性使用.我想主要原因出于他的语法版本众多,浏览器对其兼容性等. 在<"老"的Flexbox和"新"的Flexbox>一文中,让我们了解了如何识别

CSS3布局模式:伸缩布局盒(Flexbox)

文章简介:作者长期以来使用表格.浮动.行内块元素和其他 CSS 属性来布局网站内容.然而,这些并不是为复杂的页面和网页应用而设计的.不管是简单的垂直居中,还是灵活的网格布局都很难靠一己之力轻易实现,因此成就了 CSS 网格框架.但是,如果真的需要那么多项目来实现做这些事 介绍 Flexbox(伸缩布局盒) 是 CSS3 中一个新的布局模式,为了现代网络中更为复杂的网页需求而设计.本文将介绍 Flexbox 语法的技术细节.浏览器的支持越来越快,所以当 Flexbox 被广泛支持并应用时你将会快人

CSS3 Flexbox布局那些事

相信研究过CSS3的同学对Flexbox布局一定不会陌生(作为一个未来主流的布局方式,至少有所耳闻).最近完成了两个项目:一个是移动端H5 项目,一个是嵌入HTML页面的mac客户端项目.为了庆祝这两个项目不用再兼容万恶的IE,同时要体现出现代浏览器的优势,决定在项目中尝试使用 Flexbox布局.项目第一个版本完成后回过头来看,还是有不少需要注意的地方.现将项目中的一些经验总结一下,希望能够对想尝试使用Flexbox的 同学有所帮助,在恰当的地方使用恰当的布局方法. 初识Flexbox Fle

Ajax基本原理讲解

ajax 这段时间在学习ajax,前今天给公司同事讲解了一下基本原理,也随便放在网上给大家参考一下.我认为ajax简单的讲就是客户端通过javascript脚本获取服务器端的文本,通过解析返回值,更新部分的网页内容.下面结合一个获取QQ天气预报网页,并且对返回值进行处理的例子进行一下讲解.行数:解释.14:点击按钮开始获取.29:显示右上角的"正在加载..."的小区域(仿造gmail).30:创建XMLHTTP,IE的方式,其它的浏览器创建方式不同.31:XMLHTTP状态发生变化时调