前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >深入理解Flex布局 -- flex-grow & flex-shrink & flex-basis

深入理解Flex布局 -- flex-grow & flex-shrink & flex-basis

作者头像
Dickensl
发布2022-06-14 13:38:08
1.7K0
发布2022-06-14 13:38:08
举报
文章被收录于专栏:睿Talks睿Talks

一、前言

最近在项目里遇到了一个 Flex 布局的问题,才发现自己对它的理解还是停留在浅显的水平,遇到一些特殊情况就不知道如何处理。于是找了些资料深入学习一下,然后将我的学习心得总结成这篇文章。

二、问题还原

先讲讲我遇到的问题。我希望实现一个左中右三列的布局,其中左右部分固定宽度,中间部分自适应:

clipboard.png
clipboard.png

实现起来很简单,代码如下:

代码语言:javascript
复制
<div class="container">
  <div class="left">left</div>
  <div class="middle">
    middle
  </div>
  <div class="right">right</div>
</div>

.container {
  display: flex;
  width: auto;
  height: 300px;
  background: grey;
}

.left {
  flex-basis: 200px;
  background: linear-gradient(to bottom right, green, white);
}

.middle {
  flex: 1;
  background: linear-gradient(to bottom right, yellow, white);
}

.right {
  flex-basis: 300px;
  background: linear-gradient(to bottom right, purple, white);
}

到此为止一切都很美好。但遇到中间部分内容很长的时候,UI 就变形了:

clipboard.png
clipboard.png

为了固定住左右部分的宽度,需要给 left 和 right 加上flex-shrink: 0。但加上后容器的宽度就被撑开了,页面底部出现了滚动条:

clipboard.png
clipboard.png

而我期望的效果是滚动条出现在中间部分,整个页面不能滚动。解决方法是给 middle 加上overflow: scroll

clipboard.png
clipboard.png

此时的完整代码如下:

代码语言:javascript
复制
<div class="container">
  <div class="left">left</div>
  <div class="middle">
    middle
    <!-- 宽度为800px的内容-->
    <div class="long">long</div>
  </div>
  <div class="right">right</div>
</div>

.container {
  display: flex;
  width: auto;
  height: 300px;
  background: grey;
}

.left {
  flex-basis: 200px;
  flex-shrink: 0;
  background: linear-gradient(to bottom right, green, white);
}

.middle {
  flex: 1;
  overflow: scroll;
  background: linear-gradient(to bottom right, yellow, white);
}

.right {
  flex-basis: 300px;
  flex-shrink: 0;
  background: linear-gradient(to bottom right, purple, white);
}

.long {
  width: 800px;
}

完整的 codepen这里

实战经验到此结束,下面我们再深入学习涉及到的知识点。

三、知识点

先来讲讲上面用到的属性flex: 1。它其实是一个缩写,等价于flex: 1 1 0,也就是

代码语言:javascript
复制
flex-grow : 1;
flex-shrink : 1;
flex-basis : 0;
  • flex-grow 表示当有剩余空间的时候,分配给项目的比例
  • flex-shrink 表示空间不足的时候,项目缩小的比例
  • flex-basis 表示分配空间之前,项目占据主轴的空间

下面来讲讲 flex 空间分配的步骤。

  • flex-grow(默认值 0)

假设有一个宽度为 800 的容器,里面有 3 个项目,宽度分别是 100,200,300:

代码语言:javascript
复制
<div class="container">
  <div class="left">left</div>
  <div class="middle">middle</div>
  <div class="right">right</div>
</div>

.container {
  display: flex;
  width: 800px;
  height: 300px;
  background: grey;
}

.left {
  flex-basis: 100px;
  background: linear-gradient(to bottom right, green, white);
}

.middle {
  flex-basis: 200px;
  background: linear-gradient(to bottom right, yellow, white);
}

.right {
  flex-basis: 300px;
  background: linear-gradient(to bottom right, purple, white);
}

效果如下:

clipboard.png
clipboard.png

这时候就出现了多余的 200 的空间(灰色部分)。这时候如果我们对左中右分别设置flex-grow为 2,1,1,各个项目的计算逻辑如下:

  1. 首先将多余空间 200 除以 4(2 + 1 + 1),等于 50
  2. left = 100 + 2 x 50 = 200
  3. middle = 200 + 1 x 50 = 250
  4. right = 300 + 1 x 50 = 350
clipboard.png
clipboard.png
  • flex-shrink(默认值 1)

假设父容器宽度调整为 550,里面依然是 3 个项目,宽度分别是 100,200,300,这时候空间就不够用溢出了。首先要理解清楚,当我们定义一个固定宽度容器为flex的时候,flex会尽其所能不去改变容器的宽度,而是压缩项目的宽度。这时我们对左中右分别设置flex-shrink为 1,2,3,计算逻辑如下:

  1. 溢出空间 = 100 + 200 + 300 - 550 = 50
  2. 总权重 = 1 x 100 + 2 x 200 + 3 x 300 = 1400
  3. left = 100 - (50 x 1 x 100 / 1400) = 96.42
  4. middle = 200 - (50 x 2 x 200 / 1400) = 185.72
  5. right = 300 - (50 x 3 x 300 / 1400) = 267.86
clipboard.png
clipboard.png

如果我们不想项目被压缩,就必须将flex-shrink设为 0。还是用上面的例子,当左中右的flex-shrink都为 0 的时候,就会冲破宽度限制,container的宽度将会从 550 变为 600。

clipboard.png
clipboard.png

codepen这里

  • flex-basis(默认值 auto)

flex-basis指定项目占据主轴的空间,如果不设置,则等于内容本身的空间:

clipboard.png
clipboard.png

四、总结

本文从问题出发,讲解了Flex布局在实战中的应用,并深入到flex-growflex-shrinkflex-basis的细节,描述了项目空间在填充和溢出情况下的计算方式,希望对你有所帮助。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-06-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、前言
  • 二、问题还原
  • 三、知识点
  • 四、总结
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档