当前位置: 首页 > Web前端 > HTML5

flex布局中的flex-basis、flex-grow、flex-shrink有什么问题?

时间:2023-04-05 18:19:40 HTML5

flex布局是一种非常强大的布局方式,它可以轻松完成大部分我们能想到的布局,类似于圣杯布局,双飞翼布局等,非常灵活兼容,经常被在项目中使用。大部分同学应该是从阮一峰老师的这篇博文中了解到flex的。虽然是15年写的,但不落伍,指导性还是很强的。不过,阮老师只是简单的提到了flex-basis、flex-grow、flex-shrink这三个属性,并没有细说。我还没有找到很好的解释。我最近写了很多页。我一直在使用弹性布局。如果我不理解它,我会感到不舒服。于是自己研究了一下,记录下来。如有错误,请指正。基本演示HTML123

CSS.box{width:300px;height:100px;border:1pxsolidblack;display:flex;}.item{font-size:25px;color:white;display:inline-block;text-align:center;line-height:100px;}flex-basisflex-basis属性定义了项目在分配多余空间之前占据的主轴空间(主要尺寸)。浏览器根据这个属性计算主轴是否有多余空间。它的默认值为auto,即项目的原始大小。——阮老师的博客定义我们先给每个item一个不同的宽度。item:nth-child(1){width:50px;background-color:red;}.item:nth-child(2){width:100px;background-color:rgb(0,204,255);}.item:nth-child(3){width:100px;background-color:rgb(0,255,64);}(containerflexlayout,flex-direction默认为row,水平排列。align-items默认为stretch,item不设置高度,填满整个容器。我们没有为item设置flex-basis属性,默认值为auto)现在我们给第一个item一个flex-basis属性,值为100px.item:nth-child(1){width:50px;background-color:red;flex-basis:100px;}我们发现第一个item的宽度被flex-basis代替了,所以我们可以得出结论,当item的flex-basis没有设置或者是auto时,item的宽度是有效的。当item的flex-basis有值时,替换width,flex-grow无效。为0,即有剩余空间则不放大。——阮老师的博客定义了,我们还是给每个item不同的宽度(和上面第一个一样,我只是把它往下移)。item:nth-child(1){width:50px;background-color:red;}.item:nth-child(2){width:100px;background-color:rgb(0,204,255);}.item:nth-child(3){width:100px;background-color:rgb(0,255,64);}父容器div.box的宽度是300px,但是三项加起来只有250px,还有50px的剩余空间。如果这时候你想让剩余的50px空间被这三个item填满你的排列,那么flex-grow就派上用场了。flex-grow属性默认为0,表示不占用剩余空间。如果我们想让第一个项目占据所有剩余空间,那么.item:nth-child(1){width:50px;background-color:red;flex-grow:1;}.item:nth-child(2){width:100px;background-color:rgb(0,204,255);}.item:nth-child(3){width:100px;background-color:rgb(0,255,64);}这个当第一项的flex-grow为1,其他两项为0,自然会被第一项吞掉。如果我们想让第一项、第二项、第三项按照一、二、三的比例来划分剩余空间。item:nth-child(1){width:50px;background-color:red;flex-grow:1;}.item:nth-child(2){width:100px;background-color:rgb(0,204,255);flex-grow:2;}.??item:nth-child(3){width:100px;background-color:rgb(0,255,64);flex-grow:3;}然后是实际宽度第一项即:50+(1/6)*50=58.333333333第二项:100+(2/6)*50=116.6666666666第三项:100+(3/6)*50=125flex的默认值-grow属性为0,不参与剩余空间的划分。剩余空间将根据item的flex-grow属性值进行划分。——阮老师的博客定义按照惯例,还是给每个item赋予了不同的宽度。这次不同了。宽度应超过div.box的width.item:nth-child(1){width:100px;background-color:red;}.item:nth-child(2){width:150px;background-color:rgb(0,204,255);}.item:nth-child(3){width:200px;background-color:rgb(0,255,64);}可以发现虽然三个item的宽度都超过了div.box的宽度,超出的部分是150px,没有超过div.box,但是每个item被“挤回去”,这是因为每个item的flex-shrink属性默认为1,会收缩flex-shrink和flex-grow根据宽度比例,会综合考虑每一项的宽度比例和flex-shrink比例,最后将它们一一相乘做最后的比较,然后以此比例作为缩减widthratio.flex-grow之所以只看flex-grow的比例,不考虑width的比例,是因为它只占剩余的空间,与每个item本身的width是无关的。我们可以通过计算验证:它们的宽度比为:2:3:4,伸缩比为:1:1:1,缩宽比为:2:3:4,所以第一个的实际宽度item:100-(150/9)*2=66.66666666第二个:150-(150/9)*3=100第三个:200-(150/9)*4=133.3333333333我们接下来可以验证一个更复杂的:.item:nth-child(1){width:100px;background-color:red;flex-shrink:3;}.item:nth-child(2){width:150px;flex-shrink:4;background-color:rgb(0,204,255);}.item:nth-child(3){width:200px;flex-shrink:2;background-color:rgb(0,255,64);}宽度比:2:3:4flex-sh溜冰场比例:3:4:2宽度比例减少:3:6:4所以第一:100-(150/13)*3=65.384615384615384615第二:150-(150/13)*6=80.7692307692307692307第三个:200-(150/13)*4=153.84615384615384615验证正确还有一个问题,如果每一项的flex-shrink值为0怎么办?你应该聪明点,它会超过父元素div。总结当flex-basisitem的flex-basis没有设置或者为auto时,item的宽度有效。当item的flex-basis有值时,替换宽度,flex-basis无效。growflex-grow属性默认值为0,不参与剩余空间的划分。剩余的空间会根据item的flex-grow属性值的比例进行划分。flex-grow之所以只看flex-grow的比例,不考虑width的比例,是因为它只占剩余空间,与每个item本身的宽度无关。flex-shrinkflex-shrink属性默认为1,它会根据宽度按比例收缩。为0时,不收缩。flex-shrink和flex-grow是不同的。它会综合考虑每一项的宽度比例和伸缩比例,最后将它们依次相乘进行最后的比较,然后将这个比例作为缩小后的宽度比例。当父容器内的item的宽度超过父容器的宽度并且item的flex-shrink为0时,会超出父容器