Block Elements and inline elements(块元素和行内元素)


在进入正题之前,我们先来简单总结一下传统的block元素和inline元素。

  • HTML中的block元素显示在页面上时总会另起一行,并占满它的父元素的整个宽度;block元素的宽高可以通过width和height来设置;
  • inline元素正好相反,它们不会另起一行,只会占展示内容所需的宽度;width和height对inline元素不起作用;
  • 另外,还有一种处于block元素和inline元素之间的inline-block元素,这种元素和inline元素一样,不会新起一行,但是可以通过width和height来设置它的宽高;

HTML元素都有其默认显示方式,如<p>元素默认为block元素,但我们还可以通过设置 display: block; display: inline; display: inline-block; 来改变元素的显示方式;

Flex-box模型


Flex-box模型让我们可以使用 display: flex; 把一个元素变成flex容器,不管这个元素原来是block元素还是inline元素,当它变成flex容器之后,它的行为会类似block元素,会占满父元素的宽度,也可以通过width和height来设置它的宽高;

让我们通过一个例子来说明,如下面的HTML代码所示,我们用一个<span>元素把三个<div>元素包裹起来,一般来说我们不会这么做,这里只是为了说明不管是block元素还是inline元素,只要对它设置了 display: flex; 它就会变成一个类似block元素的容器。

<span class="container">
<div class="item">item1</div>
<div class="item">item2</div>
<div class="item">item3</div>
</span>

默认情况下它是这样子显示的(为了方便展示我给<span>和<div>分别添加了2px的边框):

当我们给<span>元素加上 display: flex; 之后:

<span>元素变成了一个flex容器,行为类似block元素,而且宽度和高度也可以设置;但奇怪的是,在<span>元素中的三个<div>元素按照规则应该是从上往下叠放,并且每一个都要占满父元素<span>宽度的,但它们反而是并排显示的。这是因为当一个元素变成flex容器之后,它的所有直接子元素都会变成flex item(类似inline-block),默认只会占内容展示所需要的宽度,而且不会另起一行;

让我们给<span>元素设置一下宽高 width: 300px; height: 150px; :

有没有发现现在三个flex item的高度跟父元素的高度是一样,这是因为 align-items 的默认值是 stretch;

当一个元素变成flex容器之后,它的所有直接子元素(flex item)就拥有了三个神奇的属性 flex-grow, flex-shrink, flex-basis,这三个属性是用来设置一个 flex item 要占多少宽度的;默认情况下他们的值分别是:

  • flex-grow: 0;
  • flex-shrink: 1;
  • flex-basis: auto;

flex-basis


flex-basis 相当于 flex item 的 width, 当为一个flex item设置了 flex-basis: auto; 时,如果同时为这个flex item 设置了width属性,那么这个flex item的宽度就等于width属性的值,如果没有设置width属性,那么这个flex item只会占展示内容所需的宽度;让我们给第一个flex item设置 width: 100px;

现在第一个flex item的宽度变成了100px,但这不是一个好的做法,最好还是为一个flex item直接设置flex-basis而不是width属性;

如果我们给flex-basis指定一个除了auto以外的值,那么flex item的width属性的值就会被忽略掉;当我们同时给例子中的第一个flex item设置 width: 100px; flex-baisi: 50px;

现在第一个flex item的宽度变成了50px,它的width属性被忽略了;

flex-basis还接受其他的CSS单位,例如我们可以给每个flex item设置 flex-basis: 30%;

现在每个flex item的宽度都是父元素宽度的30%,那具体是多少呢?

之前我们设置了父元素的width等于300px,而且因为我们没有设置 box-sizing: border-box; ,所以这个flex容器的内宽度(不包括padding和border)就是300px,那每个flex item的内宽度就是 300px * 30% = 90px ,但因为每个flex item都有一个2px宽的边框,所以每个flex item的总宽度(内宽度+边框)是 90px + 2px * 2 = 94px ;

但如果我们给flex容器设置了 box-sizing: border-box; width: 300px; ,现在这个flex容器的总宽度是300px,但它也有一个2px宽的边框,所以它的内宽度变成是 300px - 2px * 2 = 296px ,这时每个flex item的内宽度就变成了 296px * 30% = 88.8px ,总宽度则还要加上两边的边框 88.8px + 2px * 2 = 92.8px ;

现在我们去掉flex容器的 box-sizing: border-box; 设置,它的内宽度又变回了300px;我们再给每个flex item设置 box-sizing: border-box; padding: 10px; ,现在每个flex item的总宽度(内宽度+padding+border)变成了 300px * 30% = 90px ;我们再给第一个flex item两边加上margin, margin: 0 10px; 可以看到这并不会影响它的宽度;

 flex-shrink


现在把第一个flex item的 margin: 0 10px; 删掉:

flex容器的width还是300px,每个flex item的总宽度是 300px * 30% = 90px ,三个flex item加起来一共占了 90px * 3 = 270px ,小于flex容器的宽度;如果我们给每个flex item设置 flex-basis: 150px; 总宽度会超过flex容器的宽度,那会不会发生内容溢出的情况?

其实并不会,因为我们上面提到过,每个flex item都会默认设置 flex-shrink: 1; ,这个属性的作用就是当flex item宽度的总和大于flex容器的宽度时,适当地缩小flex item;

假如我们让每个flex item的宽度等于200px,三个加起来就是600px,然而flex容器只有300px宽,那么多出来300px就要被砍掉啦,因为每个flex item的flex-shrink都默认为1,所以它们会相应地缩小: 300px / 3 = 100px ,那么每个flex item缩小后的宽度就变成了 200px - 100px = 100px ;

flex-shrink还可以接收大于1的值,现在我们把第一个flex item设置为 flex-shrink: 2;

多出来的那300px会被分成 2 + 1 + 1 = 4 份,每一份是 300px / 4 = 75px ,第一个flex item会相应缩小两份变成 200px - 75px * 2 = 50px ,其他两个会分别缩小一份变成 200px - 75px = 125px ;

但flex-shrink不仅仅会根据多出来的那部分宽度缩小flex item的宽度,它还会根据flex item的flex-baisi的值;上面的例子中每个flex item的宽度都一样,现在我们把第一个flex item的设置为 flex-basis: 100px; flex-shrink: 1; , 并对第二和第三个flex item设置 flex-basis: 300px; flex-shrink: 2;  ,现在三个flex item的总宽度是 100px + 300px * 2 = 700px ,而flex容器的宽度是300px,所以多出来的宽度是400px;

首先找出最小的宽度,在这个例子里是100px,然后用这个宽度去除每个flex item的宽度,得到:

  • 100px / 100px = 1;
  • 300px / 100px = 3;
  • 300px / 100px = 3;

然后用得到的比例分别乘以它们的flex-shrink的值:

  • 1 * 1 = 1;
  • 3 * 2 = 6;
  • 3 * 2 = 6;

得到的值加起来就是 1 + 6 + 6 = 13;

接下来就是计算每一个flex item应该缩小多少了,在这个例子中,多出来的宽度是400px,所以每个flex item分别约缩小:

  • 400px * 1/13 = 30px
  • 400px * 6/13 = 185px
  • 400px * 6/13 = 185px

再用它们的flex-basis的值减去它们应该缩小的宽度就可以得到它们的实际宽度:

  • 100px - 30px = 70px
  • 300px - 185px = 115px
  • 300px - 185px = 115px

把这些加起来 70px + 115px + 115px = 300px 正好是flex容器的宽度;

flex-grow


现在我们给每个flex item设置 flex-basis: 50px; box-sizing: boreder-box; ,flex容器的宽度依然是300px:

可以看到flex容器还有剩余的空间,但是flex item不会把它填满,因为它们的flex-grow默认值为0;如果我们把flex-grow设置为大于0的值,那么flex item就会相应地扩大以填满flex容器;现在我们给每个flex item设置 flex-grow: 1; 它们就会把flex容器剩余的空间填满:

现在每个flex item的宽度都是100px,我们来看一下这是怎么算出来的:

  • 首先flex容器的width是300px,三个flex item加起来的宽度是 50px * 3 = 150px ,所以剩余的空间是 300px - 150px = 150px ;
  • 我们有三个flex item,而且每一个的flex-grow的值都是1,所以剩余空间会被分成 1 + 1 + 1 = 3 份, 每一份是 150px / 3 = 50px ;
  • 每一个flex item会增大50px宽,最后变成 50px + 50px = 100px ;

现在我们给第一个flex item设置 flex-grow: 3; 其他两个还是 flex-grow: 1; ,这个意思并不是说第一个flex item会是其他flex item的3倍:

现在第一个flex item的宽度变成了140px,其他两个则分别是80px,我们来看看是怎么算的吧:

首先flex容器的剩余空间还是150px,但这次不是被分成3份了,而是会分成 3 + 1 + 1 = 5 份(每个flex item的flex-grow的值相加),每一份是30px;

所以三个flex item分别会增加:

  • 3 * 30px = 90px
  • 1 * 30px = 30px
  • 1 * 30px = 30px

最终的宽度分别是:

  • 50px + 90px = 140px
  • 50px + 30px = 80px
  • 50px + 30px = 80px

