前端布局指南
前端布局完全指南
布局技术全解析 + 场景搭配推荐
目录
1. CSS 基础布局属性
1.1 display 属性
控制元素的显示类型
/* 外部显示类型 - 决定元素如何参与文档流 */
display: block; /* 块级元素,独占一行,可设宽高 */
display: inline; /* 行内元素,不换行,宽高无效 */
display: inline-block; /* 行内块,不换行,可设宽高 */
display: run-in; /* 嵌入块(浏览器支持有限) */
/* 内部显示类型 - 决定元素内部布局方式 */
display: flow; /* 常规文档流 */
display: flow-root; /* 生成新的 BFC 容器 */
display: flex; /* 弹性盒子 */
display: grid; /* 网格布局 */
display: subgrid; /* 继承父级网格 */
/* 表格布局 */
display: table;
display: inline-table;
display: table-row;
display: table-cell;
display: table-row-group;
display: table-header-group;
display: table-footer-group;
display: table-column;
display: table-column-group;
display: table-caption;
/* 列表布局 */
display: list-item;
/* 金属性布局 */
display: ruby;
display: ruby-base;
display: ruby-text;
display: ruby-base-container;
display: ruby-text-container;
/* 动画 */
display: contents; /* 纯容器,不渲染自身 */
display: none; /* 隐藏,不渲染 */
1.2 position 定位
/* 静态定位 - 默认值,不定位 */
position: static;
/* 相对定位 - 相对于自身原位置定位 */
position: relative;
top: 10px; right: 20px; bottom: 10px; left: 20px;
/* 绝对定位 - 相对于最近定位祖先元素 */
position: absolute;
top: 0; right: 0; bottom: 0; left: 0;
/* 固定定位 - 相对于视口定位 */
position: fixed;
top: 20px; right: 20px;
/* 粘性定位 - 混合定位方式 */
position: sticky;
top: 0; /* 到达此位置时变为固定定位 */
/* z-index 层级 */
z-index: 1; /* 数值越大越上层 */
z-index: auto; /* 与父元素同层级 */
z-index: -1; /* 在内容后面 */
1.3 float 浮动
⚠️ 已不推荐使用,仅作了解
float: left; /* 左浮动 */
float: right; /* 右浮动 */
float: none; /* 不浮动 */
/* 清除浮动 */
clear: left; /* 清除左浮动 */
clear: right; /* 清除右浮动 */
clear: both; /* 清除所有浮动 */
/* 清除浮动 hack */
.clearfix::after {
content: '';
display: block;
clear: both;
}
/* BFC 清除浮动 */
.clearfix {
overflow: hidden; /* 或 auto */
}
1.4 BFC (Block Formatting Context)
块级格式化上下文 - 独立的渲染区域
/* 触发 BFC 的方式 */
display: flow-root;
display: flex;
display: grid;
position: absolute;
position: fixed;
float: left/right;
overflow: hidden/auto/scroll;
/* BFC 特性 */
.bfc {
display: flow-root;
/* 内部的 Box 会在垂直方向依次排列 */
/* 垂直方向的距离由 margin 决定 */
/* 不会与浮动元素重叠 */
/* 计算 BFC 高度时包含浮动元素 */
}
1.5 IFC (Inline Formatting Context)
行内格式化上下文
/* IFC 特性 */
.ifc {
/* 水平方向排列 */
/* 垂直方向可以设置 line-height */
/* vertical-align 影响垂直对齐 */
vertical-align: baseline; /* 默认基线对齐 */
vertical-align: top; /* 与行中最高元素顶部对齐 */
vertical-align: middle; /* 居中对齐 */
vertical-align: bottom; /* 与行中最低元素底部对齐 */
vertical-align: sub; /* 下标 */
vertical-align: super; /* 上标 */
vertical-align: 10px; /* 数值偏移 */
vertical-align: 50%; /* 百分比偏移 */
}
1.6 多列布局 (Multi-column)
/* 列数 */
column-count: 3; /* 固定列数 */
column-count: auto; /* 根据宽度自动 */
/* 列宽 */
column-width: 200px; /* 固定列宽 */
column-width: auto;
/* 简写 */
columns: 200px 3; /* 列宽 列数 */
/* 列间距 */
column-gap: 20px;
column-gap: normal; /* 默认 1em */
/* 列边框 */
column-rule: 2px solid #ccc;
column-rule-width: 2px;
column-rule-style: solid;
column-rule-color: #ccc;
/* 列高度平衡 */
column-fill: balance; /* 各列高度尽量平衡 */
column-fill: auto; /* 按顺序填充 */
/* 跨列 */
column-span: all; /* 跨越所有列 */
column-span: 1; /* 只在一列中 */
1.7 书写模式 (Writing Mode)
/* 水平书写模式 - 默认 */
writing-mode: horizontal-tb;
/* 垂直书写模式 */
writing-mode: vertical-rl; /* 从右到左 */
writing-mode: vertical-lr; /* 从左到右 */
/* 文字方向 */
direction: ltr; /* 从左到右 */
direction: rtl; /* 从右到左 */
/* 文本对齐 */
text-align: left;
text-align: right;
text-align: center;
text-align: justify; /* 两端对齐 */
/* 混合模式 */
text-combine-upright: all; /* 组合竖排数字 */
text-orientation: mixed; /* 混合方向 */
text-orientation: upright; /* 直立方向 */
1.8 表格显示布局
/* 表格布局算法 */
table-layout: auto; /* 自动布局(默认) */
table-layout: fixed; /* 固定布局,性能更好 */
/* 边框折叠 */
border-collapse: collapse; /* 合并边框 */
border-collapse: separate; /* 分离边框 */
/* 边框间距 */
border-spacing: 10px;
border-spacing: 10px 5px;
/* 空单元格 */
empty-cells: show; /* 显示 */
empty-cells: hide; /* 隐藏 */
/* 表格标题位置 */
caption-side: top;
caption-side: bottom;
2. Flexbox 弹性布局
2.1 核心概念
主轴 (Main Axis) - 弹性项目排列的方向
交叉轴 (Cross Axis) - 垂直于主轴的方向
主尺寸 (Main Size) - 主轴方向的尺寸
交叉尺寸 - 交叉轴方向的尺寸
2.2 容器属性
/* 主轴方向 */
flex-direction: row; /* 从左到右(默认) */
flex-direction: row-reverse; /* 从右到左 */
flex-direction: column; /* 从上到下 */
flex-direction: column-reverse; /* 从下到上 */
/* 换行行为 */
flex-wrap: nowrap; /* 不换行(默认) */
flex-wrap: wrap; /* 换行,第一行在上 */
flex-wrap: wrap-reverse; /* 换行,第一行在下 */
/* 方向 + 换行简写 */
flex-flow: row wrap;
/* 主轴对齐方式 */
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: stretch; /* 拉伸填满(默认) */
align-items: flex-start; /* 起始对齐 */
align-items: flex-end; /* 末尾对齐 */
align-items: center; /* 居中对齐 */
align-items: baseline; /* 基线对齐 */
/* 多行对齐(flex-wrap: wrap 时有效) */
align-content: stretch; /* 拉伸行 */
align-content: flex-start; /* 起始对齐 */
align-content: flex-end; /* 末尾对齐 */
align-content: center; /* 居中对齐 */
align-content: space-between; /* 两端对齐 */
align-content: space-around; /* 行间距相等 */
align-content: space-evenly; /* 行间距相等 */
2.3 项目属性
/* 放大比例 */
flex-grow: 0; /* 不放大(默认) */
flex-grow: 1; /* 占据剩余空间 */
/* 缩小比例 */
flex-shrink: 1; /* 必要时缩小(默认) */
flex-shrink: 0; /* 不缩小 */
/* 基础尺寸 */
flex-basis: auto; /* 自动(默认) */
flex-basis: 200px; /* 固定宽度 */
flex-basis: 50%; /* 百分比 */
flex-basis: 10vw;
/* flex 简写 */
/* flex: flex-grow flex-shrink flex-basis */
flex: 0 1 auto; /* 默认值 */
flex: 1; /* flex: 1 1 0% - 放大,缩小,0基础 */
flex: auto; /* flex: 1 1 auto */
flex: none; /* flex: 0 0 auto - 不放大不缩小 */
flex: 0 0 200px; /* 固定尺寸 */
/* 单个项目交叉轴对齐 */
align-self: auto; /* 继承 align-items */
align-self: stretch;
align-self: flex-start;
align-self: flex-end;
align-self: center;
align-self: baseline;
/* 排列顺序 */
order: 0; /* 默认顺序 */
order: -1; /* 排在最前面 */
order: 1; /* 排到最后面 */
2.4 Flexbox 布局模式
水平居中
.center-x {
display: flex;
justify-content: center;
}
垂直居中
.center-y {
display: flex;
align-items: center;
}
水平垂直居中
.center-xy {
display: flex;
justify-content: center;
align-items: center;
}
两端对齐
.space-between {
display: flex;
justify-content: space-between;
}
等间距
.space-evenly {
display: flex;
justify-content: space-evenly;
}
响应式换行
.wrap {
display: flex;
flex-wrap: wrap;
gap: 20px;
}
底部对齐
.align-bottom {
display: flex;
align-items: flex-end;
}
菜单导航
.nav {
display: flex;
justify-content: space-between;
align-items: center;
}
列表项
.list {
display: flex;
flex-direction: column;
}
等高列
.equal-height {
display: flex;
}
.equal-height > * {
flex: 1;
}
3. Grid 网格布局
3.1 核心概念
-
网格容器 - 应用
display: grid的元素 - 网格项目 - 网格容器的直接子元素
- 网格线 - 划分网格的线
- 网格轨道 - 相邻网格线之间的区域
- 网格单元格 - 网格的最小单位
- 网格区域 - 多个单元格组成的矩形区域
3.2 容器属性
/* 定义网格轨道 */
grid-template-columns: 100px 100px 100px; /* 3列固定宽度 */
grid-template-columns: 1fr 2fr 1fr; /* 比例分配 */
grid-template-columns: repeat(3, 1fr); /* 重复3次 */
grid-template-columns: repeat(auto-fit, 200px); /* 自适应列数 */
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); /* 最小最大 */
grid-template-columns: [start] 100px [line2] 1fr [end];
grid-template-rows: 100px auto 1fr; /* 3行 */
grid-template-rows: repeat(3, 1fr);
/* 隐式网格 */
grid-auto-rows: 100px; /* 自动行高 */
grid-auto-columns: 1fr; /* 自动列宽 */
grid-auto-flow: row; /* 按行填充(默认) */
grid-auto-flow: column; /* 按列填充 */
grid-auto-flow: dense; /* 填充空白 */
/* 简写 */
grid-template: 100px auto / 1fr 1fr 1fr; /* 行 / 列 */
/* 间距 */
gap: 20px;
row-gap: 10px;
column-gap: 20px;
/* 网格区域 */
grid-template-areas:
"header header header"
"sidebar main aside"
"footer footer footer";
3.3 对齐属性
/* 整个网格在容器中的对齐 */
/* 行方向对齐(水平) */
justify-content: start; /* 起始对齐 */
justify-content: end; /* 末尾对齐 */
justify-content: center; /* 居中 */
justify-content: stretch; /* 拉伸填满 */
justify-content: space-around;
justify-content: space-between;
justify-content: space-evenly;
/* 列方向对齐(垂直) */
align-content: start;
align-content: end;
align-content: center;
align-content: stretch;
align-content: space-around;
align-content: space-between;
align-content: space-evenly;
/* 单元格内容对齐 */
/* 水平对齐 */
justify-items: start;
justify-items: end;
justify-items: center;
justify-items: stretch;
/* 垂直对齐 */
align-items: start;
align-items: end;
align-items: center;
align-items: stretch;
/* place-items 简写 */
place-items: center center;
3.4 项目属性
/* 网格定位 */
grid-column-start: 1;
grid-column-end: 3;
grid-row-start: 1;
grid-row-end: 4;
/* 简写 */
grid-column: 1 / 3; /* 开始 / 结束 */
grid-column: 1 / span 2; /* 开始 / 跨越数 */
grid-row: 1 / 4;
/* 网格区域 */
grid-area: header;
grid-area: 1 / 1 / 3 / 4; /* 行开始 / 列开始 / 行结束 / 列结束 */
/* 单个项目对齐 */
justify-self: start;
justify-self: end;
justify-self: center;
justify-self: stretch;
align-self: start;
align-self: end;
align-self: center;
align-self: stretch;
place-self: center center;
3.5 Grid 布局模式
基础网格
.basic-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20px;
}
自适应网格
.auto-fit-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 20px;
}
圣杯布局
.holy-grail {
display: grid;
grid-template-columns: 200px 1fr 200px;
grid-template-rows: auto 1fr auto;
min-height: 100vh;
grid-template-areas:
"header header header"
"sidebar main aside"
"footer footer footer";
}
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main { grid-area: main; }
.aside { grid-area: aside; }
.footer { grid-area: footer; }
12栏栅格系统
.grid-12 {
display: grid;
grid-template-columns: repeat(12, 1fr);
gap: 20px;
}
.col-1 { grid-column: span 1; }
.col-2 { grid-column: span 2; }
.col-3 { grid-column: span 3; }
.col-4 { grid-column: span 4; }
.col-5 { grid-column: span 5; }
.col-6 { grid-column: span 6; }
.col-7 { grid-column: span 7; }
.col-8 { grid-column: span 8; }
.col-9 { grid-column: span 9; }
.col-10 { grid-column: span 10; }
.col-11 { grid-column: span 11; }
.col-12 { grid-column: span 12; }
/* 偏移 */
.offset-1 { grid-column-start: 2; }
.offset-2 { grid-column-start: 3; }
瀑布流
.masonry {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
grid-auto-rows: 10px;
}
.masonry-item:nth-child(1) { grid-row-end: span 35; }
.masonry-item:nth-child(2) { grid-row-end: span 15; }
.masonry-item:nth-child(3) { grid-row-end: span 25; }
/* 实际使用需配合 JS 计算高度 */
4. 响应式布局
4.1 媒体查询
/* 媒体类型 */
@media screen { }
@media print { }
@media speech { }
@media all { }
/* 媒体特性 */
@media (width: 768px) { }
@media (min-width: 768px) { }
@media (max-width: 768px) { }
@media (orientation: portrait) { } /* 竖屏 */
@media (orientation: landscape) { } /* 横屏 */
@media (aspect-ratio: 16/9) { }
@media (prefers-color-scheme: dark) { }
@media (prefers-reduced-motion: reduce) { }
/* 逻辑运算符 */
@media (min-width: 768px) and (max-width: 1024px) { }
@media (min-width: 768px), (orientation: portrait) { }
@media not (min-width: 768px) { }
/* 组合媒体查询 */
@media (min-width: 640px) { }
@media (min-width: 768px) { }
@media (min-width: 1024px) { }
@media (min-width: 1280px) { }
4.2 断点策略
/* 移动优先 - 在小屏幕上写默认样式 */
:root {
--breakpoint-sm: 640px;
--breakpoint-md: 768px;
--breakpoint-lg: 1024px;
--breakpoint-xl: 1280px;
--breakpoint-2xl: 1536px;
}
/* 小平板 */
@media (min-width: 640px) { }
/* 平板 */
@media (min-width: 768px) { }
/* 小桌面 */
@media (min-width: 1024px) { }
/* 桌面 */
@media (min-width: 1280px) { }
/* 大桌面 */
@media (min-width: 1536px) { }
4.3 常见框架断点
| 框架 | 手机 | 平板 | 桌面 |
|---|---|---|---|
| Bootstrap | <576px | ≥576px | ≥768px |
| Tailwind | <640px | ≥640px | ≥1024px |
| Material UI | 0 | 600px | 960px |
| Ant Design | <576px | ≥576px | ≥992px |
5. 常见布局模式
5.1 垂直居中
/* 方法1: Flexbox */
.center-flex {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}
/* 方法2: Grid */
.center-grid {
display: grid;
place-items: center;
min-height: 100vh;
}
/* 方法3: absolute + transform */
.center-absolute {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
/* 方法4: grid + margin */
.center-margin {
display: grid;
justify-content: center;
align-content: center;
min-height: 100vh;
}
/* 方法5: table-cell (古老方法) */
.center-table {
display: table-cell;
vertical-align: middle;
text-align: center;
width: 100%;
height: 100vh;
}
5.2 Sticky Footer
/* Flexbox 方案 */
.sticky-footer {
display: flex;
flex-direction: column;
min-height: 100vh;
}
.sticky-footer > header {
flex: 0;
}
.sticky-footer > main {
flex: 1;
}
.sticky-footer > footer {
flex: 0;
}
/* Grid 方案 */
.sticky-footer-grid {
display: grid;
grid-template-rows: auto 1fr auto;
min-height: 100vh;
}
/* calc 方案 */
.sticky-footer-calc {
min-height: 100vh;
padding-bottom: 60px; /* footer 高度 */
}
.sticky-footer-calc footer {
height: 60px;
margin-top: -60px;
}
5.3 圣杯布局
/* Flexbox 方案 */
.holy-grail {
display: flex;
flex-direction: column;
min-height: 100vh;
}
.holy-grail-body {
display: flex;
flex: 1;
}
.holy-grail-main {
flex: 1;
order: 2;
}
.holy-grail-sidebar {
width: 200px;
order: 1;
}
.holy-grail-aside {
width: 200px;
order: 3;
}
/* 响应式 */
@media (max-width: 768px) {
.holy-grail-body {
flex-direction: column;
}
.holy-grail-sidebar,
.holy-grail-aside {
width: 100%;
}
}
5.4 双飞翼布局
/* 特点:中间栏优先渲染 */
.double-wing {
display: flex;
}
.double-wing .main {
flex: 1;
min-width: 0;
}
.double-wing .left,
.double-wing .right {
width: 200px;
}
.double-wing .left {
order: 1;
}
.double-wing .main {
order: 2;
}
.double-wing .right {
order: 3;
}
5.5 等高布局
/* Flexbox - 天然等高 */
.equal-height {
display: flex;
}
.equal-height > * {
flex: 1;
}
/* Grid - 天然等高 */
.equal-height-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
}
/* table - 天然等高 */
.equal-height-table {
display: table;
width: 100%;
}
.equal-height-table > * {
display: table-cell;
}
5.6 瀑布流布局
/* CSS Columns */
.masonry-columns {
column-count: 3;
column-gap: 20px;
}
.masonry-columns > .item {
break-inside: avoid;
margin-bottom: 20px;
}
/* Grid - 需配合 JS */
.masonry-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20px;
}
/* Flexbox - 有限支持 */
.masonry-flex {
display: flex;
flex-wrap: wrap;
}
.masonry-flex > .item {
width: calc(33.333% - 14px);
margin-bottom: 20px;
}
5.7 侧边栏布局
/* 左侧固定,右侧自适应 */
.sidebar-main {
display: flex;
}
.sidebar-main .sidebar {
width: 250px;
flex-shrink: 0;
}
.sidebar-main .main {
flex: 1;
min-width: 0;
}
/* 右侧固定,左侧自适应 */
.main-sidebar {
display: flex;
}
.main-sidebar .main {
flex: 1;
min-width: 0;
}
.main-sidebar .sidebar {
width: 250px;
flex-shrink: 0;
}
5.8 两栏布局
/* 左宽右窄 */
.two-col {
display: flex;
}
.two-col .left {
flex: 2;
}
.two-col .right {
flex: 1;
}
/* 各占一半 */
.half-half {
display: flex;
}
.half-half > * {
flex: 1;
}
5.9 三栏布局
/* 两侧固定,中间自适应 */
.three-col {
display: flex;
}
.three-col .left,
.three-col .right {
width: 200px;
flex-shrink: 0;
}
.three-col .center {
flex: 1;
min-width: 0;
}
/* Grid 版本 */
.three-col-grid {
display: grid;
grid-template-columns: 200px 1fr 200px;
}
5.10 流式布局
/* 百分比宽度 */
.fluid {
width: 100%;
max-width: 1200px;
margin: 0 auto;
padding: 0 20px;
box-sizing: border-box;
}
/* calc 响应式 */
.fluid-calc {
width: calc(100% - 40px);
margin: 0 auto;
}
6. CSS 框架布局方案
6.1 Tailwind CSS
/* Flexbox */
.flex { display: flex; }
.flex-row { flex-direction: row; }
.flex-col { flex-direction: column; }
.flex-wrap { flex-wrap: wrap; }
.justify-start { justify-content: flex-start; }
.justify-center { justify-content: center; }
.justify-between { justify-content: space-between; }
.items-start { align-items: flex-start; }
.items-center { align-items: center; }
.items-stretch { align-items: stretch; }
/* Grid */
.grid { display: grid; }
.grid-cols-1 { grid-template-columns: repeat(1, minmax(0, 1fr)); }
.grid-cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid-cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grid-cols-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.gap-1 { gap: 0.25rem; }
.gap-2 { gap: 0.5rem; }
.gap-4 { gap: 1rem; }
.gap-8 { gap: 2rem; }
/* 响应式 */
@media (min-width: 640px) {
.sm\:flex-row { flex-direction: row; }
.sm\:grid-cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 768px) {
.md\:flex-row { flex-direction: row; }
.md\:grid-cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (min-width: 1024px) {
.lg\:grid-cols-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
/* 间距 */
.p-1 { padding: 0.25rem; }
.p-2 { padding: 0.5rem; }
.p-4 { padding: 1rem; }
.m-auto { margin: auto; }
.mx-auto { margin-left: auto; margin-right: auto; }
/* 宽高 */
.w-full { width: 100%; }
.h-full { height: 100%; }
.min-h-screen { min-height: 100vh; }
/* 定位 */
.absolute { position: absolute; }
.relative { position: relative; }
.fixed { position: fixed; }
.inset-0 { top: 0; right: 0; bottom: 0; left: 0; }
6.2 Bootstrap 5
/* 容器 */
.container { max-width: 540px; }
.container-sm { max-width: 540px; }
.container-md { max-width: 720px; }
.container-lg { max-width: 960px; }
.container-xl { max-width: 1140px; }
.container-xxl { max-width: 1320px; }
.container-fluid { width: 100%; }
/* 12栏栅格 */
.row { display: flex; flex-wrap: wrap; margin: -0.75rem; }
.col { flex: 1 0 0%; }
.col-1 { flex: 0 0 auto; width: 8.333333%; }
.col-2 { flex: 0 0 auto; width: 16.666667%; }
.col-3 { flex: 0 0 auto; width: 25%; }
.col-4 { flex: 0 0 auto; width: 33.333333%; }
.col-6 { flex: 0 0 auto; width: 50%; }
.col-12 { flex: 0 0 auto; width: 100%; }
/* 响应式栅格 */
@media (min-width: 576px) {
.col-sm { flex: 1 0 0%; }
}
@media (min-width: 768px) {
.col-md { flex: 1 0 0%; }
}
@media (min-width: 992px) {
.col-lg { flex: 1 0 0%; }
}
@media (min-width: 1200px) {
.col-xl { flex: 1 0 0%; }
}
/* Flex */
.d-flex { display: flex; }
.d-inline-flex { display: inline-flex; }
.flex-row { flex-direction: row; }
.flex-column { flex-direction: column; }
.flex-wrap { flex-wrap: wrap; }
.flex-nowrap { flex-wrap: nowrap; }
.justify-content-start { justify-content: flex-start; }
.justify-content-center { justify-content: center; }
.justify-content-between { justify-content: space-between; }
.align-items-start { align-items: flex-start; }
.align-items-center { align-items: center; }
.align-items-stretch { align-items: stretch; }
/* 间距 */
.g-0 { gap: 0; }
.g-1 { gap: 0.25rem; }
.g-2 { gap: 0.5rem; }
.g-3 { gap: 1rem; }
.g-4 { gap: 1.5rem; }
.g-5 { gap: 3rem; }
.p-0 { padding: 0; }
.p-1 { padding: 0.25rem; }
.p-2 { padding: 0.5rem; }
.p-3 { padding: 1rem; }
.p-4 { padding: 1.5rem; }
.p-5 { padding: 3rem; }
.m-0 { margin: 0; }
.mx-auto { margin-left: auto; margin-right: auto; }
.mt-2 { margin-top: 0.5rem; }
.mb-2 { margin-bottom: 0.5rem; }
7. 主流 UI 框架布局
7.1 Ant Design (React)
// 基础布局组件
import { Layout, Header, Sider, Content, Footer } from 'antd';
<Layout>
<Header>Header</Header>
<Layout>
<Sider width={200}>Sider</Sider>
<Content>Content</Content>
</Layout>
<Footer>Footer</Footer>
</Layout>
// 响应式布局
<Layout>
<Sider
breakpoint="lg"
collapsedWidth="0"
onBreakpoint={(broken) => {}}
onCollapse={(collapsed, type) => {}}
>
Sider
</Sider>
<Layout>
<Header />
<Content />
<Footer />
</Layout>
</Layout>
// Grid 栅格
import { Row, Col } from 'antd';
<Row gutter={[16, 16]}>
<Col xs={24} sm={12} md={8} lg={6}>Col</Col>
<Col xs={24} sm={12} md={8} lg={6}>Col</Col>
<Col xs={24} sm={12} md={8} lg={6}>Col</Col>
</Row>
// Flex 布局
<div className="flex-center">...</div>
<div className="flex-between">...</div>
7.2 Element UI (Vue)
<!-- 基础布局 -->
<el-container>
<el-header>Header</el-header>
<el-container>
<el-aside width="200px">Aside</el-aside>
<el-main>Main</el-main>
</el-container>
<el-footer>Footer</el-footer>
</el-container>
<!-- 响应式布局 -->
<el-container>
<el-aside :width="isCollapse ? '64px' : '200px'">...</el-aside>
<el-container>
<el-header>...</el-header>
<el-main>...</el-main>
</el-container>
</el-container>
<!-- Row / Col 栅格 -->
<el-row :gutter="20">
<el-col :span="6" :xs="24" :sm="12" :md="8" :lg="6">
<div class="grid-content"></div>
</el-col>
</el-row>
<!-- Flex 布局 -->
<el-row type="flex" justify="center" align="middle">
<el-col>...</el-col>
</el-row>
7.3 Material UI (React)
import { Box, Grid, Container, Stack } from '@mui/material';
import { AppBar, Toolbar } from '@mui/material';
// 基础布局
<Box sx={{ display: 'flex' }}>
<AppBar position="fixed">...</AppBar>
<Box component="main" sx={{ flexGrow: 1, p: 3 }}>
Content
</Box>
</Box>
// Container 居中容器
<Container maxWidth="sm">
<Box>Content</Box>
</Container>
// Grid 栅格系统
<Grid container spacing={2}>
<Grid item xs={12} sm={6} md={4}>Item</Grid>
<Grid item xs={12} sm={6} md={4}>Item</Grid>
<Grid item xs={12} sm={6} md={4}>Item</Grid>
</Grid>
// Stack 堆叠布局
<Stack direction="row" spacing={2}>
<Item>Item 1</Item>
<Item>Item 2</Item>
<Item>Item 3</Item>
</Stack>
7.4 Vuetify (Vue)
<!-- 布局系统 -->
<v-app>
<v-app-bar>...</v-app-bar>
<v-navigation-drawer>...</v-navigation-drawer>
<v-main>
<v-container>Content</v-container>
</v-main>
<v-footer>...</v-footer>
</v-app>
<!-- 栅格系统 -->
<v-row>
<v-col cols="12" sm="6" md="4" lg="3">Col</v-col>
<v-col cols="12" sm="6" md="4" lg="3">Col</v-col>
</v-row>
<!-- 间隙 -->
<v-row no-gutters>...</v-row>
<v-row justify="center">...</v-row>
7.5 其他框架
| 框架 | 布局组件 | 栅格系统 | 特点 |
|---|---|---|---|
| Radix UI | 无官方 | 无官方 | Headless 组件 |
| Chakra UI | Box, Flex, Grid | 响应式样式 | 主题化能力强 |
| Mantine | AppShell | 12栏 | 现代 React 栈 |
| Arco Design | Layout | Row/Col | 企业级 |
| TDesign | Layout | Row/Col | 腾讯设计体系 |
| Semi Design | Layout | Row/Col | 抖音设计体系 |
8. 布局搭配推荐
8.1 页面整体结构
推荐: Grid + Flexbox 组合
/* 页面结构 - Grid */
.page {
display: grid;
grid-template-rows: auto 1fr auto; /* header main footer */
grid-template-columns: auto 1fr; /* sidebar main */
min-height: 100vh;
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
}
/* 组件内部 - Flexbox */
.page > nav {
display: flex;
justify-content: space-between;
align-items: center;
}
.page > aside {
display: flex;
flex-direction: column;
}
8.2 导航栏
推荐: Flexbox
/* 顶部导航 */
.navbar {
display: flex;
justify-content: space-between;
align-items: center;
height: 60px;
padding: 0 20px;
}
.navbar-menu {
display: flex;
gap: 20px;
list-style: none;
}
/* 移动端导航 */
@media (max-width: 768px) {
.navbar {
flex-wrap: wrap;
}
.navbar-menu {
display: none; /* 或使用 hamburger menu */
}
}
8.3 卡片列表
推荐: Grid + auto-fit
.card-list {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 24px;
}
.card {
display: flex;
flex-direction: column;
/* 卡片内部等高 */
}
.card-content {
flex: 1;
}
8.4 表单布局
推荐: Grid (对齐) + Flexbox (排列)
.form-grid {
display: grid;
gap: 20px;
max-width: 600px;
}
.form-row {
display: flex;
gap: 16px;
}
.form-row > * {
flex: 1;
}
@media (max-width: 600px) {
.form-row {
flex-direction: column;
}
}
8.5 详情页
推荐: Grid 2列 + Flexbox
.detail-page {
display: grid;
grid-template-columns: 1fr 300px;
gap: 40px;
}
@media (max-width: 768px) {
.detail-page {
grid-template-columns: 1fr;
}
}
/* 左侧内容区域 */
.detail-content {
display: flex;
flex-direction: column;
gap: 24px;
}
/* 右侧侧边栏 */
.detail-sidebar {
display: flex;
flex-direction: column;
gap: 20px;
position: sticky;
top: 20px;
}
8.6 仪表盘
推荐: Grid 网格 + Flexbox 组件
.dashboard {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: auto auto 1fr;
gap: 24px;
grid-template-areas:
"stat1 stat2 stat3 stat4"
"chart1 chart1 chart2 chart2"
"table table table table";
}
.stat-card {
display: flex;
flex-direction: column;
justify-content: space-between;
}
@media (max-width: 1024px) {
.dashboard {
grid-template-columns: repeat(2, 1fr);
}
}
@media (max-width: 640px) {
.dashboard {
grid-template-columns: 1fr;
}
}
8.7 聊天/消息界面
推荐: Grid + Flexbox 组合
.chat-layout {
display: grid;
grid-template-columns: 280px 1fr;
height: 100vh;
}
.chat-list {
display: flex;
flex-direction: column;
border-right: 1px solid #eee;
}
.chat-message {
display: flex;
gap: 12px;
margin-bottom: 16px;
}
.chat-message.me {
flex-direction: row-reverse;
}
@media (max-width: 768px) {
.chat-layout {
grid-template-columns: 1fr;
}
}
8.8 电商商品页
推荐: Grid 2列 + Flexbox
.product-page {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 40px;
max-width: 1200px;
margin: 0 auto;
}
.product-gallery {
display: flex;
flex-direction: column;
gap: 16px;
}
.product-thumbnails {
display: flex;
gap: 12px;
}
.product-info {
display: flex;
flex-direction: column;
gap: 20px;
}
.product-actions {
display: flex;
gap: 16px;
}
@media (max-width: 768px) {
.product-page {
grid-template-columns: 1fr;
}
}
8.9 文章/博客
推荐: 居中布局 + Grid
.article-layout {
display: grid;
grid-template-columns: 1fr min(700px, 100%) 1fr;
}
.article-layout > * {
grid-column: 2;
}
.article-layout > .full-width {
grid-column: 1 / -1;
}
.article-content {
font-size: 18px;
line-height: 1.8;
}
.article-content p {
margin-bottom: 1.5em;
}
8.10 登录/注册页
推荐: Flexbox 居中 或 Grid 居中
/* 方案1: Flexbox */
.login-page {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background: #f5f5f5;
}
.login-card {
width: 100%;
max-width: 400px;
padding: 40px;
background: white;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}
/* 方案2: Grid */
.login-page-grid {
display: grid;
place-items: center;
min-height: 100vh;
}
9. 现代布局技巧
9.1 clamp() 响应式尺寸
/* 响应式字体 */
h1 {
font-size: clamp(1.5rem, 5vw, 3rem);
}
h2 {
font-size: clamp(1.25rem, 4vw, 2rem);
}
/* 响应式宽度 */
.container {
width: clamp(300px, 80%, 1200px);
}
/* 响应式内边距 */
.box {
padding: clamp(10px, 5vw, 40px);
}
9.2 aspect-ratio 比例
/* 16:9 视频 */
.video {
aspect-ratio: 16 / 9;
width: 100%;
}
/* 1:1 正方形 */
.avatar {
aspect-ratio: 1;
width: 100px;
}
/* 4:3 图片 */
.photo {
aspect-ratio: 4 / 3;
}
/* 响应式比例 */
.card-image {
aspect-ratio: 4/3;
}
@media (min-width: 768px) {
.card-image {
aspect-ratio: 16/9;
}
}
9.3 container 查询
/* 定义容器 */
.card-container {
container-type: inline-size;
container-name: card;
}
/* 容器查询 */
@container card (min-width: 400px) {
.card {
display: grid;
grid-template-columns: 1fr 2fr;
}
.card-title {
font-size: 1.25rem;
}
}
@container card (min-width: 600px) {
.card {
grid-template-columns: 1fr 3fr;
}
}
9.4 逻辑属性
/* 物理属性 */
margin-left: 10px;
padding-top: 20px;
/* 逻辑属性 - 适应书写模式 */
margin-inline-start: 10px; /* 左边距/右边距(取决于方向) */
margin-block-start: 20px; /* 上边距/下边距(取决于方向) */
padding-inline: 16px; /* 内联方向 */
padding-block: 16px; /* 块方向
width: 100%;
min-inline-size: 100%; /* 逻辑宽度 */
/* 边框 */
border-inline-start: 1px solid #ccc;
border-block-end: 2px solid blue;
/* 定位 */
inset-inline-start: 10px;
inset-block-end: 10px;
9.5 subgrid 子网格
.parent-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20px;
}
.child-grid {
display: grid;
grid-template-columns: subgrid; /* 继承父网格 */
grid-column: 1 / -1;
}
9.6 is() :has() 选择器
/* is() - 简化选择器 */
:is(header, footer) {
background: #f5f5f5;
}
/* has() - 父选择器 */
.card:has(.badge) {
position: relative;
}
.card:has(img) {
padding-top: 0;
}
/* 布局中的应用 */
.grid:has(.featured) {
grid-template-columns: 2fr 1fr;
}
10. 布局最佳实践
10.1 技术选型原则
| 场景 | 推荐技术 | 原因 |
|---|---|---|
| 单行/单列排列 | Flexbox | 简单直观 |
| 二维布局 | Grid | 行列同时控制 |
| 整体页面骨架 | Grid | 结构清晰 |
| 组件内部 | Flexbox | 灵活方便 |
| 居中 | Grid place-items | 最简代码 |
| 响应式网格 | Grid + auto-fit | 智能列数 |
| 均匀间距 | Flexbox + gap | 统一管理 |
| 等高列 | Flexbox / Grid | 天然支持 |
| 表单布局 | Grid | 对齐控制 |
| 复杂对齐 | Grid | 精确定位 |
10.2 性能优化
/* 避免布局抖动 */
.card {
/* 明确指定尺寸 */
min-height: 100px;
}
/* 使用 will-change 优化动画 */
.animated {
will-change: transform;
transform: translateZ(0); /* 硬件加速 */
}
/* 减少重排 */
.bad {
width: calc(100% - 20px); /* 可能引发重排 */
}
.good {
padding: 0 10px; /* 更好 */
}
/* contain 属性 */
.isolate {
contain: layout style paint;
}
10.3 可访问性
/* 焦点可见 */
:focus-visible {
outline: 2px solid blue;
outline-offset: 2px;
}
/* 减少动画 */
@media (prefers-reduced-motion: reduce) {
* {
animation: none !important;
transition: none !important;
}
}
/* 暗色模式 */
@media (prefers-color-scheme: dark) {
:root {
--bg-color: #1a1a1a;
--text-color: #ffffff;
}
}
/* 高对比度 */
@media (prefers-contrast: more) {
.card {
border: 2px solid currentColor;
}
}
10.4 CSS 变量
:root {
/* 布局变量 */
--spacing-xs: 4px;
--spacing-sm: 8px;
--spacing-md: 16px;
--spacing-lg: 24px;
--spacing-xl: 32px;
/* 栅格 */
--grid-gap: 20px;
--grid-columns: 12;
/* 容器 */
--container-sm: 540px;
--container-md: 720px;
--container-lg: 960px;
--container-xl: 1140px;
/* 颜色 */
--color-bg: #ffffff;
--color-text: #333333;
}
.container {
max-width: var(--container-xl);
margin: 0 auto;
padding: 0 var(--spacing-md);
}
.grid {
display: grid;
gap: var(--grid-gap);
grid-template-columns: repeat(var(--grid-columns), 1fr);
}
附录
常用工具
浏览器支持
| 技术 | Chrome | Firefox | Safari | Edge |
|---|---|---|---|---|
| Flexbox | 29+ | 28+ | 9+ | 12+ |
| Grid | 57+ | 52+ | 10.1 | 16+ |
| gap (flex) | 84+ | 63+ | 14.1 | 84+ |
| subgrid | 117+ | 71+ | 16+ | 117+ |
| container | 105+ | 110+ | 16+ | 105+ |
| clamp() | 79+ | 75+ | 13.1 | 79+ |
| aspect-ratio | 84+ | 82+ | 15 | 84+ |