首页IT科技css里flex(深入理解CSS之flex精要之 flex-basis flex-grow flex-shrink 实战讲解)

css里flex(深入理解CSS之flex精要之 flex-basis flex-grow flex-shrink 实战讲解)

时间2025-05-02 13:23:08分类IT科技浏览3707
导读:这篇文章对flex不熟也可以看。这篇文章只讲这三个属性。为了简单化,不会提到主轴交叉轴,也不讲方向,默认方向就是水平方向从左往右。但并不影响对这三个概念的理解。...

这篇文章对flex不熟也可以看            。这篇文章只讲这三个属性                 。为了简单化           ,不会提到主轴交叉轴                  ,也不讲方向      ,默认方向就是水平方向从左往右      。但并不影响对这三个概念的理解      。

如果你觉得对flex比较了解           ,可以直接从第二小节开始看起                 。

1.开启flex

我们正常写三个div            。默认情况下是垂直排列的      。只要开启flex,一行代码就可以实现水平布局                 。这是flex最有用的一点            。

<div id="box"> <div class="div1 fontCenter">1</div> <div class="div2 fontCenter">2</div> <div class="div3 fontCenter">3</div> </div> #box { /*display: flex;*/ height: 500px; width: 1000px; background-color: plum; } .div1{ width: 150px; height: 150px; background-color: lightblue; } .div2{ width: 150px; height: 150px; background-color: lightgreen; } .div3{ width: 150px; height: 150px; background-color: lightsalmon; } .fontCenter{ text-align: center; line-height: 150px; font-size: 50px; }

1.1使用flex实现水平排列

我们给容器原始#box加上display: flex;这行。表示开启flex                 。这时候就已经实现了水平排列功能                 。非常的简单                  ,这个功能用浮动来做就麻烦的多。

#box { display: flex; height: 500px; width: 1000px; background-color: plum; }

1.1.2 左右分区

我想实现box1和box2在左边      ,box3在右边            。这个功能通过flex非常的好实现                 。只需要给box3设置margin-left:auto      。box3就会把能margin-left的都margin了            。自己也就到了最右边     ,也就实现了我们想要的功能                 。

.div3{ width: 150px; height: 150px; margin-left: auto; background-color: lightsalmon; }

如果你想要把box2和box3一起移动到最右边                  ,只需要把margin-left:auto设置在box2上面就可以了      。

.div2{ width: 150px; height: 150px; margin-left: auto; background-color: lightgreen; }

2.理解flex-basis

flex-basis这个属性是非常重要的一个属性            ,也是最容易混淆的一个属性      。最开始以为和width属性差不多     ,也就没怎么重视                 。不弄清楚会造成和他相关属性的理解混乱            。

其实flex-basis非常的好理解                 ,你只需要逐字逐句的把他的定义理解一遍就行      。

定义: 它的初始值是 auto            ,此时浏览器会检查元素是否设置了 width 属性值                 。如果有,则使用 width 的值作为 flex-basis 的值;如果没有                 ,则用元素内容自身的大小            。如果 flex-basis 的值不是 auto                  ,width 属性会被忽略。

分为两种情况:

1.没有设置flex-basis,这时候flex-basis为默认值auto                 。

这种情况很常见           ,就是只设置了display:flex的时候                 。别的flex属性都没设置。此时浏览器会检查元素是否设置了 width 属性值            。如果有                  ,则使用 width 的值作为 flex-basis 的值;如果没有      ,则用元素内容自身的大小                 。 这句话暗含了一个很重要的信息就是在flex里面           ,flex-basis是优先用于处理宽度的      。更切确的说                  ,在flex里面      ,根本不存在width,如果用户没设置flex-basis的值     ,flex系统会把width的值赋值给flex-basis            。flex-basis有了值后                  ,width被忽略            ,变成了工具人                 。

2.设置了flex-basis的值     ,这时候width会忽略                 ,元素的宽度用flex-basis的值表示      。

这点就更加验证了在flex里面            ,flex-basis是优先于width来处理宽度的      。在flex里面只要用户设置了flex-basis的值,我flex系统都不正眼瞧你width                 。

总之                 ,在设置了display:flex之后                  ,你最好设置flex-basis的值,并且忽略width            。

虽然width也是可以用           ,但就显得拖泥带水      。就像你一只脚已经踏入我flex这个先进的布局系统里面                  ,另一只脚还停留在原始的CSS里面                 。既然你已经用了flex这个系统      ,用就用全套           ,就用我flex-basis吧            。而且我还可以和我另两个兄弟flex-grow 和 flex-shrink一起配合使用。组成flex三巨头                 。

虽然说flex-basis是替换了width,并且他和width起到的作用是差不多的                 。但他们还是不同的。 当width为0的时候                  ,我们是看不到元素的            。但当flex-basis为0,或者为auto并且width没有设置值的时候(默认值为0)      ,该元素的大小是由内容大小决定的                 。也就是只要有内容     ,flex-basis是不会看不到元素的      。这在后面会从例子中体现            。

设为auto和0也是有区别的                 。一个最明显的区别就是为0的时候                  ,如果内容文字有空格是自动换行的      。

这个可以通过设置white space:nowrap解决      。auto就没有这个问题                 。

例一: div1同时设置了width和 flex-basis            ,width的值将会失效            。 .box1{ width: 150px; height: 150px; flex-basis: 200px; background-color: lightsalmon; } .box2{ width: 150px; height: 150px; background-color: lightgreen; } .box3{ width: 150px; height: 150px; background-color: lightblue; }

宽度使用的是flex-basis的值而不是width的      。

通常用法: 这里给父元素加了宽高和背景                 。 #content { display: flex; width: 1000px; height: 500px; background-color: lightpink; } .box1{ height: 150px; flex-basis: 15%; background-color: lightsalmon; } .box2{ height: 150px; flex-basis: 15%; background-color: lightgreen; } .box3{ height: 150px; flex-basis: 20%; background-color: lightblue; }

3.理解flex-grow

在设置了flex-basis后     ,元素就占用了一定的空间            。但还留有一些空间。这些空间可以通过flex-grow来占领                 。

以上面的这种情况为例                 ,box1,box2,box3分别占据了父元素的15%            ,15%和20%的宽度,一共占据了50%宽度                 。还剩下50%的空白空间。

我们可以给box设置flex-grow属性            。分别给三个box设置flex-grow:1                 。表示权重都是1                 ,那么三个box将会平分剩下的空间      。 .box1{ height: 150px; flex-basis: 15%; flex-grow: 1; background-color: lightsalmon; } .box2{ height: 150px; flex-basis: 15%; flex-grow: 1; background-color: lightgreen; } .box3{ height: 150px; flex-basis: 20%; flex-grow: 1; background-color: lightblue; }

父元素的宽度是1000px            。

以box1为例                  ,box1原来的宽度是1000*15%=150                 。grow的宽度是1000 * 50% * 1/3=500/3      。所以box1最终宽度是150+500/3      。大家可以在开发者工具对比一下前后宽度就明白了                 。

如果子元素flex-grow的总和超过1,那么就是按照上面的方式           ,按比例(权重)瓜分剩下的空间            。

还存在一种情况是flex-grow的总和没有超过1的                  ,比如出现小数的情况      。 .box1{ height: 150px; flex-basis: 15%; flex-grow: 0.3; background-color: lightsalmon; } .box2{ height: 150px; flex-basis: 15%; flex-grow: 0.3; background-color: lightgreen; } .box3{ height: 150px; flex-basis: 20%; flex-grow: 0.1; background-color: lightblue; }

这种情况就不会完全瓜分剩下的全部空间                 。而是子元素将自己的flex-grow值和剩余空间相乘      ,计算出的值就是增加的值            。以box1为例           ,剩余空间是100050%=500                  ,原来的宽度是10000.2=200      ,500*0.3=150这是增加的值     ,最后宽度是200+150=350。

和总和超过一的区别就是                  ,不是按照各个子元素直接的权重比例来分配了            ,而是直接用flex-grow这个值乘以剩余空间来获取增长的值                 。

3.1 flex-grow的实际用途

其实上面提到的两种用法在实际开发中基本是用不上的                 。谁会给已经设置好宽度的元素又增加点宽度呢?实际上     ,下面这种用法才是最常见的。

下面这个效果在网页里面是经常用到的            。左边是主要内容区                 ,右边是一些小模块                 。使用flex-grow可以快速实现这样的功能      。

我们想实现的效果是box1:box2=3,也就是box1宽度是box2宽度的3倍            。

#content{ display: flex; height: 700px; font-size: 50px; } .box1{ height: 100%; flex-grow: 3; background-color: lightgreen; } .box2{ height: 100%; flex-grow: 1; background-color: lightblue; } <div id="content"> <div class="box1">box1</div> <div class="box2">box2</div> </div>

但实际上            ,如果你打开开发者工具,测量一下                 ,box1和box2的宽度                  ,你会发现两者比例根本不是3:1                 。这是为什么?

也许你一开始就看出我这样写是有问题的,那么恭喜你           ,你对flex理解的很深刻      。原因出在你没有设置flex-basis=0上      。注意                  ,一定要设置为0      ,不写flex-basis默认值是auto                 。为什么设置flex-basis为0就可以了呢?

我们来分析一下上面的代码的执行逻辑: 上面的代码我们没有设置flex-basis           ,也没有设置width            。flex-basis等于auto,width没有值      。所以使用内容的宽度                 。

不信你把flex-grow属性都去掉                  ,就会看到下面的效果            。

这里引出flex-basis和width一个重要的区别。flex-basis默认值是auto,并且没有设置width的时候      ,flex-basis的值等于内容的宽度     ,值并不是为0的                 。这就是导致上面代码box1和box2不能实现3:1比例的原因                 。要想实现box1和box2比例是3:1                  ,box1和box2的起始宽度必须是0。这样flex-grow就可以按比例平分父元素空间了            。

