flex为1的父元素被子元素挤出屏幕怎么办?

需求与问题描述

需求简介

在前端开发中,我们经常会遇到这样的布局:在一个容器中,排布有两个元素,A元素宽度固定,B元素宽度自适应,如下图:

我们的CSS也能随手捏来

js 复制代码
<div class="card-content-wrap">
    <div class="left">左边元素固定宽度308px------------------</div>
    <div class="right">
        右边元素flex:1
    </div>
</div>

<style lang="less" scoped>
.card-content-wrap {
    width: 1000px;
    border: 1px solid blue;
    display: flex;
    justify-content: space-between;
    .left {
        width: 308px;
        margin-right: 16px;
    }
    .right {
        flex: 1;
    }
}
</style>

上述代码中,我们使用flex: 1的属性让右边的元素占满了剩余空间

问题描述

在一些普通场景中,上述用法是完全没有问题的,但是,当这个自适应元素(父元素)内部有子元素且子元素宽度大于父元素时,问题就出现了。

子元素较宽,导致左侧固定元素被挤压:

js 复制代码
<div class="card-content-wrap">
    <div class="left">左边元素固定宽度308px------------------</div>
    <div class="right">
        右边元素flex:1
      <div style="width: 920px; border: 1px #ff2d2d solid">
      子元素较大,导致左侧固定元素被挤压
      </div>
    </div>
</div>

子元素非常宽,导致左侧元素被挤压,右侧元素超出安全区域:

js 复制代码
<div class="card-content-wrap">
    <div class="left">左边元素固定宽度308px------------------</div>
    <div class="right">
        右边元素flex:1
      <div style="width: 1220px; border: 1px #ff2d2d solid">
      子元素宽度过大,导致父元素被挤出屏幕
      </div>
    </div>
</div>

显然,上述的样式问题和我们期望的行为不一致,那么我们该如何优雅的解决这个问题呢?

解决方案

我们先说解决方案,在具体分析原因

使用overflow: hidden

flex: 1的父元素设置overflow: hidden可以解决上述问题。但是如果需要父元素出现滚动条的情况,这种方式显然不合适。

js 复制代码
<style lang="less" scoped>
.card-content-wrap {
    width: 1000px;
    border: 1px solid blue;
    display: flex;
    justify-content: space-between;
    .left {
        width: 308px;
        margin-right: 16px;
    }
    .right {
        flex: 1;
        overflow: hidden;
    }
}
</style>

使用width:0

这是最佳的解决方案。

js 复制代码
<div class="card-content-wrap">
<style lang="less" scoped>
.card-content-wrap {
    width: 1000px;
    border: 1px solid blue;
    display: flex;
    justify-content: space-between;
    .left {
        width: 308px;
        margin-right: 16px;
    }
    .right {
        flex: 1;
        width: 0;
    }
}
</style>

且这种方式可以完美解决父元素需要出现滚动条的情况。

js 复制代码
.right {
    flex: 1;
    width: 0;
    overflow: auto;
}

使用min-width:0

min-width:0 的效果和width:0效果完全一致。

js 复制代码
.right {
    flex: 1;
    min-width: 0;
    overflow: auto;
}

竖直方向的布局如何解决

对于竖直方向其实也存在相同的问题

解决方案其实和水平方向完全一致

设置overflow: hidden

js 复制代码
.bottom{
  flex: 1;
  overflow: hidden;
}

或者设置height: 0

js 复制代码
.bottom{
  flex: 1;
  height: 0;
}

或者设置min-height: 0

js 复制代码
.bottom{
  flex: 1;
  min-height: 0;
}

问题原因

flex: 1 是 CSS 中用于弹性布局(Flexbox)的一个简写属性,用于在容器内分配多余空间或者收缩元素以适应容器大小。它综合了 flex-growflex-shrinkflex-basis 三个属性的值。

当使用 flex: 1 时,你实际上是在设置:

  • flex-grow: 1:元素会尝试占据多余的空间。
  • flex-shrink: 1:元素在必要时会缩小。
  • flex-basis: 0%:元素的默认大小是 0,这意味着它会完全依赖 flex-grow 来分配空间。

基于上述基础知识,简单来说问题的原因就在于flex属性只是对父元素的多余空间按什么比例去分配,并不是按我们的理解意思为固定分配的方式,不会对子元素原本实际内容宽度进行处理!

浏览器默认为flex容器的子元素设置了 "min-width: auto;min-height: auto",这意味着子元素的最小宽度和高度不能小于其内容的宽度和高度。

我们设置为min-width: 0,覆盖掉了其默认行为,即使其内容为空或者宽度很小,也可以使得flex子元素在flex容器中正确地布局。

相关推荐
开开心心就好6 小时前
批量提取PDF中的图片,直接导出原图
前端·javascript·支持向量机·智能手机·pdf·html·启发式算法
Setsuna_F_Seiei8 小时前
前端转型 Agent 开发 05 之 Agent Hooks 与 Checkpointer(让 Agent 从全自动转变人为可掌控)
前端·agent·ai编程
百万蹄蹄向前冲10 小时前
风扇转了一晚上MVP专家团翻车事故
前端·人工智能
默_笙10 小时前
🏛 给 AI 配一间办公室:Harness Engineering 六大模块与它的实现
前端·javascript
linux_cfan11 小时前
videojs v10 源代码系列解读:14 · 谓词守卫:在运行时安全地调用能力
前端·javascript·音视频
kyriewen12 小时前
我扒了 10,221 条 JD:腾讯技术岗 75% 在要 AI
前端·人工智能·ai编程
郑州光合科技余经理12 小时前
同城外卖小程序开发:下单成功后,后台导出能不能对上用户端状态
开发语言·前端·git·后端·uni-app·php·ai编程
IT_陈寒13 小时前
Vue的响应式让我熬到凌晨三点,原来漏了这个小细节
前端·人工智能·后端
Blanche150013 小时前
利用 RAG 为答疑机器人扩展知识范围
前端
天若有情67313 小时前
【纯前端小工具】公历生日转农历,批量查询每年农历生日对应的公历日期(GitHub Pages在线直接用)
前端·javascript·github pages·农历转换·lunisolar·网页小工具