flex是最稳的左右分栏起点,因天然支持左栏固定右栏自适应且高度上下文清晰;grid适合多栏扩展与布局切换,需严格配齐模板属性并设minmax和overflow;坚决不用table因破坏可访问性、响应式及交互稳定性。

用 display: flex 或 display: grid 布局,别碰 table 和 float —— 后者在现代后台系统里不是“能用”,而是“一加交互就出事”。
为什么 flex 是最稳的左右分栏起点
它天然支持主次结构:左栏固定、右栏自适应,且父子高度上下文清晰。关键不是写几行 CSS,而是卡死三个前提:
- 父容器必须设
height: 100vh(或明确高度),否则flex: 1没参照物 - 左栏要加
flex-shrink: 0,否则内容多时会被压缩到文字挤成一条线 - 右栏必须显式设
overflow: auto,不然长内容直接溢出、滚动条跑 body 上、Safari 尤其明显 - 避免同时给子元素设
width和flex,CSS 会忽略width,但开发者常误以为它还在生效
示例最小可用结构:
.layout { display: flex; height: 100vh; }
.sidebar { width: 240px; flex-shrink: 0; }
.main { flex: 1; overflow: auto; }
grid 适合什么场景?怎么防折叠错位
当你需要未来扩展为三栏、顶部+侧边+底部四区、或频繁切换布局(比如收起侧边栏只留图标)时,grid 更直观。但它不接受“差不多就行”的写法:
立即学习“前端免费学习笔记(深入)”;
-
grid-template-areas必须配grid-template-rows和grid-template-columns才生效,缺一不可 - 侧边栏列推荐写成
minmax(64px, 240px),不是240px—— 折叠态下 64px 刚好放图标+badge,展开后撑到 240px 放文字 - 主内容区若没设
overflow: auto,表格或弹窗一出来就会把整个页面撑高,侧边栏被截断 - 响应式改布局时,保持
grid-area名称不变,只动grid-template-areas字符串,否则 JS 绑定的区域选择器全失效
典型声明:
.layout {
display: grid;
grid-template-areas: "header header" "sidebar main" "footer footer";
grid-template-rows: 64px minmax(0, 1fr) 40px;
grid-template-columns: minmax(64px, 240px) 1fr;
}
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main { grid-area: main; overflow: auto; }
fixed 侧边栏常见崩坏点在哪
很多人用 position: fixed 是为了“永远钉住”,结果首页看着好,加个弹窗或嵌个图表就错位。核心问题不在定位本身,而在边界没对齐:
-
top值必须等于实际头部高度(比如.pg-header的 computed height),不能靠猜或写死50px;如果头部用了box-sizing: border-box或含 padding,真实高度得用浏览器开发者工具看 “Computed” 标签页 - 必须写
bottom: 0,否则长页面里侧边栏只显示半截 - 内容区不能只靠
margin-left让位,得用height: calc(100vh - 48px)+overflow-y: auto,否则滚动行为在 Safari 上极不稳定 - 侧边栏宽度别只设
width: 20%,小屏下直接缩没,底线是min-width: 200px—— 这是图标+文字可读的最小安全宽度
为什么坚决不用 table 做整体布局
它不是“不能显示两栏”,而是会让后续所有环节变脆弱:
- 屏幕阅读器把侧边栏读成“第1行第1列”,而不是
<nav>,可访问性直接归零 - 媒体查询下
colspan/rowspan失效,小屏切单列几乎等于重写 HTML - JS 控制菜单折叠时,
<td>宽度计算混乱,“菜单收了但空白还在”,调试成本远高于改用flex - 右侧内容区加个
<iframe>或<canvas>,<td>会拉伸变形,overflow: auto在单元格里行为不可靠
真有老系统必须兼容 table,最小改动方案是:外层 <table> 换成 <div class="layout">,再加三行 CSS:.layout { display: flex; height: 100vh; }、.sidebar { flex: 0 0 240px; }、.main { flex: 1; overflow: auto; } —— 其他 HTML 结构完全不动。
真正难的不是让两栏“看起来分开了”,而是当加了表格、弹窗、图表、iframe 后,它们是否还乖乖待在 content 区里不破框——这取决于你一开始有没有把 height、overflow、box-sizing 这三者的组合关系钉死。



















