4、Flexbox弹性布局:Flex容器属性、Flex项目属性、常见布局模式、实战案例
Flexbox,说实话,是我日常开发中用得最多的布局方案。没有之一。
我记得刚入行那会儿,还在用float+clearfix那套老办法做导航栏,每次都要算宽度、清浮动,烦得很。后来接触了Flexbox,感觉整个世界都清爽了。你想想看,一行代码就能让子元素水平居中,这在以前得折腾多少东西?
好,咱们今天就把Flexbox彻底讲透。从容器属性到项目属性,再到常见的布局套路,最后带一个实战案例。我保证,学完这节课,你以后写页面布局会顺手很多。
4.1 Flex容器属性:掌控大局的指挥官
先搞清楚一个概念:Flex容器和Flex项目。给一个元素设置 display: flex;,它就变成了容器,它的直接子元素自动成为项目。容器属性管的是「整体怎么排」,项目属性管的是「每个元素怎么站」。
4.1.1 flex-direction:主轴方向
这是最基础的属性。它决定了主轴的方向,也就是项目排列的走向。
row(默认):从左到右水平排列row-reverse:从右到左水平排列column:从上到下垂直排列column-reverse:从下到上垂直排列
我的习惯:做导航栏、卡片列表用 row;做表单、纵向菜单用 column。别纠结,用多了自然就记住了。
4.1.2 flex-wrap:换行策略
项目太多,一行装不下怎么办?这个属性就是管这个的。
nowrap(默认):不换行,强行压缩项目宽度wrap:换行,项目保持原尺寸wrap-reverse:换行,但新行在上方
我曾经踩过的坑:做商品列表时,忘了设 flex-wrap: wrap;,结果所有商品挤在一行,图片都变形了。排查了半天才发现是默认不换行。嗯,这个坑你们别踩。
4.1.3 justify-content:主轴对齐
这个属性太常用了。它控制项目在主轴方向上的对齐方式。
| 值 | 效果 |
|---|---|
flex-start | 左对齐(默认) |
flex-end | 右对齐 |
center | 居中 |
space-between | 两端对齐,项目之间间距相等 |
space-around | 每个项目两侧间距相等 |
space-evenly | 所有间距完全相等 |
我个人最常用的是 space-between 和 center。比如做导航栏,logo在左、菜单在右,用 space-between 一行代码搞定。
4.1.4 align-items:交叉轴对齐
主轴搞定了,交叉轴也得管。这个属性控制项目在交叉轴方向上的对齐。
stretch(默认):拉伸填满容器高度flex-start:顶部对齐flex-end:底部对齐center:垂直居中baseline:基线对齐
小技巧:想让一个盒子在页面正中间?display: flex; justify-content: center; align-items: center; 三行代码搞定。以前用绝对定位得算半天偏移量,现在多省事。
4.1.5 align-content:多行对齐
这个属性只有在 flex-wrap: wrap 且有多行时才生效。它控制整个「行组」在交叉轴上的对齐方式。取值跟 justify-content 类似,就不重复了。
4.2 Flex项目属性:每个元素的自我修养
容器属性管整体,项目属性管个体。每个项目都可以有自己的「想法」。
4.2.1 flex-grow:放大比例
默认是0,表示不放大。如果所有项目都设为1,它们会等分剩余空间。如果某个项目设为2,它占的空间是其他项目的两倍。
/* 左侧固定,右侧自适应 */
.left { flex-grow: 0; width: 200px; }
.right { flex-grow: 1; }
这个模式我几乎天天用。左侧导航栏固定宽度,右侧内容区自适应,完美。
4.2.2 flex-shrink:缩小比例
默认是1,表示空间不够时可以缩小。设为0表示打死也不缩小。
注意:如果所有项目都设了 flex-shrink: 0,而容器宽度不够,内容会溢出。我见过有人把每个项目都设成不缩小,结果页面出现了横向滚动条,用户体验很差。
4.2.3 flex-basis:初始尺寸
可以理解为项目在主轴方向上的「理想尺寸」。默认是 auto,即项目本身的宽或高。
4.2.4 flex:简写属性
推荐用这个简写,一行搞定三个属性:flex: grow shrink basis;
/* 常用写法 */
flex: 1; /* 等价于 flex: 1 1 0% */
flex: auto; /* 等价于 flex: 1 1 auto */
flex: none; /* 等价于 flex: 0 0 auto */
我个人习惯用 flex: 1 做自适应布局,简洁明了。
4.2.5 align-self:个体对齐
覆盖容器的 align-items 设置。比如容器统一左对齐,但某个特殊项目想靠右,就用这个。
4.2.6 order:排列顺序
默认是0。数值越小越靠前。可以设为负数。
实战场景:移动端想把「提交按钮」放在表单最前面,但PC端想放最后。用 order 配合媒体查询,不用改HTML结构,爽得很。
4.3 常见布局模式:拿来即用的套路
下面这几个模式,是我这些年总结出来的高频场景。你直接复制代码改改就能用。
4.3.1 水平居中
.container {
display: flex;
justify-content: center;
}
4.3.2 垂直居中
.container {
display: flex;
align-items: center;
}
4.3.3 水平垂直居中
.container {
display: flex;
justify-content: center;
align-items: center;
}
4.3.4 圣杯布局(两侧固定,中间自适应)
.container {
display: flex;
}
.left { width: 200px; flex-shrink: 0; }
.right { width: 200px; flex-shrink: 0; }
.center { flex: 1; }
4.3.5 等分布局
.container {
display: flex;
}
.item {
flex: 1;
}
4.3.6 流式布局(自动换行)
.container {
display: flex;
flex-wrap: wrap;
gap: 16px;
}
.item {
width: calc(33.33% - 16px);
}
注意:gap 属性在Flexbox中已经得到广泛支持了。以前得用margin模拟间距,现在直接用 gap,干净利落。
4.4 实战案例:响应式导航栏 + 卡片列表
光说不练假把式。咱们来做一个完整的页面片段:顶部导航栏 + 下方商品卡片列表。
4.4.1 HTML结构
<nav class="navbar">
<div class="logo">我的商店</div>
<ul class="nav-links">
<li>首页</li>
<li>商品</li>
<li>关于</li>
<li>联系</li>
</ul>
</nav>
<section class="card-list">
<div class="card">商品1</div>
<div class="card">商品2</div>
<div class="card">商品3</div>
<div class="card">商品4</div>
<div class="card">商品5</div>
<div class="card">商品6</div>
</section>
4.4.2 CSS样式
/* 导航栏 */
.navbar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 16px 24px;
background: #f5f5f5;
}
.nav-links {
display: flex;
gap: 24px;
list-style: none;
}
/* 卡片列表 */
.card-list {
display: flex;
flex-wrap: wrap;
gap: 20px;
padding: 24px;
}
.card {
flex: 1 1 calc(33.33% - 20px);
min-width: 250px;
padding: 40px;
background: #fff;
border: 1px solid #e0e0e0;
border-radius: 8px;
text-align: center;
}
/* 响应式:小屏幕变两列 */
@media (max-width: 768px) {
.card {
flex: 1 1 calc(50% - 20px);
}
}
/* 响应式:手机屏幕变一列 */
@media (max-width: 480px) {
.card {
flex: 1 1 100%;
}
}
我的经验:做响应式时,我习惯先写PC端样式,再用媒体查询向下兼容。但如果你做的是移动端优先的项目,反过来写也行。关键是保持一致性。
4.5 避坑指南
- flex-basis 和 width 的关系:当
flex-direction: row时,flex-basis会覆盖width。我刚开始学的时候被这个坑过。 - min-width 的优先级:即使设了
flex-shrink: 1,项目也不会缩小到min-width以下。这是浏览器的保护机制。 - 不要滥用 flex: 1:所有项目都设
flex: 1确实能等分,但如果内容长短不一,视觉上可能不整齐。这时候用flex: 1 1 0%更稳妥。
好了,Flexbox的核心内容就这些。说实话,这个知识点不难,但需要多练。你可以在CodePen上随便拖几个盒子试试,玩熟了自然就记住了。下一节咱们聊Grid布局,那又是另一个世界了。