下面我将为您提供从基础到高级的多面板网页布局源码,并附上详细的解释。

(图片来源网络,侵删)
传统 Flexbox 布局 (最常用、最推荐)
这是目前最主流、最灵活、兼容性也最好的方案,通过一个主容器包裹所有面板,并利用 flex 属性进行控制。
核心思路
- 外层容器: 设置
display: flex,作为所有面板的“行”或“列”。 - 面板元素: 作为
flex的子元素,它们会自动排列。 - 控制面板大小: 使用
flex-grow(弹性增长) 或flex-basis(基础尺寸) 来定义每个面板的占比或固定宽度/高度。 - 处理滚动: 使用
overflow: auto让面板内容过多时出现滚动条,而不是撑破整个布局。
示例1:经典三栏布局 (侧边栏 + 主内容区)
这是最经典的多面板布局,常见于管理后台、社交媒体等。
源码 (HTML + CSS)
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">Flexbox 三栏布局</title>
<style>
/* 重置默认样式 */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html, body {
height: 100%;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
}
/* 1. 外层容器:设置为flex布局,方向为水平(行) */
.app-container {
display: flex;
height: 100vh; /* 视口高度 */
}
/* 2. 左侧边栏 */
.sidebar {
/* 宽度固定为250像素 */
width: 250px;
background-color: #2c3e50;
color: white;
padding: 20px;
}
/* 3. 主内容区 */
.main-content {
/*
* flex-grow: 1;
* 这是最关键的一步!它告诉主内容区:
* “占据所有剩余的可用空间”
*/
flex-grow: 1;
padding: 20px;
background-color: #ecf0f1;
overflow-y: auto; /* 内容超出时垂直滚动 */
}
/* 4. 右侧边栏 (可选) */
.right-sidebar {
width: 300px;
background-color: #34495e;
color: white;
padding: 20px;
}
/* 添加一些基本样式让内容更美观 */
h2, h3 {
margin-bottom: 15px;
}
p {
line-height: 1.6;
margin-bottom: 10px;
}
</style>
</head>
<body>
<div class="app-container">
<!-- 左侧边栏 -->
<aside class="sidebar">
<h3>导航菜单</h3>
<ul>
<li><a href="#">首页</a></li>
<li><a href="#">仪表盘</a></li>
<li><a href="#">用户管理</a></li>
<li><a href="#">设置</a></li>
</ul>
</aside>
<!-- 主内容区 -->
<main class="main-content">
<h2>主内容区</h2>
<p>这里是页面的主要内容,它通过 `flex-grow: 1` 自动填充了左右侧边栏之外的所有空间。</p>
<!-- 为了演示滚动效果,添加很多内容 -->
<div style="height: 1500px; background: linear-gradient(to bottom, #ecf0f1, #bdc3c7);">
<p>向下滚动查看...</p>
</div>
</main>
<!-- 右侧边栏 -->
<aside class="right-sidebar">
<h3>信息面板</h3>
<p>这里是一些辅助信息,比如通知、状态等。</p>
</aside>
</div>
</body>
</html>
代码解析:

