
本文介绍如何利用 css flexbox 布局,让页面中带固定头部和页脚的主体内容区域自动占据剩余视口高度,并支持平滑垂直滚动,确保整体布局严格贴合 viewport。
本文介绍如何利用 css flexbox 布局,让页面中带固定头部和页脚的主体内容区域自动占据剩余视口高度,并支持平滑垂直滚动,确保整体布局严格贴合 viewport。
在构建具有固定 Header 和 Footer 的单页应用或数据表格界面时,一个常见需求是:Body 区域应动态填充视口(viewport)中 Header 与 Footer 之间的全部可用高度,并在内容溢出时启用滚动,而非撑开页面或出现空白间隙。纯 CSS 解决方案中,Flexbox 是最简洁、可靠且语义清晰的方法。
核心实现原理
关键在于将容器设为 display: flex + flex-direction: column,并利用 flex: 1 让 .body 占据剩余空间:
本书是全面讲述PHP与MySQL的经典之作,书中不但全面介绍了两种技术的核心特性,还讲解了如何高效地结合这两种技术构建健壮的数据驱动的应用程序。本书涵盖了两种技术新版本中出现的最新特性,书中大量实际的示例和深入的分析均来自于作者在这方面多年的专业经验,可用于解决开发者在实际中所面临的各种挑战。 本书内容全面深入,适合各层次PHP和MySQL开发人员阅读,既是优秀的学习教程,也可用作参考手册。
- .container 设置 height: 100vh 确保其高度等于视口;
- .header 和 .footer 使用固定高度(也可替换为 flex: 0 0 auto 配合内容自适应);
- .body 设置 flex: 1(等价于 flex-grow: 1; flex-shrink: 1; flex-basis: 0),使其无条件拉伸以填满剩余空间;
- 同时添加 overflow-y: auto(推荐替代 scroll,避免始终显示滚动条),实现按需滚动。
完整可运行代码示例
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>Viewport-Fit Scrollable Body</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
.container {
display: flex;
flex-direction: column;
height: 100vh; /* 全屏高度 */
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
}
.header {
height: 100px;
background-color: #ffeb3b;
display: flex;
align-items: center;
justify-content: center;
font-weight: bold;
border-bottom: 1px solid #ddd;
}
.body {
flex: 1; /* 关键:弹性占据剩余空间 */
overflow-y: auto; /* 内容超长时才显示滚动条 */
padding: 12px;
background-color: #f9f9f9;
}
.footer {
height: 100px;
background-color: #ff9800;
display: flex;
align-items: center;
justify-content: center;
font-weight: bold;
border-top: 1px solid #ddd;
}
.row {
background-color: #f44336;
color: white;
padding: 12px 16px;
margin: 0 0 8px 0;
border-radius: 4px;
font-size: 14px;
box-shadow: 0 1px 2px rgba(0,0,0,0.05);
}
</style>
</head>
<body>
<div class="container">
<div class="header">Header — 固定高度</div>
<div class="body" id="body"></div>
<div class="footer">Footer — 固定高度</div>
</div>
<script>
const body = document.getElementById('body');
const createFakeData = (id) => {
const row = document.createElement('div');
row.textContent = `Row ${id + 1}`;
row.classList.add('row');
body.appendChild(row);
};
// 生成 120 行测试数据,确保触发滚动
for (let i = 0; i < 120; i++) {
createFakeData(i);
}
</script>
</body>
</html>注意事项与最佳实践
- ✅ 避免 height: 100% 陷阱:在 Flex 容器内,对 .body 设置 height: 100% 无效且易引发计算错误;flex: 1 是标准解法。
- ✅ 响应式兼容性:Flexbox 在所有现代浏览器(包括 Safari 10+、Chrome 29+、Firefox 28+)中稳定支持;如需兼容 IE10/11,可添加 -ms-flex: 1 前缀(但不推荐为新项目增加兼容负担)。
- ⚠️ 内容重绘优化:当 .body 中存在大量 DOM 节点(如数百行列表)时,建议结合虚拟滚动(如 react-window 或 vue-virtual-scroller)提升性能,而非依赖原生滚动。
- ? 无障碍增强:为 .body 添加 role="region" 和 aria-label="main content" 可提升屏幕阅读器体验。
通过上述方式,你无需 JavaScript 动态计算高度,即可实现真正“贴合视口、智能伸缩、滚动可控”的三段式布局——这是现代 Web 布局中 Flexbox 的典型高效应用场景。









