想象一下老陈的快递分拣中心:几十条传送带嗡嗡作响,包裹有大有小、有轻有重。刚到岗的小李发现,传送带上的包裹要么挤成一团,要么歪七扭八,还有的干脆悬在边缘。老陈拍了拍传送带说:“别急,真正的诀窍不是搬得快,而是让每条传送带都懂‘弹性规则’——这就是网页布局里的 Flexbox。” Flexbox,全称 Flexible Box Layout,中文叫“弹性盒子布局”。它像给传送带装上智能调度系统:容器决定包裹的排队方向(主轴),决定它们在垂直方向上如何站立(交叉轴),还能让包裹根据剩余空间自动伸缩。前端工程师用这套规则,就能让导航栏、卡片、按钮组在任意屏幕尺寸下保持整齐。 今天我们就跟着老陈,把 Flexbox 的主轴/交叉轴、对齐属性、伸缩比例、换行、与 Grid 的对比,以及响应式实战一次理清。

岗位关联

对 AI 从业者而言:无论你是在搭建模型训练看板、LLM 对话界面还是 AI 产品落地页,Flexbox 都是让你快速实现“自适应、不塌版”的布局核心能力,属于前端基本功中的必考点。

目录
  1. 可视化演示
  2. 容器与项目
  3. 主轴与交叉轴
  4. 容器对齐属性
  5. 项目弹性属性
  6. 换行与多行
  7. Flex与Grid对比
  8. 响应式实践
  9. AI 应用场景
  10. Python 演示
  11. 常见误区
  12. 面试题

可视化演示

演示Flexbox弹性布局核心概念:主轴与交叉轴、对齐方式、弹性伸缩计算和换行方向控制,通过交互式动画展示Flex容器的布局行为。

本节配有交互动效(进入视口后自动加载,约 3KB)。

主轴与交叉轴 主轴(Main Axis)默认水平 交叉轴(Cross)垂直主轴 flex-direction改变方向 两轴是Flexbox布局的基石

容器与项目

老陈带着小李走到 3 号传送带前,指了指传送带侧面的一个按钮:“这条带子只要贴上 display: flex 标签,就从普通铁架子变成了‘弹性舞台’。带子本身是容器,上面跑的包裹是项目。”小李发现,贴上标签后,包裹们仿佛突然有了秩序:谁在前、谁在后、怎么对齐,都由传送带说了算。

技术上说,任何 HTML 元素只要设置了 display: flex,就成了 Flex 容器;它的所有直接子元素自动变成 Flex 项目。容器掌控全局规则,比如排列方向、是否换行、项目之间的间距;项目则拥有“弹性权限”,比如自己是否多占空间、是否允许被压缩。两者构成一套完整的“双角色体系”。

这套体系之所以强大,是因为布局不再靠 float 和 position 反复试错。你只需要告诉容器“你是弹性盒子”,浏览器就会自动把项目按主轴和交叉轴组织起来。这就是 Flexbox 的起点。

小李在笔记本上写下:容器是舞台,项目是演员,弹性上下文是整场演出。只要舞台一贴上 display: flex,演员们就有了统一的站位纪律。

弹性上下文={主轴方向, 交叉轴方向, 项目序列}\text{弹性上下文} = \left\{ \text{主轴方向},\ \text{交叉轴方向},\ \text{项目序列} \right\}
这个公式描述:一个 Flex 布局由“主轴怎么走、交叉轴怎么站、有哪些子元素”三件事共同定义。
  1. 弹性上下文指 display: flex 之后形成的整个布局环境,如同传送带系统启动后的分拣区域。
    弹性上下文\text{弹性上下文}
  2. 主轴方向项目排队的基线方向,默认从左到右。
    主轴方向=row\text{主轴方向} = \text{row}
  3. 交叉轴方向与主轴垂直的方向,决定项目在垂直方向上如何对齐。
    交叉轴方向⊥主轴方向\text{交叉轴方向} \perp \text{主轴方向}
  4. 项目序列容器内的直接子元素,按照 DOM 顺序依次排列。
    项目序列={p1,p2,…,pn}\text{项目序列} = \{ p_1, p_2, \dots, p_n \}

