2602 字
13 分钟
CSS Flexbox & Grid 布局完全指南
🎨 CSS Flexbox & Grid 布局完全指南
目录
📋 概述
CSS布局技术从传统的float和position发展到现代的Flexbox和Grid,为开发者提供了强大而灵活的布局解决方案。本文将深入探讨这两种现代布局技术,帮助你掌握构建复杂布局的核心技能。
🔧 Flexbox 弹性盒子布局
什么是Flexbox?
Flexbox(弹性盒子)是CSS3引入的一维布局方法,用于在容器中排列项目,即使在不知道项目大小或项目大小可变的情况下也能有效工作。
🎯 Flexbox 核心概念
/* Flex 容器 */.flex-container { display: flex; /* 或 display: inline-flex; */}
/* Flex 项目 */.flex-item { flex: 1; /* 简写属性 */}主要术语
- Flex Container(弹性容器) - 设置了
display: flex的父元素 - Flex Items(弹性项目) - 弹性容器的直接子元素
- Main Axis(主轴) - 弹性容器的主要方向
- Cross Axis(交叉轴) - 垂直于主轴的方向
🎪 Flex Container 属性
1. flex-direction - 主轴方向
.container { display: flex;
/* 主轴方向 */ flex-direction: row; /* 默认:水平从左到右 */ flex-direction: row-reverse; /* 水平从右到左 */ flex-direction: column; /* 垂直从上到下 */ flex-direction: column-reverse; /* 垂直从下到上 */}2. flex-wrap - 换行控制
.container { flex-wrap: nowrap; /* 默认:不换行 */ flex-wrap: wrap; /* 换行 */ flex-wrap: wrap-reverse; /* 反向换行 */
/* 简写 */ flex-flow: row wrap; /* flex-direction + flex-wrap */}3. justify-content - 主轴对齐
.container { justify-content: flex-start; /* 默认:起始对齐 */ justify-content: flex-end; /* 末尾对齐 */ justify-content: center; /* 居中对齐 */ justify-content: space-between; /* 两端对齐 */ justify-content: space-around; /* 环绕对齐 */ justify-content: space-evenly; /* 均匀对齐 */}4. align-items - 交叉轴对齐
.container { align-items: stretch; /* 默认:拉伸填充 */ align-items: flex-start; /* 起始对齐 */ align-items: flex-end; /* 末尾对齐 */ align-items: center; /* 居中对齐 */ align-items: baseline; /* 基线对齐 */}5. align-content - 多行对齐
.container { align-content: stretch; /* 默认:拉伸 */ align-content: flex-start; /* 起始对齐 */ align-content: flex-end; /* 末尾对齐 */ align-content: center; /* 居中对齐 */ align-content: space-between; /* 两端对齐 */ align-content: space-around; /* 环绕对齐 */}🎭 Flex Item 属性
1. flex-grow - 伸展比例
.item { flex-grow: 0; /* 默认:不伸展 */ flex-grow: 1; /* 可伸展,占据剩余空间 */ flex-grow: 2; /* 伸展比例为其他项目的2倍 */}2. flex-shrink - 收缩比例
.item { flex-shrink: 1; /* 默认:可收缩 */ flex-shrink: 0; /* 不收缩 */ flex-shrink: 2; /* 收缩比例为其他项目的2倍 */}3. flex-basis - 基础尺寸
.item { flex-basis: auto; /* 默认:基于内容 */ flex-basis: 200px; /* 固定基础宽度 */ flex-basis: 20%; /* 百分比基础宽度 */ flex-basis: 0; /* 不考虑内容尺寸 */}4. flex - 简写属性
/* 简写属性 *//* flex : flex-grow | flex-shrink | flex-basis; */.item { flex: 1; /* flex: 1 1 0% */ flex: 0 1 auto; /* 默认值 */ flex: 2; /* flex: 2 1 0% */ flex: 200px; /* flex: 1 1 200px */ flex: none; /* flex: 0 0 auto */}5. align-self - 单独对齐
.item { align-self: auto; /* 默认:继承容器设置 */ align-self: flex-start; /* 起始对齐 */ align-self: flex-end; /* 末尾对齐 */ align-self: center; /* 居中对齐 */ align-self: stretch; /* 拉伸对齐 */ align-self: baseline; /* 基线对齐 */}🌟 Flexbox 实用案例
1. 水平垂直居中
<div class="center-container"> <div class="center-item">居中内容</div></div>.center-container { display: flex; justify-content: center; align-items: center; height: 100vh;}
.center-item { padding: 20px; background: #3498db; color: white; border-radius: 8px;}2. 导航栏布局
<nav class="navbar"> <div class="logo">Logo</div> <ul class="nav-menu"> <li><a href="#">首页</a></li> <li><a href="#">产品</a></li> <li><a href="#">关于</a></li> </ul> <div class="nav-actions"> <button>登录</button> </div></nav>.navbar { display: flex; justify-content: space-between; align-items: center; padding: 0 20px; background: #fff; box-shadow: 0 2px 4px rgba(0,0,0,0.1);}
.nav-menu { display: flex; list-style: none; margin: 0; padding: 0; gap: 20px;}
.nav-menu li a { text-decoration: none; color: #333; font-weight: 500;}3. 卡片布局
<div class="card-container"> <div class="card">卡片1</div> <div class="card">卡片2</div> <div class="card">卡片3</div></div>.card-container { display: flex; gap: 20px; flex-wrap: wrap;}
.card { flex: 1; min-width: 250px; padding: 20px; background: #f8f9fa; border-radius: 8px; border: 1px solid #e9ecef;}🏗️ CSS Grid 网格布局
什么是Grid?
CSS Grid是CSS3中最强大的布局系统,它是二维布局方法,能同时处理行和列,使复杂布局变得简单直观。
🎯 Grid 核心概念
/* Grid 容器 */.grid-container { display: grid; /* 或 display: inline-grid; */}
/* Grid 项目 */.grid-item { grid-column: 1 / 3; /* 跨列 */ grid-row: 1 / 2; /* 跨行 */}主要术语
- Grid Container(网格容器) - 设置了
display: grid的父元素 - Grid Items(网格项目) - 网格容器的直接子元素
- Grid Line(网格线) - 组成网格结构的分界线
- Grid Track(网格轨道) - 两条相邻网格线之间的空间
- Grid Cell(网格单元) - 四条网格线围成的区域
- Grid Area(网格区域) - 四条网格线围成的矩形区域
🎪 Grid Container 属性
1. grid-template-columns/rows - 定义网格
.container { display: grid;
/* 固定尺寸 */ grid-template-columns: 200px 200px 200px; grid-template-rows: 100px 100px;
/* fr单位(分数单位) */ grid-template-columns: 1fr 2fr 1fr;
/* repeat()函数 */ grid-template-columns: repeat(3, 1fr); grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
/* 混合单位 */ grid-template-columns: 200px 1fr 100px;
/* 命名网格线 */ grid-template-columns: [start] 250px [content-start] 1fr [content-end] 250px [end];}2. grid-template-areas - 网格区域
.container { display: grid; grid-template-columns: 1fr 3fr 1fr; grid-template-rows: 60px 1fr 60px; 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; }3. gap - 网格间距
.container { display: grid;
/* 统一间距 */ gap: 20px;
/* 分别设置行列间距 */ row-gap: 20px; column-gap: 30px;
/* 简写 */ gap: 20px 30px; /* row-gap column-gap */}4. justify-items/align-items - 项目对齐
.container { /* 水平对齐 */ 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: center; /* align-items justify-items */}5. justify-content/align-content - 容器对齐
.container { /* 水平分布 */ justify-content: start; justify-content: end; justify-content: center; justify-content: space-between; justify-content: space-around; justify-content: space-evenly;
/* 垂直分布 */ align-content: start; align-content: end; align-content: center; align-content: space-between; align-content: space-around; align-content: space-evenly;
/* 简写 */ place-content: center; /* align-content justify-content */}🎭 Grid Item 属性
1. grid-column/row - 位置定位
.item { /* 列定位 */ grid-column-start: 1; grid-column-end: 3; grid-column: 1 / 3; /* 简写 */ grid-column: 1 / span 2; /* 跨越2列 */
/* 行定位 */ grid-row-start: 1; grid-row-end: 2; grid-row: 1 / 2; /* 简写 */ grid-row: 1 / span 1; /* 跨越1行 */
/* 使用命名网格线 */ grid-column: content-start / content-end;}2. grid-area - 区域定位
.item { /* 使用命名区域 */ grid-area: header;
/* 使用数值 */ grid-area: 1 / 1 / 2 / 4; /* row-start / col-start / row-end / col-end */}3. justify-self/align-self - 单独对齐
.item { 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; /* align-self justify-self */}🌟 Grid 实用案例
1. 响应式网页布局
<div class="page-layout"> <header class="header">Header</header> <nav class="sidebar">Sidebar</nav> <main class="main">Main Content</main> <aside class="aside">Aside</aside> <footer class="footer">Footer</footer></div>.page-layout { display: grid; min-height: 100vh; grid-template-columns: 250px 1fr 200px; grid-template-rows: 60px 1fr 40px; grid-template-areas: "header header header" "sidebar main aside" "footer footer footer"; gap: 10px;}
.header { grid-area: header; background: #3498db; }.sidebar { grid-area: sidebar; background: #95a5a6; }.main { grid-area: main; background: #ecf0f1; }.aside { grid-area: aside; background: #95a5a6; }.footer { grid-area: footer; background: #34495e; }
/* 响应式适配 */@media (max-width: 768px) { .page-layout { grid-template-columns: 1fr; grid-template-areas: "header" "main" "sidebar" "aside" "footer"; }}2. 瀑布流相册
<div class="gallery"> <div class="item item-tall">图片1</div> <div class="item">图片2</div> <div class="item item-wide">图片3</div> <div class="item">图片4</div> <div class="item item-big">图片5</div> <div class="item">图片6</div></div>.gallery { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); grid-auto-rows: 200px; gap: 15px; padding: 20px;}
.item { background: #f0f0f0; border-radius: 8px; display: flex; align-items: center; justify-content: center; font-weight: bold; color: #333;}
.item-tall { grid-row: span 2; }.item-wide { grid-column: span 2; }.item-big { grid-row: span 2; grid-column: span 2;}3. 卡片网格布局
<div class="card-grid"> <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></div> .card-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 20px; padding: 20px; }
.card { background: white; padding: 24px; border-radius: 12px; box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); transition: transform 0.2s ease, box-shadow 0.2s ease; }
.card:hover { transform: translateY(-2px); box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15); }⚖️ Flexbox vs Grid 对比
🎯 使用场景选择
| 特性 | Flexbox | Grid |
|---|---|---|
| 维度 | 一维布局(行或列) | 二维布局(行和列) |
| 主要用途 | 组件内部布局、对齐 | 页面整体布局、复杂网格 |
| 内容驱动 | 从内容出发的布局 | 从布局出发的设计 |
| 浏览器支持 | 优秀 | 现代浏览器支持好 |
| 学习曲线 | 相对简单 | 功能更强大,稍复杂 |
📋 选择建议
使用Flexbox的场景
- 🔧 导航栏布局
- 📱 移动端适配
- 🎯 居中对齐
- 📊 表单组件
- 🎨 卡片内部布局
- 📐 等高布局
使用Grid的场景
- 🏗️ 整体页面布局
- 📱 复杂响应式设计
- 🖼️ 图片相册/瀑布流
- 📊 数据表格
- 🎨 杂志式布局
- 📐 不规则网格
🎨 高级技巧与最佳实践
1. 响应式设计模式
/* 移动优先的响应式Grid */.responsive-grid { display: grid; gap: 1rem;
/* 移动端:单列 */ grid-template-columns: 1fr;
/* 平板:两列 */ @media (min-width: 768px) { grid-template-columns: repeat(2, 1fr); }
/* 桌面:三列 */ @media (min-width: 1024px) { grid-template-columns: repeat(3, 1fr); }}2. 自适应网格
/* 自动填充网格 */.auto-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 1rem;}
/* 自动创建网格 */.auto-create-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); grid-auto-rows: 200px; gap: 1rem;}3. 嵌套布局
.nested-layout { display: grid; grid-template-columns: 1fr 3fr; gap: 2rem;}
.sidebar { display: flex; flex-direction: column; gap: 1rem;}
.main-content { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 1.5rem;}4. 性能优化
/* 使用transform代替改变grid属性 */.item { transition: transform 0.2s ease;}
.item:hover { transform: scale(1.05); /* 而不是改变grid-column等属性 */}
/* 合理使用will-change */.animated-grid-item { will-change: transform;}🔧 调试技巧
1. 开发工具
/* 临时显示网格线 */.debug-grid { background-image: linear-gradient(rgba(255,0,0,0.3) 1px, transparent 1px), linear-gradient(90deg, rgba(255,0,0,0.3) 1px, transparent 1px); background-size: 20px 20px;}
/* Flexbox调试 */.debug-flex { border: 2px solid red;}
.debug-flex > * { border: 1px solid blue;}2. CSS自定义属性
:root { --gap: 1rem; --columns: 3; --min-item-width: 250px;}
.configurable-grid { display: grid; grid-template-columns: repeat(var(--columns), 1fr); gap: var(--gap);}
/* 动态调整 */@media (max-width: 768px) { :root { --columns: 1; --gap: 0.5rem; }}🌟 总结
Flexbox和Grid是现代CSS布局的两大核心技术:
🎯 关键要点
- Flexbox - 适合一维布局,内容驱动,简单灵活
- Grid - 适合二维布局,布局驱动,功能强大
- 组合使用 - 在同一项目中结合使用,发挥各自优势
- 渐进增强 - 提供fallback方案,确保兼容性
- 性能考虑 - 合理使用,避免不必要的重排重绘
📈 学习建议
- 从基础开始 - 理解核心概念和术语
- 动手实践 - 通过实际项目加深理解
- 使用工具 - 利用浏览器开发者工具调试
- 关注兼容性 - 了解浏览器支持情况
- 持续学习 - 跟进新特性和最佳实践
掌握Flexbox和Grid布局,你将能够创建出美观、灵活且响应式的现代Web界面!
💡 提示: 在实际开发中,建议优先考虑Grid用于整体布局,Flexbox用于组件内部布局,两者结合使用效果最佳。
CSS Flexbox & Grid 布局完全指南
https://fuwari.vercel.app/posts/flexbox-grid-layout/