Flex-box入门---flex-grow, flex-shrink, flex-basis的更多相关文章

  1. CSS 弹性盒子 flex的三个属性:grow、shrink、basis

    flex-grow 首先介绍flex-grow属性,flex-grow会在容器太大时(图片A.B的宽度和 < 父容器宽度)对元素作出调整. 如果图片A的flex-grow属性的值为 1,图片B的 ...

  2. CSS3 弹性盒子(Flex Box)

    1 CSS3 弹性盒子(Flex Box) 1 http://caniuse.com/#search=flex%20box https://www.w3.org/TR/css-flexbox-1/ C ...

  3. css3弹性盒模型flex快速入门与上手(align-content与align-items)

    接着上文css3弹性盒模型flex快速入门与上手1继续,上文还剩下两个父容器的属性align-items和align-content. 一.align-content:多行的副轴对齐方式 含义 多行的 ...

  4. Flex box弹性布局 及 响应式前端设计的优化

    Flex box弹性布局 Flex box是CSS3新添加的一种模型属性,它的出现有力的打破了我们常常使用的浮动布局.实现垂直等高.水平均分.按比例划分,可以实现许多我们之前做不到的自适应布局.如果你 ...

  5. 【CSS3】 CSS3:弹性盒子(Flex Box)

    Flex布局是什么 如何指定一个容器为Flex布局 Flex的基本语法 display flex-direction justify-content align-items flew-wrap ali ...

  6. flex box 布局

    .box{ display:flex; } .box { display: inline-flex; } .box { display:-webkit-flex; display: flex; } f ...

  7. CSS弹性盒模型(flex box)

    本文介绍的是 CSS3 规范中引入的新布局模型:弹性盒模型(flex box).随着响应式用户界面的流行,Web 应用一般都要求适配不同的设备尺寸和浏览器分辨率. 浏览器支持: 弹性盒布局的容器(fl ...

  8. arcgis api for flex 开发入门(一)环境搭建

    http://www.cnblogs.com/wenjl520/archive/2009/06/02/1494514.html arcgis api for flex 开发入门(一)环境搭建arcgi ...

  9. Flex Box 简单弹性布局

    弹性盒子模型有两种规范:早起的display:box 和后期的display:flex.它可以轻易的实现均分.浮动.居中等灵活布局,在移动端只考虑webkit内核时很实用. 一.display:box ...

  10. CSS3 Flex Box(弹性盒子)

    CSS3 Flex Box(弹性盒子) 一.简介 弹性盒子是 CSS3 的一种新的布局模式. CSS3 弹性盒( Flexible Box 或 flexbox),是一种当页面需要适应不同的屏幕大小以及 ...

随机推荐

  1. LOB

    一,LOB介绍 1,概念 LOB 是指用来存储大对象的数据类型,一般说LOB只是泛指,具体有BLOB,CLOB,NCLOB,BFILE.   根据你数据库的设置,一个LOB可以存储的最大大小从8TB到 ...

  2. vue父子组件的传值总结

    久违的博客园我又回来了.此篇文章写得是vue父子组件的传值,虽然网上已经有很多了.写此文章的目的就是记录下个人学习的一部分.接下来我们就进入主题吧! 在开发vue项目中,父子组件的传值是避免不掉的. ...

  3. ionic2启动出现try again later

    新建IONIC2的项目时,启动只出现try again later 这个问题应该是安装依赖出现的,重装npm install 一次就可以了

  4. multiThread (一)

    并发系列(1)之 Thread 详解   阅读目录 一.线程概述 二.线程状态 三.源码分析 1. native注册 2. 构造方法和成员变量 3. start 方法 4. exit 方法 5. 弃用 ...

  5. aggregate基础 使用记录

    mongoDB中聚合(aggregate)的具体使用 我们可以用$指定字段来表示选定的document的field,另外可以使用$$ROOT来表示选定的document的所有内容(例如:chosenD ...

  6. [luogu P2391] 白雪皑皑

    [luogu P2391] 白雪皑皑 题目背景 “柴门闻犬吠,风雪夜归人”,冬天,不期而至.千里冰封,万里雪飘.空中刮起了鸭毛大雪.雪花纷纷,降落人间. 美能量星球(pty 在 spore 上的一个殖 ...

  7. Win10系列:C#应用控件进阶8

    LineGeometry LineGeometry控件通过指定直线的起点和终点来定义线.LineGeometry对象无法进行自我绘制,因此同样需要使用 Path元素来辅助呈现.LineGeometry ...

  8. php 面向对象二

    多态: 多态就是多种形态:多态分为方法重写和方法重载,但是php不支持方法重载 重写: 子类和父类的方法名必须一致,严格标准要求参数必须一致,但是参数可以不一致 子类中覆盖的方法不能比父类的方法访问权 ...

  9. svn 删除svn项目命令

    svn delete svn://127.0.0.1:3690/project -m delete

  10. XAMPP本地服务器打不开解决方案

    第一步:先开启相关服务:如图 第二步:在浏览器上输入localhost:端口号,(或127.0.0.1:端口号),按回车,就成功登陆本地服务器. =========================== ...