弹性布局中的 min-width

在 CSS 中,min-width 属性用于设置元素的最小宽度,即:

当指定一个值给 min-width 时,无论容器的宽度如何变化,该元素的宽度都不会小于设定的最小宽度。

与之类似的是 max-width,使用这些属性可以做响应式布局,例如:

css 复制代码
.box {
  min-width: 300px;  /* 设置最小宽度 */
  width: 50%;        /* 宽度设为父容器宽度的50% */
  max-width: 600px;  /* 设置最大宽度 */
}

那么 box 容器宽度用于是父容器宽度的 50%,但是不小于 300px,不超过 600px。这个知识点非常基础,搞前端的无人不知。但是今天要讲的是 min-width 在弹性布局中的特殊用途,请看下面的代码:

css 复制代码
.flex-container {
  display: flex;
}

.flex-item {
  flex: 1; 
  min-width: 0; 
}

给 flex-item 设置 min-width: 0 的作用是什么呢?从常规认知上来讲,任何一个元素的宽度都是不可以小于 0 的,这句话岂不是毫无意义?其实并不然,请看下面的列表案例:

看起来一切正常,当然我们优秀的测试同学也非常细心的想到了:如果标题特别长的话,是否会发生布局异常。就构造了下面的测试案例:

发现一切 OK,测试认为正常就上线了。然而,用户不按套路出牌啊,竟然出现了下面的情况:

之所以出现上面的排版问题,在于浏览器的断行规则,像长英文单词、持续的中文标点符号(例如句号、破折号等),默认是不会自动换行的,当超出了容器的宽度,就会发生溢出 。为了解决这个问题,有些同学可能想到用 word-break: break-all 来处理(使用方法可参考这篇文章),效果如下:

发现可以处理英文溢出问题,但解决不了中文的情况,这是为什么呢?因为 break-all 只能处理拉丁语系的单词,允许在任意字母处进行断行,但是对 CJK 语言不生效 。那又有同学可能想到用 overflow-wrap: break-word 来处理(使用方法可参考这篇文章),发现竟然没有任何效果,而增加一句 min-width: 0 之后,立马不一样了,所有溢出全部正确换行:

怎么会这样呢?今天正好借着这个案例讲一下 min-width: 0 的特殊用途,首先要知道:

min-width 的默认值是 auto,即内容所需宽度。

在 CSS 弹性布局(Flexbox)和网格布局(Grid)中,设置 min-width: 0 有一个特定的用途。

当在一个弹性容器(flex container)中设置子项(flex item)的 min-width 为 0,实际上是允许这个子项在必要的情况下缩小到比其内容的最小尺寸还要小的宽度。

因此,在弹性布局当中,对子项设置下面两种样式,效果是一样的:

css 复制代码
/* 方案1 */
overflow-wrap: anywhere;

/* 方案2 */
overflow-wrap: break-word;
min-width: 0;

在 Grid 布局的场景中也有类似的情况,例如下面的 HTML 结构:

html 复制代码
<div class="container">
  <div class="first-item"></div>
  <div class="second-item">AAAAAAAAAAAAAAAAAABBBBBBBBBBBBBCCCCCCCCCCCCCCCDDDDDDDDDDDD</div>
  <div class="third-item"></div>
</div>

配合下面的 CSS 代码:

css 复制代码
.container {
  width: 300px;
  display: grid;
  grid-template-columns: 100px 1fr 100px;
}

.first-item {
  background-color: red
}

.second-item {
  background-color: yellow;
}

.third-item {
  background-color: red;
}

由于中间的项目(second-item)内容太多导致被撑大,排版效果如下:

这种情况其实非常常见,但是很多前端开发在编码的时候是意识不到,因为中间部分的内容很可能不会超长,那么一切看起来都非常 OK:

css 复制代码
/* 内容较短时显示正常 */
+---------+----------------------------+---------+
|  <div>  |  <p> - 10 characters long  |  <div>  |
+---------+----------------------------+---------+

但是一旦发生溢出,右侧的栅格项目就可能看不见了:

css 复制代码
/* 内容较长时发生溢出 */
+---------+--------------------------------------+
|  <div>  |  <p> - 1000 characters looooooooooooong |  <div>  |
+---------+--------------------------------------+

例如,如果父容器设置了 overflow: hidden 的话就会显示成这样:

而如果给 second-item 设置 min-width: 0 之后,发现虽然内容溢出了,但是不影响 grid 栅格项目的显示:

除了使用 min-width 之外,还有一种相同的处理方式是:

css 复制代码
.container {
  display: grid;
  grid-template-columns: 100px minmax(0, 1fr) 100px;
}

因为 1fr 的意思是 minmax(auto, 1fr),即项目即使溢出了,也不能缩小到比最小内容宽度(min-content)还要小,而如果改成 minmax(0, 1fr) 之后,表示理论上可以缩小到 0px,于是项目宽度就能够保持在容器不溢出的最小宽度了。

相关推荐
大家的林语冰15 分钟前
React 生态大迁徙,脸书源码仓库跑路,核心技术栈全员加盟 React 基金会!
前端·javascript·react.js
AI智图坊24 分钟前
亚马逊多站点Listing视觉制作的效率瓶颈与AI解决方案:GPT-Image-2与Nano Banana Pro双模型分析
大数据·前端·数据库·人工智能·自动化·aigc
Rain50936 分钟前
1.3. Next.js与Nest.js在AI数据分析中的角色
前端·javascript·人工智能·后端·数据分析·node.js·ai编程
wanghao66645538 分钟前
精益方法论:用更少的资源创造更大的价值
大数据·前端·数据库·敏捷开发
北风toto43 分钟前
Shell脚本(.sh)常用语法全解析:从入门到实战
前端·chrome
zandy10111 小时前
体验家 XMPlus 智能客群分群引擎:从 RFM 模型到多维行为画像的动态标签体系设计
大数据·前端·人工智能
DFT计算杂谈1 小时前
WannierTools输入文件wt.in一键批量生成脚本
java·前端·chrome·python·算法·conda
rising start1 小时前
九、vue3 组件通信:全场景详解
前端·vue.js·typescript
VOLUN1 小时前
告别 AI 乱码!Vue3+TS 项目的 AI 编码助手规范实践
前端·ai编程
踏雪羽翼1 小时前
android 实现文字打印机效果
android·前端·javascript