Skip to content

Flexbox水太深,你把持不住 #407

@mqyqingfeng

Description

@mqyqingfeng

我以前以为我懂 flexbox,于是给容器加个 display: flex,然后就祈祷布局如我所愿。

有时候确实有效,但大部分时候,我得到了一堆“各自为政”的列,完全不是我想要的样子。

直到我发现了这三个简单模式,一切都变了。

1. 核心问题:为什么布局总是乱?

你创建了 3 个完美的列,宽度相等,间距美观,你感到自己很帅。

然后你添加了一些内容——这里有一段长文字,那里有个短标题。

突然第 2 列变得巨大,第 3 列却瘦得像竹竿。

为什么?

因为 flexbox 默认会让内容决定布局。

但这种做法实际上在破坏你的设计!

2. 模式一:真正的等宽列

你想要实现真正的等宽列,该如何实现?

大多数人一开始会这样写:

/* 看起来很合理,对吧? */
.column {
  width: 33.33%;
}

但如果你是 2 列、4 列、5 列呢?如果一个项目有内边距呢?

真正有效的解决方案是:

.even-columns {
  display: flex;
}

.even-columns > * {
  flex-basis: 100%;
}

就这么简单,两行代码搞定。

为什么要设置 flex-basis: 100%

因为你在告诉每一列都保持相同的大小

由于默认允许收缩,它们会等比例缩小来适应空间。它们会协调分配空间,而不是各自为政。

当你删除一列时**,也**没问题,剩余列会自动扩展填满空间。添加一列时,也是如此。

我经常用这个模式,导航菜单、功能卡片、团队成员介绍——任何需要列的地方都可以用。

image.png

3. 模式二:智能网格(告别媒体查询)

如果你想要一个能根据可用空间自动调整的网格,你该如何实现?

以前我们要写一堆的媒体查询,但我们可没时间搞这个了!

直接上我们的解决方案:

.gridish {
  display: flex;
  flex-wrap: wrap;
}

.gridish > * {
  flex: 1 1 15rem;
}

让我解释下这个设置:

  • flex-wrap: wrap 的意思是:“如果空间不够,把项目换到下一行”

  • flex: 1 1 15rem 的意思是:“我可以扩大,也允许收缩,理想大小是 15rem”

  • 合起来就是:“尽可能保持 15rem 宽,但可以扩展填满空间或换行”

于是当你调整屏幕大小时,项目会自动流动。

三列变成两列,再变成一列,然后又变回三列。无需断点,无需媒体查询,智能布局。

我把这个用在博客布局上,每个文章卡片至少需要 15rem 才能好看。于是在宽屏上,显示四列。在平板上,显示两到三列。在手机上,堆叠显示,布局自动调整。

关键在于选择合适的 flex-basis 值。

太小了,移动端会有尴尬的超窄列。太大了,什么都并排不了。我通常从 15rem 开始,根据实际内容调整。

image.png

4. 模式三:内容-侧边栏保持黄金比例

现在我们实现一个典型的博客布局:

主体内容占大头,右边一个固定宽度的侧边栏。

大部分教程会让你用百分比或固定宽度。

但当屏幕变窄时,这两种方法都会失败——要不然内容变得不可读,要不然侧边栏变得非常窄。

其实你应该这样写:

.content-sidebar {
  display: flex;
  flex-wrap: wrap;
}

.main-content {
  flex: 1 1 70%;
  min-width: 25ch;
}

.sidebar {
  flex: 1 1 30%;
  min-width: 15ch;
}

关键在于 min-widthch 单位代表字符宽度, 25ch 意思是“绝不小于 25 个字符”。

此时会发生什么呢?

  • 宽屏幕: 70/30 分割,看起来很专业

  • 中等屏幕: 仍然并排,调整比例

  • 窄屏幕: 当任何一列达到最小宽度时,它们就堆叠

无需断点,布局会在内容需要时自然断裂。

flexbox_content_sidebar

5. 什么时候用这些模式?

模式一(等宽列): 导航菜单、功能卡片——任何需要等宽列的地方

模式二(智能网格): 博客布局、图片画廊、产品网格——任何需要内容自然流动的地方

模式三(内容侧边栏): 文章布局、仪表板面板——任何需要主要和次要内容的地方

应用场景总结海报

6. 思维转变

写 CSS 的时候,我经历过“改三行 CSS,刷新十次”的抓狂时刻。

后来我慢慢懂了一个道理:布局就像搭积木,你先决定“规则”,然后让它自己长成最合适的样子。

Flexbox 的魅力不在于“精准像素控制”,而在于“给出合理约束,剩下交给它”。

今天和你分享的这三个模式,保你在大多数业务页面里稳稳当当地交付。

等把它们用熟了,再去实现更复杂的响应式细节和组合策略,也会顺手很多。

我是冴羽,10 年笔耕不辍,专注前端领域,更新了 10+ 系列、300+ 篇原创技术文章,翻译过 Svelte、Solid.js、TypeScript 文档,著有小册《Next.js 开发指南》、《Svelte 开发指南》、《Astro 实战指南》。

欢迎围观我的“网页版朋友圈”,关注我的公众号:冴羽(或搜索 yayujs),每天分享前端知识、AI 干货。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions