Flexbox(Flexible Box Layout)是 CSS3 引入的一维布局模型,专门用于在容器的主轴方向上分配空间和对齐元素。在 Flexbox 出现之前,实现垂直居中、等分列、动态分配宽度这些需求往往需要各种 hack 技巧,比如浮动加清除浮动、表格布局、行内块加空白符处理等。Flexbox 让这些曾经的难题变得轻而易举。
基本概念
Flexbox 的核心是两个角色:弹性容器(Flex Container)和弹性项目(Flex Item)。将一个元素的 display 设为 flex 或 inline-flex,它就变成了弹性容器,其直接子元素自动成为弹性项目。
.container {
display: flex;
/* 此时 .container 是弹性容器 */
/* 其直接子元素成为弹性项目 */
}
Flex 布局围绕两根轴运作:主轴(Main Axis)是弹性项目排列的方向,默认是水平从左到右;交叉轴(Cross Axis)与主轴垂直,默认是从上到下。理解这两根轴是掌握 Flexbox 的关键。
容器属性
flex-direction
定义主轴方向,决定弹性项目如何排列:
.container {
display: flex;
flex-direction: row; /* 默认,水平从左到右 */
flex-direction: row-reverse; /* 水平从右到左 */
flex-direction: column; /* 垂直从上到下 */
flex-direction: column-reverse; /* 垂直从下到上 */
}
justify-content
控制弹性项目在主轴上的对齐方式和剩余空间分配:
.container {
display: flex;
justify-content: flex-start; /* 默认,起始对齐 */
justify-content: flex-end; /* 末尾对齐 */
justify-content: center; /* 居中对齐 */
justify-content: space-between; /* 两端对齐,项目间等距 */
justify-content: space-around; /* 每个项目两侧等距 */
justify-content: space-evenly; /* 完全均匀分布 */
}
align-items
控制弹性项目在交叉轴上的对齐方式:
.container {
display: flex;
align-items: stretch; /* 默认,拉伸填满容器高度 */
align-items: flex-start; /* 交叉轴起始对齐 */
align-items: flex-end; /* 交叉轴末尾对齐 */
align-items: center; /* 交叉轴居中 */
align-items: baseline; /* 按文本基线对齐 */
}
flex-wrap 与 gap
默认情况下弹性项目不会换行。设置 flex-wrap: wrap 后,当项目总宽度超出容器时自动换行。gap 属性则直接控制项目之间的间距:
.container {
display: flex;
flex-wrap: wrap;
gap: 16px; /* 项目之间的间距,行和列都生效 */
}
项目属性
flex-grow、flex-shrink、flex-basis
这三个属性共同控制弹性项目如何伸缩。通常推荐使用简写属性 flex:
.item {
/* flex-grow: 放大比例,默认 0(不放大) */
/* flex-shrink: 缩小比例,默认 1(等比缩小) */
/* flex-basis: 初始大小,默认 auto */
flex: 0 1 auto; /* 默认值,不放大、可缩小 */
flex: 1; /* 等价于 flex: 1 1 0%,等分空间 */
flex: 2; /* 占据 flex:1 项目两倍的空间 */
flex: auto; /* 等价于 flex: 1 1 auto */
flex: none; /* 等价于 flex: 0 0 auto,固定大小 */
}
order 与 align-self
order 可以改变项目的视觉排列顺序,默认值为 0,值越小越靠前。align-self 允许单个项目覆盖容器的 align-items 设置:
.item-first {
order: -1; /* 排到最前面 */
}
.item-tall {
align-self: stretch; /* 单独拉伸 */
}
常见布局模式
完美居中
Flexbox 实现居中只需三行代码,这是它最受欢迎的用法:
.center-box {
display: flex;
justify-content: center;
align-items: center;
height: 300px;
}
导航栏布局
Logo 在左,导航链接在右,中间自动填充空间:
.navbar {
display: flex;
align-items: center;
padding: 0 24px;
height: 60px;
}
.navbar .logo {
flex: none; /* Logo 固定宽度 */
}
.navbar .links {
flex: 1; /* 链接区域占满剩余空间 */
display: flex;
justify-content: flex-end;
gap: 20px;
}
卡片网格
等宽卡片自动换行排列,响应式无需媒体查询:
.card-grid {
display: flex;
flex-wrap: wrap;
gap: 24px;
}
.card {
flex: 1 1 300px; /* 最小宽度 300px,自动填充 */
max-width: calc(50% - 12px); /* 最多两列 */
padding: 20px;
border: 1px solid #e0e0e0;
border-radius: 8px;
}
等高列布局
传统 CSS 实现等高列需要各种技巧,而 Flexbox 默认就支持:
.columns {
display: flex;
gap: 20px;
}
.column {
flex: 1;
/* 所有列自动等高,无需额外设置 */
}
注意事项
Flexbox 是一维布局模型,适合处理单行或单列的场景。如果需要同时控制行和列,应该使用 CSS Grid。此外,flex 简写属性中只写一个数值时(如 flex: 1),浏览器会将 flex-basis 设为 0% 而非 auto,这在某些场景下会影响项目内容的最小宽度计算,需要特别注意。
Flexbox 已经得到了所有现代浏览器的完整支持,在项目中可以放心使用。它极大地简化了 CSS 布局的复杂度,是每个前端开发者必须掌握的核心技能。