弹性盒子布局早已被现代浏览器支持了个遍用起来简单方便能满足大多数场景下的布局需求对于典型的左右上下结构的页面可以抛弃绝对定位转而用弹性盒子来布局了

不过我在使用的过程中遇到过一个问题有时即便设置 overflow 为 autoscroll仍然会撑开 flex item

比如说下面这个例子

<div class="page">
  <div class="sidebar">
    Sidebar
  </div>
  <div class="main">
    <div class="content">
      <div style="width: 300px">Very wide content</div>
    </div>
  </div>
</div>

<style>
body {
  padding: 2em;
}
.page {
  background: rgba(0, 0, 0, .1);
  display: flex;
  width: 200px;
}
.sidebar {
  background: rgba(0, 0, 255, .1);
  width: 100px;
}
.main {
  background: rgba(255, 0, 0, .1);
  display: flex;
  flex: 1;
}
.content {
  flex: 1;
  overflow: auto;
}
</style>

一个简单的左右两栏布局效果是这样的

Sidebar
Very wide content

侧边栏是固定的 100px 宽右边的主区域自适应宽度虽然为 .content 设置了overflow: auto但是内容依然撑开了.main侧边栏也被挤得不成模样

原因在于 CSS 弹性盒子布局的规范为 flex item 设置了一个隐含的最小的大小最小宽度和最小高度min-widthmin-height 的默认值也就不再是0而是新定义的值auto

On a flex item whose overflow is visible in the main axis, when specified on the flex items main-axis min-size property, specifies an automatic minimum size. It otherwise computes to 0 (unless otherwise defined by a future specification).

大致是说如果对一个 overflowvisible 的 flex item 设置 min-sizemin-width / min-heightauto默认值就会指定一个自动的最小值这个最小值一般是内容大小content size指定大小specified size的较小值但是如果没有指定大小但是指定了比例比如上面的 .main那么自动的最小值将会是内容大小和 transferred size 之间的较小值

如果想让内容区域出现滚动条而不是撑开主区域可以为 .main 显式设置 min-width0

main {
  background: rgba(255, 0, 0, .1);
  display: flex;
  flex: 1;
  min-width: 0;
}

效果如下

Sidebar
Very wide content