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

news2025/1/23 5:02:20

这篇文章对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.按比例划分
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/408256.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

window.print() 前端页面打印与预览PDF

window.print()打印是浏览器自带的打印&#xff0c;实现原理是将html转换为pdf可以在线预览打印或者导出pdf&#xff0c;在任何网页上可通过Ctilp快捷键调出浏览器打印程序&#xff0c;它可将整个网页打印出来&#xff0c;在我们开发中&#xff0c;其实并不需要将所有页面打印出…

js调用gpt3.5

参考链接&#xff1a;直接在前端调用 GPT-3 API 效果图&#xff1a; 小技巧&#xff1a; 1. shiftenter是发送消息的快捷键 2. 有本地聊天记录功能 3. 按delete按钮可以删除包括这条之后的记录 <!DOCTYPE html> <html><head><meta charset"UTF-8&…

前端插件库之vue3使用vue-codemirror插件

vue3插件vue-codemirror使用步骤和实例vue-codemirror使用配置说明:个人代码编辑区Demovue-codemirror 基于 CodeMirror &#xff0c;适用于 Vue 的 Web 代码编辑器。 使用 1.命令行安装 npm install vue-codemirror --save // cnpm install vue-codemirror --save如果运行…

vue3使用viewer

介绍 v-viewer是一款基于viewer.js的强大的插件&#xff0c;不但支持vue3版本&#xff0c;还支持vue2、JavaScript、jquery&#xff0c;有以下特点&#xff1a; 支持移动设备触摸事件支持响应式支持放大/缩小支持旋转&#xff08;类似微博的图片旋转&#xff09;支持水平/垂直…

idea / eclipse 配置 Tomcat 并发布 Web 项目

文章目录tomcat 安装配置简介下载安装系统环境配置优化配置修改默认内存管理员用户名和密码设置支持中文文件名称idea 配置 tomcat 并发布 web 项目项目创建为项目添加 tomcat发布测试eclipse 配置 tomcat 并发布 web 项目引入 tomcat建立 web 项目发布测试总结本篇内容主要讲述…

python Web开发 flask轻量级Web框架实战项目--实现功能--账号密码登录界面(连接数据库Mysql)

ps&#xff1a;各位好久不见&#xff0c;我回家了&#xff01;终于有时间把之前的一些东西整理一下了&#xff08;好吧&#xff0c;之前是我太懒了&#xff09;&#xff0c;今天分享一个功能简单的python web实战项目&#xff0c;后期功能可自行丰富。 先看效果 输入正确用户名…

猿创征文|【C++游戏引擎Easy2D】我拿吃零食的时间,学会了在C++上添加可点击按钮

&#x1f9db;‍♂️iecne个人主页&#xff1a;&#xff1a;iecne的学习日志 &#x1f4a1;每天关注iecne的作品&#xff0c;一起进步 &#x1f4aa;学C必看iecne 本文专栏&#xff1a;【C游戏引擎】. &#x1f433;希望大家多多支持&#x1f970;一起进步呀&#xff01; ✨前…

vuex报错:Property or method “$store“ is not defined on the instance but referenced during render. Make

‘store’ is defined but never used no-unused-vars 最近在写vuex&#xff0c;报过一个这样的错误&#xff1a; Property or method “$store” is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the da…

结合表单验证谈el-form中model、prop、rules属性

目录前言modelproprules验证总结前言 最近写vue项目需要用element ui中的表单组件显示一些信息呈现在页面上&#xff0c;但在使用提供的一些属性时有些困惑——这三者之间有什么关系&#xff0c;必须要同时存在吗&#xff1f;于是在这里做一些记录。 model 官方说是表单中的数…

flex布局中使用flex-wrap实现换行

最近做个项目,其中有个样式是换行布局,作为样式渣渣的我一开始不会,只能查资料,然后摆平了它.今天得空了,简要记录一下,方便后面小伙伴布局使用. 参考资料 flex-wrap 开始样式 <div class"planWrap"><div class"content planItem">1</div…

