一、Flex 布局详解
- Flex 容器属性
.flex-container {
display: flex; /* 启用 flex 布局 */
flex-direction: row; /* 主轴方向:row(默认) | row-reverse | column | column-reverse */
flex-wrap: wrap; /* 换行:nowrap(默认) | wrap | wrap-reverse */
justify-content: center;/* 主轴对齐:flex-start | flex-end | center | space-between | space-around */
align-items: center; /* 交叉轴对齐:flex-start | flex-end | center | baseline | stretch */
gap: 20px; /* 项目间距 */
}
- Flex 项目属性
.flex-item {
flex: 1 1 auto; /* flex-grow | flex-shrink | flex-basis */
order: 0; /* 项目排序 */
align-self: center; /* 单个项目对齐方式 */
}
- Flex 布局特点:
- 一维布局,只能处理行或列
- 适合处理线性布局
- 项目可以自动伸缩
- 适合处理未知数量的项目
二、Grid 布局详解
- Grid 容器属性
.grid-container {
display: grid;
grid-template-columns: repeat(3, 1fr); /* 定义列 */
grid-template-rows: 100px 200px; /* 定义行 */
gap: 20px; /* 网格间距 */
grid-auto-rows: minmax(100px, auto); /* 自动行高 */
justify-items: center; /* 单元格内容水平对齐 */
align-items: center; /* 单元格内容垂直对齐 */
}
- Grid 项目属性
.grid-item {
grid-column: 1 / 3; /* 跨越列 */
grid-row: 1 / 2; /* 跨越行 */
grid-area: header; /* 网格区域名称 */
justify-self: center; /* 单个项目水平对齐 */
align-self: center; /* 单个项目垂直对齐 */
}
- Grid 布局特点:
- 二维布局,可以同时控制行和列
- 适合处理复杂的网格布局
- 更精确的空间分配
- 适合处理固定数量的项目
三、两种布局的对比
-
维度差异:
- Flex:一维布局,只能处理行或列
- Grid:二维布局,可以同时处理行和列
-
适用场景:
-
Flex 适合:
- 导航栏
- 卡片列表
- 表单布局
- 需要项目自动伸缩的场景
-
Grid 适合:
- 整体页面布局
- 图片画廊
- 仪表盘
- 需要精确对齐的场景
-
-
性能考虑:
- Flex 布局计算相对简单,性能较好
- Grid 布局计算较复杂,但现代浏览器优化得很好
四、实际应用示例
- Flex 布局示例:
/* 响应式导航栏 */
.nav {
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
}
/* 卡片列表 */
.card-list {
display: flex;
flex-wrap: wrap;
gap: 20px;
}
.card {
flex: 1 1 300px;
max-width: 400px;
}
- Grid 布局示例:
/* 仪表盘布局 */
.dashboard {
display: grid;
grid-template-columns: 250px 1fr;
grid-template-rows: 60px 1fr;
grid-template-areas:
"sidebar header"
"sidebar main";
height: 100vh;
}
/* 图片画廊 */
.gallery {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 20px;
}
完整示例
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>仪表盘和图片画廊布局示例</title>
<style>
/* 基础样式重置 */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: Arial, sans-serif;
}
/* 仪表盘布局 */
.dashboard {
display: grid;
grid-template-columns: 250px 1fr;
grid-template-rows: 60px 1fr;
grid-template-areas:
"sidebar header"
"sidebar main";
height: 100vh;
}
.sidebar {
grid-area: sidebar;
background: #2c3e50;
color: white;
padding: 20px;
}
.header {
grid-area: header;
background: #34495e;
color: white;
padding: 0 20px;
display: flex;
align-items: center;
justify-content: space-between;
}
.main {
grid-area: main;
background: #ecf0f1;
padding: 20px;
overflow-y: auto;
}
/* 图片画廊布局 */
.gallery {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 20px;
padding: 20px;
}
.gallery-item {
background: #3498db;
color: white;
padding: 20px;
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
min-height: 200px;
transition: transform 0.3s ease;
}
.gallery-item:hover {
transform: scale(1.05);
}
/* 响应式设计 */
@media (max-width: 768px) {
.dashboard {
grid-template-columns: 1fr;
grid-template-rows: 60px auto 1fr;
grid-template-areas:
"header"
"sidebar"
"main";
}
.sidebar {
height: auto;
}
}
</style>
</head>
<body>
<!-- 仪表盘布局示例 -->
<div class="dashboard">
<div class="sidebar">
<h2>侧边栏</h2>
<ul>
<li>菜单项 1</li>
<li>菜单项 2</li>
<li>菜单项 3</li>
</ul>
</div>
<div class="header">
<h2>头部导航</h2>
<div>用户信息</div>
</div>
<div class="main">
<h2>主要内容区域</h2>
<p>这里是仪表盘的主要内容...</p>
<!-- 图片画廊布局示例 -->
<div class="gallery">
<div class="gallery-item">图片 1</div>
<div class="gallery-item">图片 2</div>
<div class="gallery-item">图片 3</div>
<div class="gallery-item">图片 4</div>
<div class="gallery-item">图片 5</div>
<div class="gallery-item">图片 6</div>
</div>
</div>
</div>
</body>
</html>
- 宫格示例:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Flex 和 Grid 宫格布局示例</title>
<style>
/* 基础样式 */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: Arial, sans-serif;
padding: 20px;
}
.container {
max-width: 1200px;
margin: 0 auto;
}
.layout-section {
margin-bottom: 40px;
padding: 20px;
background: #f5f5f5;
border-radius: 8px;
}
h2 {
margin-bottom: 20px;
color: #333;
}
/* Flex 宫格布局 */
.flex-grid {
display: flex;
flex-wrap: wrap;
gap: 20px;
}
.flex-grid .grid-item {
flex: 1 1 calc(33.333% - 20px);
min-width: 200px;
height: 200px;
background: #4CAF50;
color: white;
display: flex;
align-items: center;
justify-content: center;
font-size: 24px;
border-radius: 8px;
transition: all 0.3s ease;
}
.flex-grid .grid-item:hover {
transform: scale(1.05);
background: #45a049;
}
/* Grid 宫格布局 */
.grid-layout {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 20px;
}
.grid-layout .grid-item {
height: 200px;
background: #2196F3;
color: white;
display: flex;
align-items: center;
justify-content: center;
font-size: 24px;
border-radius: 8px;
transition: all 0.3s ease;
}
.grid-layout .grid-item:hover {
transform: scale(1.05);
background: #1976D2;
}
/* 响应式设计 */
@media (max-width: 768px) {
.flex-grid .grid-item {
flex: 1 1 calc(50% - 20px);
}
.grid-layout {
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
}
}
@media (max-width: 480px) {
.flex-grid .grid-item {
flex: 1 1 100%;
}
.grid-layout {
grid-template-columns: 1fr;
}
}
</style>
</head>
<body>
<div class="container">
<section class="layout-section">
<h2>Flex 宫格布局</h2>
<div class="flex-grid">
<div class="grid-item">1</div>
<div class="grid-item">2</div>
<div class="grid-item">3</div>
<div class="grid-item">4</div>
<div class="grid-item">5</div>
<div class="grid-item">6</div>
</div>
</section>
<section class="layout-section">
<h2>Grid 宫格布局</h2>
<div class="grid-layout">
<div class="grid-item">1</div>
<div class="grid-item">2</div>
<div class="grid-item">3</div>
<div class="grid-item">4</div>
<div class="grid-item">5</div>
<div class="grid-item">6</div>
</div>
</section>
</div>
</body>
</html>