Skip to content

Flex

display: flexdisplay: inline-flex

CSS Display Module Level 3 定义了 display 可以接受两个值:

css
.block-container {
    display: flex;

    /*相当于*/
    display: block flex;
}

.inline-container {
    display: inline-flex;
    /* 相当于 */
    display: inline flex;
}

Flexbox中的换行

默认情况之下,位于Flexbox容器的所有子元素都会排在同一行(或同一列),但 Flexbox 容器的可用空间是未知的。当Flexbox没有足够多的空间来容纳其所有 Flex 项目(其子元素)时,Flex 项目会溢出 Flexbox 容器,将会打破布局或出现滚动条:

在Flexbox容器上显式设置 flex-wrap 的值为 wrap(默认值为 nowrap

css
.flex-box {
    display: flex;
    flex-wrap: wrap;
}

flex-wrap: wrap 只有在Flex项目不能自动收缩扩展状态下有效.如果在Flex项目中显式设置了 flex: 1 时,即使你在Flexbox容器上显式设置flex-wrapwrap也不能让Flex项目换行:

html
<div class="flex-box">
  <div class="flex-item"></div>
  <div class="flex-item"></div>
  <div class="flex-item"></div>
</div>
css
.flex-box {
    display: flex;
    flex-wrap: wrap;
}

.flex-item {
    flex: 1;
}

flex: 1

flex: 1 它相当于

css
flex-grow: 1;
flex-shrink: 1;
flex-basis: 0%;

如果未显式设置flex(它是flex-growflex-shrinkflex-basis的简写属性)时,其初始值是:

css
flex-grow: 0;
flex-shrink: 1;
flex-basis: auto;

默认情况下,元素不会缩短至小于内容框尺寸,若想改变这一状况,请设置元素的 min-widthmin-height 属性。

flex-basis 为 auto 时,Flex项目的宽度是 max-content

当设置 flex:1 时,flex-basis变成了0%,这将覆盖Flex项目的内在尺寸(max-content),Flex项目的基本尺寸现在是 0,但由于 flex-grow的存在,它们都可以增长以填补空的空间(Flexbox的剩余空间)。

在这种情况下,flex-shrink不再做任何事情,因为所有的Flex项目现在的宽度都是0,并且正在增长以填补可用空间。 只不过,Flexbox容器有可有没有剩余空间,甚至是有不足空间。这个时候,flex:1也就不能均分Flexbox容器了。

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

主轴上Flex项目的 overflow 属性是 visible 时,主轴上Flex项目的最小尺寸(min-size)将会指定一个自动的(automatic)最小尺寸 ”

flex-flow

flex-flow 属性是 flex-direction 和 flex-wrap 的简写。

flex-direction 中的 row-reverse 表现同 row ,但是置换了主轴起点和主轴终点

flex: 1 无效的情况

有时候设置flex: 1会无效。

这个时候有一种 hack 方式

使用 overflow: hidden; /* 或 auto, scroll */

为什么添加 overflow 有效

当你给元素添加 overflow 属性时,它会创建一个新的块级格式化上下文,这改变了元素的高度计算方式。

在 Flexbox 容器中:

  • height: 100% 需要明确的父元素高度参考
  • 但 flex 容器的高度是动态计算的
  • 这就造成了循环依赖:子元素需要父元素高度,父元素高度又依赖子元素
html
<!-- 之前:高度计算混乱 -->
<div class="flex-1 flex flex-col">
  <div style="height: 100%">内容</div>
</div>

<!-- 之后:高度计算正常 -->
<div class="flex-1 flex flex-col overflow-hidden">
  <div style="height: 100%">内容</div>
</div>

深层原理

  1. 强制高度确定: overflow 让浏览器必须确定容器的确切高度
  2. 打破循环依赖: 建立明确的高度参考点
  3. 触发重新计算: 浏览器重新评估整个布局

虽然 overflow 能解决问题,但更语义化的方法是使用 flex-1 + min-height: 0

css
/* 推荐方式 */
.flex-container {
  display: flex;
  flex-direction: column;
  min-height: 0; /* 关键! */
}

.flex-item {
  flex: 1;
  min-height: 0; /* 关键! */
}

Flex 上的滚动失效

flex-end为什么overflow无法滚动及解决方法


让CSS flex布局最后一行列表左对齐的N种方法

CSS 防御

终于搞懂了Flex:1 是怎么工作的了!