vue 父传子 子传父实现方式

父传子&#xff1a; 主要步骤&#xff1a; 首先在子组件props中创建一个属性&#xff0c;用以接收父组件传过来的值&#xff1b;然后父组件中引用子组件&#xff0c;并在子组件标签中添加子组件props中创建的属性&#xff1b;最后把需要传给子组件的值赋给该属性。 理解&#…

Vue父子组件生命周期执行顺序

要想弄懂Vue父子组件的生命周期执行顺序&#xff0c;首先要知道vue页面的生命周期钩子函数的执行顺序&#xff0c;这也是在面试中老生常谈的问题&#xff0c;同时相信大家在工作的时候也能经常碰到父子组件加载上的问题&#xff0c;所以&#xff0c;不管是面试还是工作&#xf…

前端常见的时间转换方法合集+动态时钟效果实现

1.将时间戳转换为YYYY-MM-DD HH:mm:ss格式-老方法 通过对应的年月日时分秒依次进行拼接&#xff0c;另外还需要对小于10的值进行处理&#xff0c;在前面添加字符串‘0’&#xff0c;转换为常见的两位数时间格式 function transformTime(timestamp new Date()) { if (time…

Vue实现生成二维码

目 录 ①首先创建一个vue项目 ②引入qrcodejs2 ③封装组件 1. 创建Vue文件 2. 定义template模板 3. 引入QRCode包 4. 进行封装 5. less控制样式 ④启动项目 1. 在终端输入启动项目命令 2. 在浏览器中输入访问地址 3. 访问生成的二维码 4. 扫码进行解析 与后端用J…

CSS实现文字描边效果

一、介绍 最近在一个项目的宣传页中&#xff0c;设计师使用了文字描边效果&#xff0c;之前我确实没有实现过文字的描边效果&#xff0c;然后我在查阅资料后&#xff0c;知道了实现方法。文字描边分为两种&#xff1a;内外双描边和单外描边&#xff0c;也就是指在给文字加上描…

ElementPlus DateTimePicker日期时间选择器限制可选时间范围(精确时分秒)

项目场景 ElementPlus DateTimePicker日期时间选择器 当我们使用日期时间选择器时&#xff0c;可能会有需求只能选择今日之前或者今日之后&#xff0c;又或者一周内&#xff0c;一个月内的时间&#xff0c;而其他的时间应该禁止被用户选择。 解决 直接看文档&#xff1a; …

【element】el-autocomplete的常见用法

前言&#xff1a; 这段时间突然发现很少写博客了&#xff0c;平时都在平衡工作和休息的时间&#xff0c;周末也没动过笔&#xff0c;而且更重要的是我找不到写的内容了&#xff0c;在经历的初始的新知识的学习阶段后&#xff0c;目前的阶段更加转入对于业务的理解&#xff0c;…

vite基本配置教程

&#x1f469; 个人主页&#xff1a;不爱吃糖的程序媛 &#x1f64b;‍♂️ 作者简介&#xff1a;前端领域新星创作者、CSDN内容合伙人&#xff0c;专注于前端各领域技术&#xff0c;成长的路上共同学习共同进步&#xff0c;一起加油呀&#xff01; ✨系列专栏&#xff1a;前端…

C1认证之web基础知识及习题——我的学习笔记

文章目录 目录 文章目录 前言​​​​​​​ Web基础 十四、语义化标签 知识点 习题 十五、表单标签 知识点 习题 十六、转义字符 知识点 习题 十七、Head头 知识点 习题 十八、CSS引入方式 知识点 习题 十九、CSS背景 知识点 习题 二十、CSS文本属性 …

CSS合并单元格四种方式:table/display/flex/grid

目录 方式一&#xff1a;table【最简单写法】 方式二&#xff1a;display: table--不推荐 方式三&#xff1a;display: flex 方式四&#xff1a;display: grid 效果图&#xff1a; 方式一&#xff1a;table【最简单写法】 colspan&#xff1a;规定单元格可横跨的列数。row…