(图片来源网络,侵删)
.app-container:display: flex创建了弹性盒子。.sidebar:width: 250px给予一个固定宽度。.main-content**:flex-grow: 1` 是核心,它“吃掉”了所有剩余空间,实现了自适应。.right-sidebar: 同样是固定宽度。overflow-y: auto: 确保主内容区内容过多时,只在该面板内部滚动,不影响其他面板。
示例2:可拖拽调整大小的面板
这是对基础布局的增强,让用户体验更好。注意:这需要用到 JavaScript。
源码 (HTML + CSS + JavaScript)
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">可拖拽调整大小的面板</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
html, body { height: 100%; font-family: sans-serif; }
body { background-color: #f0f2f5; }
.container {
display: flex;
height: 100vh;
}
.panel {
background: white;
box-shadow: 0 0 10px rgba(0,0,0,0.1);
overflow: auto;
padding: 20px;
}
#panel-left {
width: 200px;
}
#panel-right {
flex-grow: 1;
}
/* 拖拽手柄的样式 */
.resizer {
width: 5px;
cursor: col-resize; /* 鼠标样式 */
background: transparent;
position: relative;
}
.resizer:hover {
background-color: #3498db;
}
/* 为了更好的视觉效果,可以在拖拽手柄上加一条线 */
.resizer::after {
content: '';
position: absolute;
top: 0;
bottom: 0;
left: 50%;
width: 1px;
background-color: #ccc;
transform: translateX(-50%);
}
</style>
</head>
<body>
<div class="container">
<div id="panel-left" class="panel">
<h3>左侧面板</h3>
<p>拖拽右边的边缘可以调整大小。</p>
</div>
<!-- 拖拽手柄 -->
<div class="resizer" id="resizer"></div>
<div id="panel-right" class="panel">
<h3>右侧面板</h3>
<p>这里是右侧内容,会自适应剩余空间。</p>
</div>
</div>
<script>
const resizer = document.getElementById('resizer');
const leftPanel = document.getElementById('panel-left');
const rightPanel = document.getElementById('panel-right');
let isResizing = false;
// 鼠标按下事件
resizer.addEventListener('mousedown', (e) => {
isResizing = true;
document.body.style.cursor = 'col-resize'; // 改变全局鼠标样式
// 防止文本选中
document.body.style.userSelect = 'none';
});
// 鼠标移动事件
document.addEventListener('mousemove', (e) => {
if (!isResizing) return;
// 计算新的左侧面板宽度
const newWidth = e.clientX;
// 设置最小和最大宽度限制
if (newWidth > 100 && newWidth < window.innerWidth - 200) {
leftPanel.style.width = newWidth + 'px';
// 右侧面板不需要手动设置宽度,因为flex-grow会自动填充
}
});
// 鼠标松开事件
document.addEventListener('mouseup', () => {
isResizing = false;
document.body.style.cursor = 'default';
document.body.style.userSelect = '';
});
</script>
</body>
</html>
代码解析:
- HTML: 在两个面板之间增加了一个
.resizer元素作为拖拽手柄。 - CSS: 为
.resizer设置了特殊的鼠标样式cursor: col-resize,让用户知道这里可以拖拽。 - JavaScript:
- 监听
mousedown事件,当用户按下拖拽手柄时,设置isResizing标志为true。 - 监听
mousemove事件,当isResizing为true时,根据鼠标的 X 坐标动态改变左侧面板的width。 - 监听
mouseup事件,当用户松开鼠标时,取消拖拽状态。
- 监听
CSS Grid 布局 (更强大、更现代)
CSS Grid 是一个二维布局系统,非常适合创建复杂的网格布局,对于多面板布局,它同样非常强大和简洁。

(图片来源网络,侵删)
核心思路
- 外层容器: 设置
display: grid。 - 定义网格: 使用
grid-template-columns(定义列) 和grid-template-rows(定义行) 来创建网格轨道。 - 放置面板: 使用
grid-column和grid-row属性将面板放置到网格的特定位置。
示例:使用 Grid 实现三栏布局
源码 (HTML + CSS)
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">CSS Grid 布局</title>
<style>
/* 重置样式 */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html, body {
height: 100%;
font-family: sans-serif;
}
/* 1. 外层容器:设置为grid布局 */
.grid-container {
display: grid;
/*
* 2. 定义列:
* 250px 1fr 300px
* 意思是:第一列固定250px,第二列占据剩余空间(1fr = 1份可用空间),第三列固定300px
*/
grid-template-columns: 250px 1fr 300px;
height: 100vh;
}
/* 3. 面板样式 */
.grid-item {
padding: 20px;
overflow-y: auto;
}
.sidebar-left {
background-color: #2c3e50;
color: white;
}
.main-content {
background-color: #ecf0f1;
}
.sidebar-right {
background-color: #34495e;
color: white;
}
</style>
</head>
<body>
<div class="grid-container">
<!-- 面板会按照HTML中的顺序自动填充网格 -->
<div class="grid-item sidebar-left">
<h3>左侧边栏 (Grid)</h3>
<p>通过 `grid-template-columns` 定义列宽。</p>
</div>
<div class="grid-item main-content">
<h2>主内容区 (Grid)</h2>
<p>这里的 `1fr` 表示它会占据所有剩余的空间,非常直观。</p>
<div style="height: 1500px; background: linear-gradient(to bottom, #ecf0f1, #bdc3c7);">
<p>向下滚动...</p>
</div>
</div>
<div class="grid-item sidebar-right">
<h3>右侧边栏 (Grid)</h3>
<p>布局定义非常清晰。</p>
</div>
</div>
</body>
</html>
代码解析:
.grid-container**:display: grid` 启用了 Grid 布局。grid-template-columns: 250px 1fr 300px;: 这是 Grid 布局的精髓,它直接定义了三列的宽度:固定、弹性、固定。1fr(fraction unit) 是一个弹性单位,代表“可用空间的一份”,这使得中间面板自动填充剩余空间。.grid-item: 所有直接子元素会自动按照定义的网格顺序排列,无需额外的定位属性。
总结与对比
| 特性 | Flexbox | CSS Grid |
|---|---|---|
| 维度 | 一维 (行或列) | 二维 (行和列同时) |
| 适用场景 | 组件内部布局、导航栏、单行/单列元素对齐 | 页面整体布局、复杂网格系统、卡片布局 |
| 核心概念 | 容器(flex), 子元素(flex-grow, flex-shrink) |
容器(grid-template-areas, grid-template-columns), 子元素(grid-column, grid-row) |
| 代码直观性 | 对于简单多列,需要flex-grow来填充空间。 |
对于多列布局,grid-template-columns: 1fr 非常直观。 |
| 拖拽调整 | 需要JS动态修改width或flex-basis。 |
同样需要JS,但可以基于网格线进行更复杂的定位。 |
如何选择?
- 绝大多数情况下,使用 Flexbox 足够且更灵活,它非常适合创建一个主容器和几个子面板的布局。
- 当你的布局非常复杂,涉及多个维度(一个顶部导航栏,一个左侧边栏,一个主要内容区,还有一个页脚),并且希望它们之间的关系非常稳固时,CSS Grid 是更好的选择,你可以用
grid-template-areas来命名区域,代码可读性极高。
对于初学者和大多数项目,强烈建议从 Flexbox 开始,因为它更简单、更普及,掌握了 Flexbox 后,再学习 CSS Grid 来处理更高级的布局需求。
