Block Elements and inline elements(块元素和行内元素)
在进入正题之前,我们先来简单总结一下传统的block元素和inline元素。
- HTML中的block元素显示在页面上时总会另起一行,并占满它的父元素的整个宽度;block元素的宽高可以通过width和height来设置;
- inline元素正好相反,它们不会另起一行,只会占展示内容所需的宽度;width和height对inline元素不起作用;
- 另外,还有一种处于block元素和inline元素之间的inline-block元素,这种元素和inline元素一样,不会新起一行,但是可以通过width和height来设置它的宽高;
HTML元素都有其默认显示方式,如 元素默认为block元素,但我们还可以通过设置 display: block; display: inline; display: inline-block; 来改变元素的显示方式;
Flex-box模型
Flex-box模型让我们可以使用 display: flex; 把一个元素变成flex容器,不管这个元素原来是block元素还是inline元素,当它变成flex容器之后,它的行为会类似block元素,会占满父元素的宽度,也可以通过width和height来设置它的宽高;
让我们通过一个例子来说明,如下面的HTML代码所示,我们用一个元素把三个 默认情况下它是这样子显示的(为了方便展示我给和 当我们给元素加上 display: flex; 之后: 元素变成了一个flex容器,行为类似block元素,而且宽度和高度也可以设置;但奇怪的是,在元素中的三个 让我们给元素设置一下宽高 width: 300px; height: 150px; : 有没有发现现在三个flex item的高度跟父元素的高度是一样,这是因为 align-items 的默认值是 stretch; 当一个元素变成flex容器之后,它的所有直接子元素(flex item)就拥有了三个神奇的属性 flex-grow, flex-shrink, flex-basis,这三个属性是用来设置一个 flex item 要占多少宽度的;默认情况下他们的值分别是: 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的宽度,得到: 然后用得到的比例分别乘以它们的flex-shrink的值: 得到的值加起来就是 1 + 6 + 6 = 13; 接下来就是计算每一个flex item应该缩小多少了,在这个例子中,多出来的宽度是400px,所以每个flex item分别约缩小: 再用它们的flex-basis的值减去它们应该缩小的宽度就可以得到它们的实际宽度: 把这些加起来 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 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分别会增加: 最终的宽度分别是: 转载于:https://www.cnblogs.com/sukiY/p/9391187.html<span class="container">
<div class="item">item1div>
<div class="item">item2div>
<div class="item">item3div>
span>