主轴与交叉轴

“传送带为什么能左右跑、也能上下竖着跑?”老陈指着另一条垂直升降带说,“因为传送带有一根主动力线,叫主轴;与它垂直的货架滑轨,叫交叉轴。主轴一转,包裹就排队;交叉轴一摆,包裹就站高站低。”

在 Flexbox 里,flex-direction 负责决定主轴方向。默认值是 row,主轴水平从左到右;row-reverse 让主轴从右到左;column 把主轴变成垂直从上到下;column-reverse 则从下往上。交叉轴永远与主轴垂直:主轴水平时交叉轴垂直,主轴垂直时交叉轴水平。

理解主轴和交叉轴,是理解一切对齐属性的钥匙。justify-content 管的是“沿主轴怎么排”,align-items 管的是“沿交叉轴怎么站”;当 flex-direction 改成 column 后,两者操控的方向会互换,这也是初学者最容易犯晕的地方。

小李恍然大悟:原来“横排还是竖排”不是靠猜,而是靠主轴方向。记住一句话:主轴是传送带,交叉轴是升降架,二者永远垂直。

主轴方向={row水平从左到右row-reverse水平从右到左column垂直从上到下column-reverse垂直从下到上\text{主轴方向} =\begin{cases}\text{row} & \text{水平从左到右}\\\text{row-reverse} & \text{水平从右到左}\\\text{column} & \text{垂直从上到下}\\\text{column-reverse} & \text{垂直从下到上}\end{cases}
这段公式是方向字典:读出你想要的布局方向,再决定主轴怎么设置。
  1. row主轴水平向右,包裹像普通传送带一样从左侧上带。
    row⇒水平从左到右\text{row} \Rightarrow \text{水平从左到右}
  2. row-reverse主轴水平向左,起点在右端,包裹从右侧排队。
    row-reverse⇒水平从右到左\text{row-reverse} \Rightarrow \text{水平从右到左}
  3. column主轴垂直向下,相当于把传送带竖起来,包裹从上往下落。
    column⇒垂直从上到下\text{column} \Rightarrow \text{垂直从上到下}
  4. column-reverse主轴垂直向上,起点在下端,包裹从底部向上堆。
    column-reverse⇒垂直从下到上\text{column-reverse} \Rightarrow \text{垂直从下到上}

容器对齐属性

老陈让小李试着一个按钮一个按钮地调:按下“开头对齐”,包裹们齐刷刷挤在左侧;按下“居中”,包裹们退到中间;按下“两端对齐”,前后贴边、中间留缝;按下“均匀分布”,每个包裹周围都有差不多的呼吸空间。这就是 justify-content 的魔力。

justify-content 沿主轴方向分配剩余空间,主流的取值有 flex-start、center、flex-end、space-between、space-around、space-evenly。它的本质是:当包裹总宽小于传送带长度时,多出来的空白如何分配。另一边,align-items 管的是交叉轴上的对齐方式:stretch 让项目拉伸填满、center 居中、flex-start 贴顶、flex-end 贴底、baseline 按文字基线对齐。

此外,gap 属性可以直接设置项目之间的固定间距,不用再靠 margin 一个一调。gap 的值可以是一个长度,也可以是百分比,浏览器会自动在项目之间插出等宽缝隙。

小李在机器上调出了“两端对齐”,包裹首尾紧贴传送带两端,中间三个缝隙完全相等。他感叹:所谓对齐,不过是把剩余空间安排得明明白白。

相邻间距=剩余空间n−1,n>1\text{相邻间距} = \frac{\text{剩余空间}}{n - 1},\quad n > 1
这是 space-between 的计算逻辑:把多出来的空间平均分到相邻两两之间。
  1. 相邻间距任意两个相邻项目之间的空隙。
    相邻间距\text{相邻间距}
  2. 剩余空间容器主轴长度减去所有项目主轴尺寸之和后,剩下的空白区域。
    剩余空间=容器主轴长度−∑i=1n项目主轴尺寸i\text{剩余空间} = \text{容器主轴长度} - \sum_{i=1}^{n} \text{项目主轴尺寸}_i
  3. 除以 n-1因为 n 个项目只有 n-1 个“相邻缝隙”,把空白平均分摊。
    剩余空间n−1\frac{\text{剩余空间}}{n - 1}

项目弹性属性

包裹有大有小,但老陈手里有三张“弹性贴纸”可以贴在包裹上:一张写 flex-basis,决定包裹默认占多宽;一张写 flex-grow,决定有剩余空间时包裹有多大“胃口”;一张写 flex-shrink,决定传送带不够长时包裹愿意“瘦身”多少。

flex-grow 的默认值是 0,意思是“不抢多余空间”。假如剩余空间是 150px,三个项目的 flex-grow 分别为 1、2、0,那么空间会按 1:2:0 分配,后抢的项目一无所获。flex-shrink 的默认值是 1,意思是在空间不足时大家按加权比例缩小;而真正的收缩量,通常还要乘以每个项目的基础尺寸,才能模拟现实中的“大包裹更难被压缩”。

flex 是一个简写属性,一行就能定义三项:flex: 1 1 0% 等价于 flex-grow:1; flex-shrink:1; flex-basis:0%。实际开发中最常用的 flex: 1 就是三个项目均分剩余空间的经典写法。

小李给三个包裹分别贴上“胃口 1、2、0”,传送带空出一段后,前两个包裹胀了起来,第三个纹丝不动。他写下总结:grow 分的是“剩余空间”,不是“重新排大小”。

最终尺寸i=flex-basisi+fg,i∑jfg,j×剩余空间\text{最终尺寸}_i = \text{flex-basis}_i + \frac{f_{g,i}}{\sum_j f_{g,j}} \times \text{剩余空间}
这个公式适用于剩余空间为正的情况:每个项目先拿回自己的基础尺寸,再按 grow 比例分走剩余空间。
  1. flex-basis_i项目 i 在分配前的初始主轴尺寸,相当于包裹的出厂标签尺寸。
    flex-basisi\text{flex-basis}_i
  2. f_{g,i}项目 i 的 flex-grow 数值,表示它参与剩余空间分配的权重。
    fg,if_{g,i}
  3. 分母求和所有项目 grow 数值相加,算出每个权重占整体权重的比例。
    ∑jfg,j\sum_j f_{g,j}
  4. 乘以剩余空间用比例乘总空白,得到该项目额外分到的空间。
    fg,i∑jfg,j×剩余空间\frac{f_{g,i}}{\sum_j f_{g,j}} \times \text{剩余空间}

换行与多行

传送带只有一条,可包裹越来越多。老陈按下 flex-wrap: wrap,传送带瞬间分出第二层、第三层——第一层排满后,新的包裹自动滚到下一层继续排。这就是 Flex 的换行机制。

默认的 nowrap 会强迫所有项目挤在一条主轴线上,哪怕被压扁也不换行;而 wrap 允许项目在主轴排不下时,沿着交叉轴方向生成新的一行或多行。开启换行后,交叉轴上不再只有一条队伍,而是多条队伍叠放。

这时候,单行的 align-items 只管“行内站姿”,多行之间的整体分布则交给 align-content。align-content: space-between 可以让多行上下两端贴紧、中间均匀分布;center 可以让所有行整体垂直居中。它与 justify-content 的取值逻辑几乎一致,只不过操作对象从“一行内的项目”变成了“多行之间的行”。

小李看着原本挤巴巴的包裹在换行后一层层排开,恍然大悟:wrap 相当于给传送带增加了“立体多层”能力,也让响应式布局有了自然断行的可能。

若 ∑i=1n项目主尺寸i>容器主尺寸⇒触发换行\text{若 } \sum_{i=1}^{n} \text{项目主尺寸}_i > \text{容器主尺寸} \Rightarrow \text{触发换行}
当项目在主轴方向的总宽度超过容器时,flex-wrap: wrap 会让超出的项目换到新的交叉轴行。
  1. 项目主尺寸总和所有项目沿主轴方向的宽度或高度之和。
    ∑i=1n项目主尺寸i\sum_{i=1}^{n} \text{项目主尺寸}_i
  2. 容器主尺寸容器沿主轴方向可用的总宽度或高度。
    容器主尺寸\text{容器主尺寸}
  3. 大于判断一旦超出容器容量,换行机制被触发。
    ∑i=1n项目主尺寸i>容器主尺寸⇒换行\sum_{i=1}^{n} \text{项目主尺寸}_i > \text{容器主尺寸} \Rightarrow \text{换行}

Flex与Grid对比

老陈带着小李来到仓库后区,指着一面巨大的货架网格说:“传送带只解决一条线上的排队问题;可当我要铺满整面货架,让货架打横又打竖同时起作用时,就得请出 Grid。”这就是 Flex 与 Grid 最大的分水岭:Flex 是一维布局,Grid 是二维布局。

FlexBox 的核心是“内容驱动”:项目按内容自动排列,擅长导航栏、按钮组、卡片行这类线状结构。Grid 则更像“容器驱动”:先划好行和列,再把内容放进对应单元,擅长页面骨架、复杂仪表盘等棋盘式结构。

二者并非对立,而是配合关系。一个 Grid 容器内部完全可以嵌套 Flex 容器,让“整页网格”与“局部弹性排列”共存。布局选型时可以先问自己一个简单问题:我真正要排的是“一条线”还是“一个面”?

小李把“一行用 Flex,平面用 Grid”写在便签上,贴在工位前。老陈点头:布局工具没有高下之分,只有合不合适。

选型={Flex一维布局:只需处理一个方向Grid二维布局:需要同时控制行列\text{选型} =\begin{cases}\text{Flex} & \text{一维布局:只需处理一个方向}\\\text{Grid} & \text{二维布局:需要同时控制行列}\end{cases}
选型逻辑很简单:一条线用 Flex,一个面用 Grid,复杂页面把它们嵌套组合。
  1. 一维布局项目只沿主轴排列,交叉轴只用于对齐,不参与网格划分。
    一维布局⇒Flex\text{一维布局} \Rightarrow \text{Flex}
  2. 二维布局同时存在行与列的独立控制,适合页面级骨架。
    二维布局⇒Grid\text{二维布局} \Rightarrow \text{Grid}
  3. 组合使用Flex 与 Grid 可以嵌套,形成局部弹性 + 整体网格的混合布局。
    Grid 容器⊃Flex 容器\text{Grid 容器} \supset \text{Flex 容器}

响应式实践

分拣中心的传送带每天面对不同批次的包裹量,尺寸忽大忽小。老陈真正的绝活是:让一套 Flex 规则自动适应所有屏幕。小李最常用的三招就是“万能居中”“导航栏自适应”和“卡片流式换行”。

先说万能的垂直水平居中:只要给父容器设置 display: flex; justify-content: center; align-items: center;,无论容器尺寸怎么变,子元素永远稳稳地待在正中央。其次是导航栏:logo 靠左,菜单按钮靠右,只需要让右侧菜单容器设 margin-left: auto,就能把整块菜单推到最右端。

最后是自适应卡片流:给卡片设置 flex: 1 1 260px; flex-wrap: wrap;,当屏幕变宽时卡片自动横向铺开,屏幕变窄时卡片自动换行成多列,省掉大量媒体查询。移动端优先的团队,甚至会把 flex-direction: column 作为默认方向,再在大屏上切换成 row。

小李按这三招改造了分拣看板:页面在大屏上整齐铺开,在手机上一列到底。他终于明白,响应式不是“为每个屏幕写一套代码”,而是让弹性规则自动消化尺寸变化。

每项宽度=100%−gap×(n−1)n\text{每项宽度} = \frac{100\% - \text{gap} \times (n - 1)}{n}
如果你希望一排放 n 张卡片,同时保留等宽间隙,就可以用这个公式反推每一项的基础宽度。
  1. 每项宽度单张卡片在容器内应该占用的主尺寸百分比。
    每项宽度\text{每项宽度}
  2. gap 乘 n-1n 张卡片之间有 n-1 个固定间隙,需要从总宽度中让出来。
    gap×(n−1)\text{gap} \times (n - 1)
  3. 除以 n剩余可用宽度平均分给 n 张卡片。
    100%−gap×(n−1)n\frac{100\% - \text{gap} \times (n - 1)}{n}

AI 应用场景

AI 训练监控仪表盘

阶段:前端展示层开发

解决的问题:训练看板需要同时展示损失曲线、学习率、GPU 利用率等多个监控卡片,传统 float 布局在窗口缩放时经常错位;用 Flex 容器包裹卡片,配合 flex-wrap: wrap 和 flex-grow,卡片能自动换行并均分剩余宽度。

具体案例:某 MLOps 平台用 display: flex; flex-wrap: wrap; gap: 16px; 把 6 个指标卡片放在同一个弹性容器里。窗口缩小时卡片从 3 列自动变成 2 列再到 1 列,监控数据始终完整可见。

LLM 聊天界面消息布局

阶段:产品交互开发

解决的问题:聊天界面中“用户气泡靠右、AI 气泡靠左”需要快速切换,输入框和发送按钮要水平对齐。Flex 的 justify-content: flex-end 和 align-items: center 能轻松解决消息横竖对齐问题。

具体案例:某大模型应用把每条消息的 outer 容器设为 Flex,用户消息设置 justify-content: flex-end,AI 消息设置 flex-start;底部输入区用 align-items: center 让文本框和按钮垂直居中,适配各种屏幕。

模型推理结果展示

阶段:结果可视化

解决的问题:AI 生成的多张图片或表格结果需要顺序排列,并支持响应式缩放。Flexbox 主轴负责排列、交叉轴负责对齐,配合 flex-basis 可以控制每个结果卡片的初始最小宽度。

具体案例:一个文生图平台用 flex: 1 1 220px 展示生成结果,图片卡片随窗口大小均匀增宽或自动换行,用户无需横向滚动即可查看全部结果。

Python 演示

python35 行
def flex_layout(items, container_size):    """模拟单行 Flex 布局主尺寸计算。     items: 列表,每个元素含 basis/grow/shrink 三个键    container_size: 容器在主轴方向的总尺寸    """    bases = [item["basis"] for item in items]    basis_sum = sum(bases)    remaining = container_size - basis_sum     if remaining >= 0:        total_grow = sum(item["grow"] for item in items)        result = []        for item in items:            extra = remaining * item["grow"] / total_grow if total_grow else 0            result.append(item["basis"] + extra)    else:        overflow = -remaining        weighted = [item["basis"] * item["shrink"] for item in items]        total_weight = sum(weighted)        result = []        for item, w in zip(items, weighted):            shrink = overflow * w / total_weight if total_weight else 0            result.append(max(0, item["basis"] - shrink))    return result  if __name__ == "__main__":    items = [        {"basis": 100, "grow": 1, "shrink": 1},        {"basis": 200, "grow": 2, "shrink": 2},        {"basis": 150, "grow": 0, "shrink": 1},    ]    print("容器 600px:", flex_layout(items, 600))    print("容器 300px:", flex_layout(items, 300))
目的:用 Python 模拟 Flexbox 中 flex-grow 与 flex-shrink 的空间分配逻辑,帮助你直观理解弹性伸缩公式。
  1. basis_sum = sum(bases)先把所有项目的基础尺寸加起来,判断是否有剩余空间。
  2. remaining = container_size - basis_sum容器尺寸减去基础总尺寸,得到“剩余空间”或“溢出量”。
  3. total_grow = sum(item["grow"] for item in items)所有项目 flex-grow 之和,作为分配剩余空间的总权重。
  4. extra = remaining * item["grow"] / total_grow if total_grow else 0每个项目按自己的 grow 权重重分剩余空间。
  5. weighted = [item["basis"] * item["shrink"] for item in items]收缩时按“基础尺寸 × shrink”加权,体现大包裹更难被压缩。
  6. shrink = overflow * w / total_weight if total_weight else 0按加权比例从每个项目的基础尺寸中扣除溢出量。

常见误区

误区很多人以为要想让子元素“有弹性”,就该在子元素上写 `display: flex`。结果写了半天,发现元素根本没有变成弹性项目,布局也没变化。

正解display: flex 必须写在父容器上。父容器是传送带,子元素才是包裹。只有先激活传送带,包裹才会获得排队资格。想在子元素上控制伸缩,请用 flex-grow、flex-shrink、flex-basis,而不是 display: flex。

为何常见:名称里带有“flex”,容易让人下意识认为它是直接作用在子元素上的属性,忽略了“容器与项目”的双角色结构。

误区很多新手把 `justify-content` 固定理解为“水平居中”,把 `align-items` 固定理解为“垂直居中”,一旦 `flex-direction: column` 就彻底迷茫。

正解这两个属性作用的对象分别是“主轴”和“交叉轴”,而不是绝对的水平或垂直。主轴方向一旦被 flex-direction 改变,它们的管辖范围也会跟着交换。传送带如果竖起来,原来左右排列的规则就变成上下排列。

为何常见:日常看到的大多数案例都是 row 方向,导致大脑把“水平/垂直”与“主轴/交叉轴”的错误对应关系固化了。

误区有人给三个项目都设了 `flex-grow: 1`,发现宽窄不一样,以为是代码写错了,其实是因为没有设 `flex-basis`,项目仍按各自内容宽度分配。

正解flex-grow 分配的是“剩余空间”,不是把项目总宽度整体平分。只有把所有项目的 flex-basis 设为 0,剩余空间才等于容器全部宽度,三个 grow:1 的项目才会真正均分宽度,就像三只手从同一起点抢同一块蛋糕。

为何常见:日常口头禅“flex:1 是平均分配”省略了前提条件,让人误以为 grow 本身会重排基础宽度。

误区看到简写 `flex: 1` 和 `flex: auto` 都包含 grow:1,就以为它们等价,任意替换后布局却对不上。

正解flex: 1 等价于 1 1 0%,基础尺寸归零,所有项目从零开始按权重均分;flex: auto 等价于 1 1 auto,先保留内容大小,再分配剩余空间。一个是“从零分蛋糕”,一个是“先拿自己的再分蛋糕”。

为何常见:简写遮蔽了 flex-basis 的差异,而教材又常把“flex:1”当作标准写法,导致 auto 被忽略。

误区开启换行后,有人用 `align-items: center` 想让所有行整体居中,结果发现只有每行内部的项目被居中,多行之间的分布根本没变化。

正解align-items 只负责“单行内项目在交叉轴上的对齐”,多行之间的整体分布要交给 align-content。前者管一队人的站姿,后者管几队人之间的距离。

为何常见:换行产生多行后,视觉上仍然停留在“对齐”这个概念,忽略了一行和多行在属性职责上的分界。

面试题

Q1. 要让子元素进入弹性布局,正确的 CSS 写法是?

单选题 · easy

  • A.display: flex← 正确答案
  • B.position: flex
  • C.float: flex
  • D.flex: wrap

答案:A。display: flex 写在父容器上即可让直接子元素成为 Flex 项目,相当于给传送带贴标签。position 和 float 都没有“flex”取值,flex: wrap 也不是合法属性。

Q2. Flex 容器默认的主轴方向是?

单选题 · easy

  • A.水平向右← 正确答案
  • B.垂直向下
  • C.水平向左
  • D.垂直向上

答案:A。默认 flex-direction: row,主轴沿水平方向从左到右,项目依次横向排列。垂直方向需要显式设置 column 或 column-reverse。

Q3. justify-content: space-between 的效果是?

单选题 · mid

  • A.首尾贴边、中间平分空隙← 正确答案
  • B.所有项目平均分配空间
  • C.项目偏向起始端排列
  • D.项目沿交叉轴居中

答案:A。space-between 把剩余空间平均分到相邻项目之间,第一个项目贴容器起点,最后一个贴容器终点。B 更像 space-evenly,C 是 flex-start,D 是 align-items: center。

Q4. 想让三个项目均分容器剩余空间,最合适的简写是?

单选题 · mid

  • A.flex: 1 1 0%← 正确答案
  • B.flex: 0 1 auto
  • C.flex: 0 0 auto
  • D.flex: 1 0 auto

答案:A。flex: 1 1 0% 把基础尺寸归零,再让 grow 均分整个容器。B 保留内容宽度;C 不伸缩;D 允许 grow 但不允许 shrink,空间不足时容易溢出。

Q5. flex-direction: column 时,align-items: center 控制的是?

单选题 · mid

  • A.水平居中← 正确答案
  • B.垂直居中
  • C.主轴居中
  • D.项目拉伸

答案:A。column 下主轴变为垂直,交叉轴变为水平,所以 align-items: center 让项目在水平方向居中。B 是 justify-content: center 的效果,D 是 stretch 的效果。

Q6. 容器宽 600px,三个项目 basis 分别为 100/200/150,grow 为 1/2/0,第三个项目的最终宽度是?

单选题 · hard

  • A.150px← 正确答案
  • B.200px
  • C.250px
  • D.300px

答案:A。basis 总和为 450px,剩余 150px。第三个项目 grow 为 0,不参与剩余空间分配,因此最终宽度维持 basis 150px。前两个项目按 1:2 分走 50px 和 100px。

Q7. 容器宽 300px,basis 100/200/150,shrink 为 1/2/1,第一个项目最终宽度约为?

单选题 · hard

  • A.77px← 正确答案
  • B.100px
  • C.123px
  • D.50px

答案:A。基础总宽 450px,溢出 150px。加权权重为 100×1、200×2、150×1,总计 650。第一个项目被削减 150×(100/650)≈23px,最终约 77px。B 是零收缩,C 是错误权重,D 是误解。

Q8. 以下属于 Flex 容器属性的有?

多选题 · mid

  • A.justify-content← 正确答案
  • B.flex-grow
  • C.align-items← 正确答案
  • D.flex-wrap← 正确答案

答案:ACD。容器属性负责整体排列规则:justify-content 管主轴分布、align-items 管交叉轴对齐、flex-wrap 管换行。flex-grow 是写在项目上控制自身伸缩的,不属于容器属性。

Q9. 关于 flex-wrap: wrap,正确的说法有?

多选题 · mid

  • A.主轴方向发生改变
  • B.项目可以溢出到多行← 正确答案
  • C.交叉轴可能出现多行← 正确答案
  • D.剩余空间分配方式改变

答案:BC。wrap 让项目在主轴排不下时换到新的一行,新行在交叉轴方向堆叠形成多行。主轴方向由 flex-direction 决定,与换行无关;虽然换行后单行剩余空间可能变化,但属性本身不直接改变分配方式,所以 A、D 不选。

Q10. 关于 Flex 与 Grid 的区别,正确的是?

多选题 · hard

  • A.Flex 是一维布局模型← 正确答案
  • B.Grid 是二维布局模型← 正确答案
  • C.Grid 能完全替代 Flex
  • D.Flex 容器可以嵌套 Grid← 正确答案

答案:ABD。Flex 只处理一个主轴方向,Grid 同时处理行和列。二者各有优劣,Grid 不能完全替代 Flex,尤其在单行弹性排列场景下。实际开发中常见 Grid 整页布局配合 Flex 局部弹性,二者可互相嵌套。