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. CSS3 3D图片立方体旋转

    html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <titl ...

  2. idea 配置git

    1.注册https://github.com 2. 3.填入信息完成

  3. zabbix报错gd、freetype、png、jpeg

    安装包位置:http://www.p-pp.cn/app/zabbix/ 1.安装freetype [root@localhost softs]# tar xf freetype-2.5.0.tar. ...

  4. OO第二单元作业总结【自我反思与审视】

    第二单元作业的完成史,就是一部心酸的血泪史…… 多线程的出现为我(们)打开一片广阔的天地,我也在这方天地摸爬滚打,不断成长!如果说第一单元之前还对Java语法有所了解的话,那么这单元学习多线程则完全是 ...

  5. CDI Features(EL(SPEL),Decorator,Interceptor,Producer)

    一.EL(SPEL) EL 1.概述:EL是JSP内置的表达式语言,用以访问页面的上下文以及不同作用域中的对象 ,取得对象属性的值,或执行简单的运算或判断操作.EL在得到某个数据时,会自动进行数据类型 ...

  6. Spring框架中获取连接池的几种方式

    什么是数据库连接池? 数据库连接池是一种关键的有限的昂贵的资源,对数据库连接的管理能显著影响到整个应用程序的伸缩性和健壮性,影响到程序的性能指标.数据库连接池就是用来解决这些问题而提出的. 数据库连接 ...

  7. c# Process cmd 执行完回调 Proc_OutputDataReceived mysql mysqldump mysql source备份还原数据

    c# Process 执行完回调 Proc_OutputDataReceived mysql mysqldump mysql source备份还原数据 直接贴代码 前提:mysql5.7 vs2017 ...

  8. Tsinghua 2018 DSA PA3简要题解

    CST2018 3-1-1 Sum (15%) 简单的线段树,单点修改,区间求和. 很简单. CST2018 3-1-2 Max (20%) 高级的线段树. 维护区间最大和,区间和,左边最大和,右边最 ...

  9. javascript 十进制转换为二进制

    1.十进制转换为二进制 var toBin = (n) => { if(n == 0) return '0'; var res = ''; while(n != 0) { res = n % 2 ...

  10. FastCGI 进程意外退出造成500错误

    在一台新服务器上,安装新网站,之前只放至了一个网站.是服务器商配置好的,非集成环境. 添加了一个新站,路径都制定好了,但是在访问时出现了500错误.提示貌似是php的问题,但是之前的网站,运行的是di ...