李涛自留地
回到顶部
首页 > 前端 > flex布局的适用范围到底有多大,我拿三个页面做了对比

flex布局的适用范围到底有多大,我拿三个页面做了对比

文章目录

上周三晚上十点多,我在改一个后台列表页,本来只想加个横向滚动,结果 flex 怎么写都别扭,右边按钮老被挤到第二行,当时第一反应是这破布局又抽风了。索性把手上三个页面拆开重做,顺手把 flex布局的适用范围 摸了一遍,也踩了两个坑,这篇就是那晚的记录。

三个页面,先交代各自的布局长相

三个页面都不复杂:一个是顶部导航加内容区,一个是商品卡片列表,一个是详情页的规格参数表。我当时以为一套 flex 能全包,结果第三个页面直接把我按在椅子上改了半小时。

剖面里被弹性绳沿单轴分配的容器层,flex布局的适用范围

我判断一个布局要不要用 flex,现在只问一句:这些元素是排在一条线上,还是要同时对齐行和列。前者交给 flex,后者别硬来,这是我踩过坑才服气的结论。

为了看清楚,我把三个页面的容器样式都翻出来,在开发者工具里逐个改 display 的值,看布局怎么塌、怎么复位。这一折腾倒省了不少猜想,哪个页面该换容器,切一下就见分晓。

这三个页面也正好把 flex布局的适用范围 的边界撑开了。我拿它们当样本,是因为它们分别踩在一维、二维和混合三种形态上,比看文档里的示意图直观得多。

flex布局适用场景:一条线上的分配和顺序

导航栏是典型。左边 logo,中间几个菜单,右边一个按钮,全在同一行。这种地方用 flex 最省事,justify-content 管主轴空隙,align-items 管纵向对齐,两行 CSS 就完事。

我习惯先给容器 display: flex,再用 gap 拉开间距。老实说 gap 比给子元素加 margin 干净得多,最后一个元素也不用写 :last-child 去清边距。

.nav {
  display: flex;
  align-items: center;
  gap: 24px;
}

.nav__actions {
  margin-left: auto;
}

上面这段里 margin-left: auto 是我顺手学的招,它会把剩余空间全吃掉,等于把右侧按钮顶到最右边。比你算宽度、写绝对定位都省事,窄屏下也不会错位。

说回 flex布局的适用范围:凡是「一维」的排列,工具栏、标签页、一行输入框加按钮、卡片里的图标配文字,基本都在它的地盘里。这条线画清楚,后面判断就不容易跑偏。

我当时以为 flex 只能做横向,结果 flex-direction: column 一样顺手。纵向排列的时候,主轴变成上下,justify-content 和 gap 管的是块与块的间距,align-items 管的是横向怎么摆。想左右分栏又要求等高,那还是得回 row 方向配 align-items: stretch,column 下这条管的是宽度,别把两件事记混。

这一步做完我才确认,flex布局的适用范围 里最稳的一块就是一维分配:谁多宽、谁对齐、谁吃剩下的空间,都是它擅长的事。超出这个范围,问题就开始来了。

第二个页面翻车了:卡片墙不该硬套

商品列表那页我一开始也是 flex,容器加 flex-wrap: wrap,每个卡片写 width: calc(33.33% - 16px)。看着能跑,窗口一缩就露馅,最后一行常剩两张卡孤零零靠左,右边空一大块。

那晚我折腾了快四十分钟,试过给容器加 justify-content: space-between,间距又乱;试过用 :nth-child 补 margin,代码越写越长,索性全删了重来。

多行铺开、最后一行没铺满的卡片阵列,flex布局的适用范围

换成 grid 之后,问题一下就没了。卡片自动换行,间距由 gap 统一管,窄屏也不用堆媒体查询。

.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 16px;
}

auto-fill 和 auto-fit 的区别得留意,这是第二个坑:auto-fill 按容器宽度保留空轨道,最后一行两张卡照样靠左留白;auto-fit 会把空轨道压掉再拉伸剩下的卡片,才铺得满。我一开始抄的是 auto-fill,看半天以为没用,换成 auto-fit 那两张卡才撑开。列数要稳定的页面我还是用 auto-fill 多一些,改版时不容易塌。

这一页让我重新审了一遍 flex布局的适用范围。它在二维网格面前确实到顶了,硬套只会拿一堆 calc 和 nth-child 去补,维护起来太折腾,白跑的时间比省下的多。

顺便说一句,flex-wrap: wrap 不是没用,标签云那种长短不一、只求排满一行的东西,它比 grid 更随性。它算 flex布局的适用范围 的边缘地带,能用,但别指望它对齐。我当时错在拿它去撑一个需要严格对齐的卡片墙。

flex和grid怎么选:看一维还是二维

我的做法分两步。第一步看内容:卡片、表格这种行列明确的,直接 grid;工具栏、按钮组这种排一行的,用 flex。第二步看伸缩:谁该吃掉剩余空间,就把 flex: 1 给它。

选择依据我不看流行度,只看两条:要不要同时控制行和列,内容尺寸是不是由容器决定。前者要 grid,后者 flex 更自在,flex和grid怎么选 这个问题基本就落到这里。

还有个坑我吃过亏:flex 子元素默认 flex-shrink: 1,内容一长就被压扁。做文字加省略号的布局,得给文字块加 min-width: 0,不然 text-overflow: ellipsis 根本不生效。

这个坑很隐蔽,我当时盯着 overflow: hidden 找了半天,结果问题在父级的收缩上。你遇到文字撑不开、省略号不出来,先查这一条。

顺带提一句,min-width: 0 这条也算 flex布局的适用范围 里的隐形规则,凡是内容可能溢出的子项,都值得加上。

被卡住的队列压弯的分支结构,flex布局的适用范围

详情页的规格表我最后用了 grid,两列固定,grid-template-columns: 120px 1fr,标签一列、值一列,比 flex 加固定宽度省心,长文本换行也不用单独处理。

我现在的判断顺序

拿到一个页面,我先在纸上画一遍它是一维分布还是二维分布,再决定容器用谁。flex布局的适用范围 说大不大,说小也不小,写业务够用,但别拿它当万能钥匙。

混用也很正常。外层 grid 划区域,每个区域内部用 flex 排一行按钮,这种组合我在后台项目里天天写,没什么别扭的。你如果也在写后台,大概率已经是这么干的。

说到底工具没有高下,只有合不合适。flex布局的适用范围 我认下来就三样:一维、流动、需要伸缩,别的场合老老实实换 grid。

最后留一句经验:布局写完把浏览器窗口从 400 拉到满屏,来回两遍,会变形的地方一眼就看出来,比事后改 bug 省事得多。这个坑我踩过一次,你照着拉一遍就行。

若非作者标注皆为李涛自留地原创文章,转载或复制请以超链接形式并注明出处。