夜猫子的知识栈 夜猫子的知识栈
首页
  • 前端文章

    • JavaScript
  • 学习笔记

    • 《JavaScript教程》
    • 《Web Api》
    • 《ES6教程》
    • 《Vue》
    • 《React》
    • 《TypeScript》
    • 《Git》
    • 《Uniapp》
    • 小程序笔记
    • 《Electron》
    • JS设计模式总结
  • 《前端架构》

    • 《微前端》
    • 《权限控制》
    • monorepo
  • 全栈项目

    • 任务管理日历
    • 无代码平台
    • 图书管理系统
  • HTML
  • CSS
  • Nodejs
  • Midway
  • Nest
  • MySql
  • 其他
  • 技术文档
  • GitHub技巧
  • 博客搭建
  • Ajax
  • Vite
  • Vitest
  • Nuxt
  • UI库文章
  • Docker
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

夜猫子

前端练习生
首页
  • 前端文章

    • JavaScript
  • 学习笔记

    • 《JavaScript教程》
    • 《Web Api》
    • 《ES6教程》
    • 《Vue》
    • 《React》
    • 《TypeScript》
    • 《Git》
    • 《Uniapp》
    • 小程序笔记
    • 《Electron》
    • JS设计模式总结
  • 《前端架构》

    • 《微前端》
    • 《权限控制》
    • monorepo
  • 全栈项目

    • 任务管理日历
    • 无代码平台
    • 图书管理系统
  • HTML
  • CSS
  • Nodejs
  • Midway
  • Nest
  • MySql
  • 其他
  • 技术文档
  • GitHub技巧
  • 博客搭建
  • Ajax
  • Vite
  • Vitest
  • Nuxt
  • UI库文章
  • Docker
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • HTML

  • CSS

    • CSS基础

    • flex布局

      • flex布局语法
      • flex布局案例-基础
      • flex布局案例-骰子
      • flex布局案例-圣杯布局
      • flex布局案例-网格布局
      • flex布局案例-输入框布局
      • flex与margin的巧妙运用
      • flex实现左边自适应右边全展示
      • flex布局子元素宽度超出父元素问题
        • 问题分析
        • 解决方案
        • 总结
      • flex布局和overflow一起使用超出滚动失效
    • CSS过渡与动画

    • Grid网格布局

    • 移动端布局
    • css 变量
    • svg的使用
    • 「布局技巧」图片未加载前自动撑开元素高度
    • 文字在一行或多行时超出显示省略号
    • 从box-sizing属性入手,了解盒子模型
    • 水平垂直居中的几种方式-案例
    • 如何根据系统主题自动响应CSS深色模式
    • Typora样式
    • 隐藏与美化滚动条
    • 多行展开收起自动隐藏
    • placeholder 样式修改
    • 实现按钮右下角勾选样式
    • svh、lvh、dvh
  • 页面
  • CSS
  • flex布局
JackTian
2024-07-11
目录

flex布局子元素宽度超出父元素问题

# flex布局子元素宽度超出父元素问题

最近在做项目中,使用flex布局遇到了个老问题:当flex子元素里的子元素的宽度过大,超出flex父元素时,设置flex:1并不能限制flex子元素的尺寸;具体表现如下:

<html>
<style>
.wrap {
    width: 300px;
    height: 100px;
    margin: 30px 0;
    display: flex;
    border: 1px solid red;
    .left {
        flex: 0 0 100px;
        background: lightgray;
    }
    .right {
        flex: 1;
        background: lightblue;
        &-content {
            overflow: hidden;
            white-space: nowrap;
            text-overflow: ellipsis;
            background: lightyellow;
        }
    }
}
</style>
<div class="wrap">
    <div class="left"></div>
    <div class="right">
        <div class="right-content">
            adasdasdasdadasdasdasdasdasadasdasdasdadasdasadasdasdasdadasdasdasdasdasadasdasdasdadasdas
        </div>
    </div>
</div>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

可以看到,右侧的文本超出部分没有隐藏,而且超出了.wrap的宽度。之前也遇到过这种情况,没太注意就给忘了,看来有必要总结一下;

# 问题分析

  • .right的宽度该如何计算?

正常情况下的元素宽度,如果设置有具体的值,那就是设置的值;如果没有设置,那就是该元素内容区占据的宽度。上面的例子可以看到,.right并没有设置width属性,所以.right是由.right-content撑开。又由于是flex盒子子元素,设置了flex: 1属性,所以:

.right宽度 = .right内容占据宽度(即.right-content宽度) + flex: 1属性分配的宽度
1
  • .right盒子已经设置flex: 1;为什么宽度还会超出父元素?

这是使用flex布局很常见的一个误区:给子元素设置了flex属性,很自然的就认为,它会按比例分配父元素的宽度。因为大多时候恰好是这样,其实并非如此。我们再来好好理解一下flex:1的含义(flex是flex-grow、flex-shrink和flex-basis的缩写,这里就不做介绍。详情点这里 (opens new window)

image-20240904155320072

可以看出,flex:1并不是决定子元素宽度的因素,它只是规定了,如果父元素有多余空间,以怎样的比例去分配剩余空间,并不会对子元素原本就占据的空间做处理。所以,当元素原本的宽度就超过父元素宽度时,子元素内容就会超出。

# 解决方案

  1. 限制子元素原本宽度,.right设置width属性

修改.right元素css如下,

.wrap {
    ...
    .right {
        width: 0; //新增
        flex: 1;
        background: lightblue;
        &-content {
            ...
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11

原理:强行设置.right原本宽度为0,让.right盒模型宽度完全由flex: 1这个属性来分配。

chrome浏览器效果完美:

image.png

但是在 firefox 浏览器时,即使设置width: 0,也不会生效,子元素还是超出;可以设置min-width: 0。

:::

设置min-width: 0可行的原理:

原因是浏览器默认为flex容器的子元素设置了 "min-width: auto;min-height: auto", 即flex子元素的最小宽度高度不能小于其内容的宽高, 在规范里的表述是: A flex item cannot be smaller than the size of its content along the main axis. 所以通过设置 min-width: 0, 覆盖这个默认设置, flex-shrink属性就能生效了 具体参考这个回答:html - Why don't flex items shrink past content size? - Stack Overflow (opens new window)

:::

  1. .right设置overflow属性不为visible 设置width: 0可行的前提是:.right-content元素宽度继承父元素.right。如果当.right-content元素设置了自己的宽度时,方法1就不能满足了,如下所示:

image.png

设置.right-content元素css如下,子元素依然会超出

.wrap {
    ...
    .right {
        width: 0; //新增
        flex: 1;
        background: lightblue;
        &-content {
            width: 300px; //新增
            overflow: hidden;
            white-space: nowrap;
            text-overflow: ellipsis;
            background: lightyellow;
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

这时候就回到了基本的css问题,子元素内容超出如何展示,给.right设置overflow搞定

正常css如下,让

.wrap {
    ...
    .right {
        // width: 0;
        flex: 1;
        background: lightblue;
        overflow: auto; //新增
        &-content {
            width: 300px; //新增
            overflow: hidden;
            white-space: nowrap;
            text-overflow: ellipsis;
            background: lightyellow;
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<html>
<style>
.wrap {
    width: 300px;
    height: 100px;
    margin: 30px 0;
    display: flex;
    border: 1px solid red;
    .left {
        flex: 0 0 100px;
        background: lightgray;
        overflow: auto; //新增
    }
    .right {
        flex: 1;
        background: lightblue;
        &-content {
            width: 300px; //新增
            overflow: hidden;
            white-space: nowrap;
            text-overflow: ellipsis;
            background: lightyellow;
        }
    }
}
</style>
<div class="wrap">
    <div class="left"></div>
    <div class="right">
        <div class="right-content">
            adasdasdasdadasdasdasdasdasadasdasdasdadasdasadasdasdasdadasdasdasdasdasadasdasdasdadasdas
        </div>
    </div>
</div>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

# 总结

  1. 设置min-width:0可以解决当flex子元素的子元素大小为auto的情况;
  2. 设置overflow不为visible可以解决所有情况下的麻烦;

兜兜转转一大圈,回到最初的原点,随手记录一下。

编辑 (opens new window)
上次更新: 2024/9/4 15:56:06
flex实现左边自适应右边全展示
flex布局和overflow一起使用超出滚动失效

← flex实现左边自适应右边全展示 flex布局和overflow一起使用超出滚动失效→

最近更新
01
IoC 解决了什么痛点问题?
03-10
02
如何调试 Nest 项目
03-10
03
Provider注入对象
03-10
更多文章>
Copyright © 2019-2025 Study | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式