CSS实现元素撑满剩余空间的5种方法 🎨
在日常开发中,我们经常需要让某个元素占据容器的剩余空间。这是一个常见的布局需求,比如侧边栏+主内容区、头部+内容区+底部等布局。本文将介绍5种不同的方法来实现这个需求,并分析各种方法的优缺点。
目录
- [CSS实现元素撑满剩余空间的5种方法 🎨](#CSS实现元素撑满剩余空间的5种方法 🎨 "#css%E5%AE%9E%E7%8E%B0%E5%85%83%E7%B4%A0%E6%92%91%E6%BB%A1%E5%89%A9%E4%BD%99%E7%A9%BA%E9%97%B4%E7%9A%845%E7%A7%8D%E6%96%B9%E6%B3%95-")
Flexbox 方法
📁 详见
./01-flexbox/index.html
Flexbox 是最现代和推荐的方式。通过设置 flex-grow: 1
,元素会自动扩展占据剩余空间。对于垂直布局,配合 height: 0
使用效果更好。
聊天应用布局:

html
<div class="chat-container">
<header class="chat-header">
<img src="avatar.jpg" alt="用户头像">
<h2>聊天室</h2>
</header>
<main class="chat-messages">
<div class="message received">收到的消息</div>
<div class="message sent">发送的消息</div>
</main>
<footer class="chat-input">
<input type="text" placeholder="输入消息...">
<button>发送</button>
</footer>
</div>
<style>
.chat-container {
display: flex;
flex-direction: column;
height: 100vh;
}
.chat-header {
height: 60px;
background: #075e54;
}
.chat-messages {
flex: 1;
height: 0; /* 关键属性 */
overflow-y: auto;
}
.chat-input {
height: 60px;
background: #f0f0f0;
}
</style>
实现思路解析:
-
垂直布局三要素:
display: flex
+flex-direction: column
创建垂直伸缩布局flex: 1
让中间区域自动占据剩余空间height: 0
防止内容撑开,确保严格遵守 flex 规则
-
滚动区域处理:
- 设置
overflow-y: auto
使内容过多时可滚动 - 不设置 height: 0 的话,内容会撑开容器,破坏布局
- 设置
-
布局结构: 容器 (100vh) ├── 头部 (固定60px) ├── 内容 (flex: 1 + height: 0) └── 底部 (固定60px)
-
性能优化:
- 使用 transform 代替定位提升性能
- 避免频繁改变高度触发重排
其他适用场景:
-
后台管理系统布局
- 顶部固定导航栏
- 左侧固定菜单栏
- 右侧自适应内容区
-
移动端应用布局
- 固定顶部header
- 可滚动的内容区域
- 固定底部导航栏
-
文档编辑器
- 工具栏
- 自适应的编辑区域
- 状态栏
优点:
- 灵活且直观
- 支持动态内容
- 响应式表现好
- 一维布局的最佳选择
缺点:
- IE11及以下版本支持不完善
- 不适合复杂的二维布局
Grid 方法
📁 详见
./02-grid/index.html
Grid 布局通过 fr
单位或 auto
来分配剩余空间,特别适合复杂的二维布局。
仪表盘布局:

html
<div class="dashboard">
<!-- 状态卡片 -->
<div class="widget status-card">
<h3>总访问量</h3>
<div class="number">1,234,567</div>
</div>
<div class="widget status-card">
<h3>活跃用户</h3>
<div class="number">45,678</div>
</div>
<!-- 大尺寸部件 -->
<div class="widget large-widget">
<h3>访问趋势图</h3>
</div>
</div>
<style>
.dashboard {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: 100px 200px;
gap: 20px;
}
.widget {
background: white;
border-radius: 10px;
padding: 20px;
}
.large-widget {
grid-column: span 2;
}
/* 响应式布局 */
@media (max-width: 768px) {
.dashboard {
grid-template-columns: repeat(2, 1fr);
}
}
</style>
实现思路解析:
-
网格系统设计:
- 使用
repeat(4, 1fr)
创建均等的四列布局 grid-template-rows
定义不同的行高gap: 20px
统一设置网格间距
- 使用
-
响应式布局策略: 桌面端:4列 平板端:2列 (media query) 手机端:1列
-
组件尺寸控制:
- 使用
grid-column: span 2
让组件跨越两列 - 通过
grid-area
可以实现更复杂的位置控制
- 使用
-
自适应处理:
- fr 单位自动分配剩余空间
- 结合 minmax() 设置最小尺寸防止挤压
适用场景:
-
图片画廊/瀑布流
- 自适应的网格布局
- 不规则的图片排列
- 响应式的列数调整
-
网站首页布局
- 多区块的内容排列
- 广告位的灵活布局
- 响应式的栅格系统
-
在线商城商品展示
- 商品网格
- 不同尺寸的促销位
- 自适应的分类展示
优点:
- 二维布局更灵活
- 代码简洁明了
- 响应式设计更简单
- 支持复杂的对齐和间距控制
缺点:
- 老浏览器兼容性问题
- 对于简单的一维布局可能显得过重
- 学习曲线相对较陡
绝对定位方法
📁 详见
./03-absolute/index.html
使用绝对定位和固定值来计算剩余空间,通过设置 top
、right
、bottom
、left
值来精确控制位置。
视频播放器控制层:

html
<div class="video-container">
<video poster="thumbnail.jpg">
<source src="video.mp4" type="video/mp4">
</video>
<div class="controls-overlay">
<div class="top-controls">
<h2>视频标题</h2>
<button class="control-button">⚙️</button>
</div>
<div class="progress-bar">
<div class="progress"></div>
</div>
<div class="bottom-controls">
<button class="control-button">▶️</button>
<div class="time-display">02:30 / 10:00</div>
<button class="control-button">🔊</button>
</div>
</div>
</div>
<style>
.video-container {
position: relative;
width: 100%;
height: 100vh;
}
.controls-overlay {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
background: linear-gradient(
to bottom,
rgba(0,0,0,0.7) 0%,
rgba(0,0,0,0) 20%,
rgba(0,0,0,0) 80%,
rgba(0,0,0,0.7) 100%
);
}
.bottom-controls {
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 60px;
padding: 15px;
}
</style>
实现思路解析:
-
层级控制: 视频容器 (relative) ├── 视频元素 └── 控制层 (absolute) ├── 顶部控件 ├── 进度条 └── 底部控件
-
渐变遮罩设计:
- 使用 linear-gradient 创建渐变背景
- 顶部和底部渐变营造层次感
- 中间区域透明保持视频可见
-
交互优化:
- hover 时显示控制层
- 使用 transition 实现平滑过渡
- 控件布局考虑触控友好性
-
响应式考虑:
- 控件尺寸使用相对单位
- 移动端适配大小按钮
- 保持关键控件始终可见
适用场景:
-
固定元素覆盖
- 全屏遮罩层
- 模态框背景
- 全屏加载指示器
-
广告位布局
- 固定位置的广告条
- 悬浮广告
- 角标定位
-
特殊交互界面
- 拖拽区域
- 自定义滚动条
- 图片裁剪区域
优点:
- 浏览器兼容性好
- 性能较好
- 精确控制位置
- 层级控制容易
缺点:
- 不够灵活
- 需要手动计算位置
- 脱离文档流可能影响其他元素
- 响应式布局较难维护
calc() 方法
📁 详见
./04-calc/index.html
使用 CSS 的 calc() 函数动态计算尺寸,可以混合使用不同单位进行计算。
多栏布局:

html
<div class="article-container">
<h2>等宽三栏布局</h2>
<div class="three-columns">
<div class="column">第一栏</div>
<div class="column">第二栏</div>
<div class="column">第三栏</div>
</div>
<h2>混合宽度布局</h2>
<div class="mixed-columns">
<aside class="sidebar">侧边栏</aside>
<main class="main-content">主内容区</main>
</div>
</div>
<style>
/* 三栏等宽布局 */
.three-columns {
display: flex;
gap: 30px;
}
.three-columns .column {
width: calc(100% / 3 - 20px);
/* 减去间距的权重 */
}
/* 混合宽度布局 */
.mixed-columns {
display: flex;
gap: 30px;
}
.mixed-columns .sidebar {
width: 300px;
}
.mixed-columns .main-content {
width: calc(100% - 330px);
/* 减去侧边栏宽度和间距 */
}
@media (max-width: 768px) {
.three-columns,
.mixed-columns {
flex-direction: column;
}
.three-columns .column,
.mixed-columns .sidebar,
.mixed-columns .main-content {
width: 100%;
}
}
</style>
实现思路解析:
-
宽度计算原理:
css/* 三栏等宽布局 */ width: calc(100% / 3 - 20px) /* 总宽度均分减去间距 */ /* 混合布局 */ width: calc(100% - 330px) /* 总宽度减去固定宽度和间距 */
-
间距处理策略:
- 使用 gap 属性设置列间距
- 在计算时减去对应的间距值
- 响应式布局时重置间距
-
精确计算:
- 考虑边框和内边距的影响
- 使用 box-sizing: border-box
- 预留边距防止小数点误差
-
响应式设计:
- 断点处切换为垂直布局
- 重置为 100% 宽度
- 保持间距的一致性
适用场景:
-
自定义滚动容器
- 减去固定高度的滚动区域
- 考虑padding和边框的精确计算
- 动态高度的内容区域
-
表单布局
- 标签和输入框组合
- 多列表单布局
- 自适应的输入区域
-
媒体播放器
- 进度条计算
- 控制栏布局
- 缩略图网格
优点:
- 精确控制
- 支持动态计算
- 可混合不同单位
- 适合精确的数学计算
缺点:
- 需要明确知道其他元素的尺寸
- IE9及以下不支持
- 计算规则可能复杂
- 性能略低于固定值
table 布局方法
📁 详见
./05-table/index.html
使用 CSS table 布局属性来分配空间,特别适合需要等高列或自动空间分配的场景。
数据表格:

html
<div class="table-container">
<div class="data-table">
<div class="table-header">
<div class="table-row">
<div class="table-cell">ID</div>
<div class="table-cell">项目名称</div>
<div class="table-cell">进度</div>
<div class="table-cell">状态</div>
</div>
</div>
<div class="table-body">
<div class="table-row">
<div class="table-cell">001</div>
<div class="table-cell">项目重构</div>
<div class="table-cell">
<div class="progress-bar">
<div class="progress" style="width: 75%"></div>
</div>
</div>
<div class="table-cell">
<span class="status">进行中</span>
</div>
</div>
</div>
</div>
</div>
<style>
.data-table {
display: table;
width: 100%;
border-collapse: collapse;
}
.table-header {
display: table-header-group;
background: #f8f9fa;
}
.table-body {
display: table-row-group;
}
.table-row {
display: table-row;
}
.table-cell {
display: table-cell;
padding: 15px;
border-bottom: 1px solid #dee2e6;
vertical-align: middle;
}
/* 列宽设置 */
.table-cell:nth-child(1) { width: 80px; }
.table-cell:nth-child(2) { width: 200px; }
.table-cell:nth-child(3) { width: 200px; }
.table-cell:nth-child(4) { width: 120px; }
</style>
实现思路解析:
-
表格结构设计: table-container └── data-table (display: table) ├── table-header (table-header-group) │ └── table-row │ └── table-cell × N └── table-body (table-row-group) └── table-row × N └── table-cell × N
-
列宽控制策略:
- 固定列使用具体像素值
- 自适应列不设宽度自动分配
- 使用 min-width 防止内容挤压
-
样式优化:
- 使用 border-collapse 处理边框
- 通过 vertical-align 控制对齐
- nth-child 实现斑马纹效果
-
特点利用:
- 自动等高列
- 自动垂直对齐
- 天然的响应式行为
适用场景:
- 数据密集型界面
- 数据表格
- 列表展示
- 价格对比表
最佳实践建议 💡
-
优先使用 Flexbox
- 对于大多数现代网站,Flexbox 是最佳选择
- 代码简单,维护方便
-
需要考虑兼容性时
- 如果需要支持旧版浏览器,可以考虑 calc() 或绝对定位方案
- 可以使用 @supports 进行优雅降级
-
复杂布局场景
- 对于复杂的网格布局,优先使用 Grid
- 可以配合 Flexbox 实现更复杂的布局
总结
每种方法都有其适用场景,选择合适的方法要考虑:
- 浏览器兼容性要求
- 布局复杂度
- 响应式需求
- 维护成本
建议在实际项目中:
- 优先使用 Flexbox/Grid 等现代方案
- 需要兼容老浏览器时,可以采用 calc()/绝对定位方案
- 结合项目实际情况选择最合适的方案