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. Entity Framework 使用Mysql的配置文件

    <?xml version="1.0" encoding="utf-8"?> <configuration> <configSec ...

  2. AAS代码运行-第11章-1

    启动PySpark export IPYTHON= # PySpark也可使用IPython shell pyspark --master yarn --num-executors 发生如下错误: / ...

  3. maven install 读取jar包时出错;error in opening zip file

    错误信息: [INFO] ------------------------------------------------------------------------ [ERROR] Failed ...

  4. WPF 绑定枚举值

    前台Xaml <ComboBox x:Name=" HorizontalAlignment="Left" Margin="5 0 0 0" Se ...

  5. Codeforces Round #346 (Div. 2)E - New Reform(DFS + 好题)

    E. New Reform time limit per test 1 second memory limit per test 256 megabytes input standard input ...

  6. mysql 外键(FOREIGN KEY)

    最近有开始做一个实验室管理系统,因为分了几个表进行存储·所以要维护表间的关联··研究了一下MySQL的外键. (1)只有InnoDB类型的表才可以使用外键,mysql默认是MyISAM,这种类型不支持 ...

  7. ajax+jsp自动刷新

    通过 AJAX,JavaScript 可使用 JavaScript 的 XMLHttpRequest 对象来直接与服务器进行通信.通过这个对象, JavaScript 可在不重载页面的情况与 Web ...

  8. vuejs怎么在服务器部署?(知乎)

    作者:知乎用户链接:https://www.zhihu.com/question/46630687/answer/157166318来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请 ...

  9. 安卓程序代写 网上程序代写[转]SVN 在线代码托管工具

    本文转载自 : http://blog.csdn.net/ithomer/article/details/8142920  作者:阳光岛主 在互联网环境使用SVN服务,你必须要有一台在互联网环境内支持 ...

  10. AngularJs 学习 (二)

    紧接着第一部分: 推荐阅读: http://adrianmejia.com/blog/2014/10/03/mean-stack-tutorial-mongodb-expressjs-angularj ...