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 属性。

转载:http://blog.csdn.net/lihongxun945/article/details/45458717

参考:https://css-tricks.com/snippets/css/a-guide-to-flexbox/

Flex布局语法的更多相关文章

  1. 【转】Flex 布局语法教程

    网页布局(layout)是CSS的一个重点应用. 布局的传统解决方案,基于盒状模型,依赖 display属性 + position属性 + float属性.它对于那些特殊布局非常不方便,比如,垂直居中 ...

  2. Flex布局语法与实践

    一.参考文献 阮一峰 Flex布局的语法 阮一峰 Flex布局的实践 二.Flex语法 (一)Flex是什么 Flex是Flexible Box的缩写,意为"弹性布局",用来为盒状 ...

  3. Flex布局—语法篇

    网页布局(layout)是CSS的一个重点应用. 布局的传统解决方案,基于盒状模型,依赖 display属性 + position属性 + float属性.它对于那些特殊布局非常不方便,比如,垂直居中 ...

  4. flex布局语法(阮一峰)

    Flex 布局教程:语法篇   作者: 阮一峰 日期: 2015年7月10日 网页布局(layout)是CSS的一个重点应用. 布局的传统解决方案,基于盒状模型,依赖 display属性 + posi ...

  5. Flex 布局语法教程

    一.Flex布局是什么? Flex是Flexible Box的缩写,翻译成中文就是“弹性盒子”,用来为盒装模型提供最大的灵活性.任何一个容器都可以指定为Flex布局. .box{ display: - ...

  6. flex布局 (引用阮一峰老师的flex布局-语法篇)

    一.Flex 布局是什么? Flex 是 Flexible Box 的缩写,意为"弹性布局",用来为盒状模型提供最大的灵活性. 任何一个容器都可以指定为 Flex 布局. .box ...

  7. flex布局语法+实例

    一.什么是flex布局 flex 是 flexible box 的缩写,意为"弹性布局",用来为盒状模型提供最大的灵活性. 任何一个容器都可以指定为 flex 布局.你可以将前端页 ...

  8. Flex 布局:语法篇

    网页布局(layout)是 CSS 的一个重点应用.布局的传统解决方案,基于盒状模型,依赖 display 属性 + position 属性 + float 属性.它对于那些特殊布局非常不方便,比如, ...

  9. flex布局基本语法

    注 : 本文章按照菜鸟教程 Flex布局语法教程为原型稍加修改,以方便自己学习. 菜鸟教程地址:http://www.runoob.com/w3cnote/flex-grammar.html 2009 ...

随机推荐

  1. 在JavaScript中使用json.js:使得js数组转为JSON编码

    在json的官网中下载json.js,然后在script中引入,以使用json.js提供的两个关键方法. 1.数组对象.toJSONString() 这个方法将返回一个JSON编码格式的字符串,用来表 ...

  2. Spring学习—生成图片验证码

    今天想学下一下验证码的生成,就之前搭建好的一个spring框架上写了一个demo,我会贴出细节代码,但是spring的配置就不在介绍了.需要完整代码可以联系我! 会从前台页面到后台实现完整的讲解: 1 ...

  3. QT_FORWARD_DECLARE_CLASS

    相当于class 类名. 那么他和#include 包含头文件有什么区别呢 首先我们为什么要包括头文件问题的回答很简单通常是我们需要获得某个类型的定义(definition).那么接下来的问题 ...

  4. TCP/IP 第二章

    1, 以太网的封装格式.其中MTU的最小值为46字节,所以,ARP和RARP需要添加18字节的PAD.CRC是检验和.(循环冗余检验) 2,SLIP:(串行线路ip) 首尾一个end字符加以区分数据. ...

  5. Ubuntu中MongoDB安装

    在Ubuntu中MongoDB有时候启动不起来,可以参考以下方法从新安装: 1.导入包管理系统使用的公钥 Ubuntu 的软件包管理工具(即dpkg和APT)要求软件包的发布者通过GPG密钥签名来确保 ...

  6. jQuery中的常用内容总结(二)

    jQuery中的常用内容总结(二) 转载请注明地址: http://www.cnblogs.com/funnyzpc/p/7571993.html 前言 距离上次博客更新已经有二十来天了(●′ω`●) ...

  7. php追加编译GD库

    一.准备工作. 安裝 GD 前需要安裝 jpegsrc.v7.tar.gz, libpng-1.6.17.tar.gz, zlib-1.2.8.tar.gz, freetype-2.5.5.tar.g ...

  8. c# 【MVC】WebApi开发实例

    using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using S ...

  9. DevOps之基础设施

    唠叨话 关于德语关我屁事的知识点,仅提供精华汇总,具体知识点细节,参考教程网址,如需帮助,请留言. <信息技术(IT )> 关于IT信息技术的基础设施,知识与技能的层次(知道.理解.运用) ...

  10. IOS应用FFMPEG库

    1.引用资源 build-ffmpeg  ffmpeg库生成 -sh开源地址: https://gist.github.com/m1entus/6983547 iFrameExtractor ffmp ...