只需要给两个box都加上flex-basis:0就可以实现按比例平分的效果了                 。 .box1{ height: 100%; flex-grow: 3; flex-basis: 0; background-color: lightgreen; } .box2{ height: 100%; flex-grow: 1; flex-basis: 0; background-color: lightblue; }

4.理解flex-shrink

在《深入理解CSS》这本书里面            ,有下面这样一个图      。给三个元素设置flex-basis都等于40%            。将会溢出一部分                 。

我也照着做了一遍      。 <div id="content"> <div class="box1">1</div> <div class="box2">2</div> <div class="box3">3</div> </div> #content{ display: flex; height: 500px; width: 1000px; background-color: lightpink; font-size: 50px; } .box1{ height: 200px; flex-basis: 40%; background-color: lightgreen; } .box2{ height: 200px; flex-basis: 40%; background-color: lightblue; } .box3{ height: 200px; flex-basis: 40%; background-color: lightsalmon; }

发现和想象中的不一样      。box3并没有溢出                 。但三个flex-basis加起来确实是超出父元素宽度了            。

但我心想     ,大牛写的书                 ,应该不会骗我      。一定是我写错了                 。但我没有写错            ,书里面说的也没错            。

问题就出在flex-shrink身上。可是我也没写flex-shrink啊                 。你没写flex会自动给你添加上,而且默认值还不是0                 ,而是1                 。

实际上                  ,你上面的代码等价于下面的代码。 .box1{ height: 200px; flex-basis: 40%; flex-shrink: 1; background-color: lightgreen; } .box2{ height: 200px; flex-basis: 40%; flex-shrink: 1; background-color: lightblue; } .box3{ height: 200px; flex-basis: 40%; flex-shrink: 1; background-color: lightsalmon; }

flex-shrink的作用和flex-grow相反            。当合计的flex-basis的总宽度超过父元素的总宽度的时候                 。flex-shrink会把子元素按比例减少,把溢出的宽度抹没      。

比如前面的例子总宽度是40%*3=120%           ,也就是溢出了20%的宽度                  ,也就是1000 * 20%=200px的宽度            。怎么把这200px给抹没掉呢?就是从前面三个子元素上面扣宽度                 。三个子元素的flex-shrink都是1      ,也就是平均扣除200/3px      。

就能实现抹没的效果      。打开开发者工具           ,量一下子元素的宽度                  ,确实是减少了这些宽度的                 。

如果说      ,我就想有这种溢出的效果     ,那么就把flex-shrink都设为0就好了            。就可以达到下面这样效果      。也就是书上提到的效果                 。

5.flex属性的使用

介绍完了flex-basis                  ,flex-grow和flex-shrink后            ,我们可以用他们的一种精简写法flex            。

例如:

我们给三个子元素都写上flex:1,就可以实现三等分的效果。 .box1{ height: 200px; flex: 1; background-color: lightgreen; } .box2{ height: 200px; flex: 1; background-color: lightblue; } .box3{ height: 200px; flex: 1; background-color: lightsalmon; }

这个效果是真正三等分的                 。

这里的flex:1相当于下面的写法                 。三个值分别表示flex-grow,flex-shrink,flex-basis。

注意     ,flex:1和只写一个flex-grow:1是不一样的            。

写成flex:1                 ,flex-shrink,flex-basis的默认值是1和0%                 。

而写成flex-grow:1,flex-shrink,flex-basis的默认值是1和auto      。也就是flex-basis是不同的            。

而flex-basis值为0和auto的不同前面已经验证过了            ,就是auto在没有width的情况下宽度是内容的宽度                 。这会导致flex-grow不能整体平均分      。具体见flex-grow小节      。 flex:1 1 0%

或者

flex-grow:1 flex-shrink:1 flex-basis:0%

除了flex-basis会单独当类似width使用外                 。flex-grow,flex-shrink基本是很少使用的            。

flex-grow也很少单独使用,因为使用flex-grow的时候                 ,一般就是为了按比例分配布局      。这时候要同时设置flex-basis:0                 。

所有一般使用下面的方式来替代单独使用flex-grow            。因为这种方式可以快速达到按比例分配布局。 flex:1

至于flex-shrink基本就不会用                  ,也就设个默认值让子元素不会超出                 。

使用flex实现常用效果

1.包裹内容水平排列

设置flex后,子元素也不要设置width,就会出现这种包裹内容水平排列的效果                 。

2.第一个子元素固定           ,第二个子元素撑满剩余高度。

flex-shrink的值是无所谓的                  ,因为并没有超出父容器宽度            。

3.三足鼎立型                 。两边固定宽度      ,中间填满剩余空间

4.按比例划分

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
百度上如何做优化网站推广(百度上如何做优化网站营销) win11 启动模式(win11怎么设置开机启动项? win11开机启动项添加删除的方法)