仪表盘页面自适应首选 display: grid,必须配合 grid-template-areas、媒体查询重写模板及 gap 控制间距;仅用 flex 或百分比宽度无法解决二维区域对齐、页脚粘底、小屏截断等问题。

直接说结论:仪表盘页面自适应,display: grid 是首选,但必须配合 grid-template-areas + 媒体查询重写模板 + gap 控制间距,缺一不可;用 flex 或浮动做主结构,90% 会卡在 iPad 横屏或小屏文字截断上。
为什么不能只靠 flex 或百分比宽度
仪表盘是二维区域划分(头、侧边栏、主内容、页脚),不是一维流式排列。用 flex 强行堆,很快会遇到:
- 侧边栏和主内容高度不齐——
align-items: stretch在嵌套 flex 容器里经常失效 - 页脚无法“粘底”,尤其主内容不足一屏时,
margin-top: auto在多层 flex 中行为不可控 - 响应式切换时,
flex-direction: column把侧边栏压到顶部,但导航项又没留足够点击热区,真机测试常点不中 - 卡片区域想等高排列?
flex: 1对子项高度无强制约束,iOS Safari 15 以下直接忽略
grid-template-areas 必须按断点重写,不能只调 grid-template-columns
很多教程只改列宽,结果小屏下“nav main sidebar”还在同一行,侧边栏被压缩成一条竖线。正确做法是媒体查询里整块重写 grid-template-areas:
/* 默认(手机) */
.dashboard {
display: grid;
grid-template-areas:
"header"
"nav"
"main"
"footer";
grid-template-rows: 60px 1fr 2fr 40px;
}
<p>@media (min-width: 769px) {
.dashboard {
grid-template-areas:
"header header header"
"nav main sidebar"
"footer footer footer";
grid-template-rows: 60px 1fr 40px;
grid-template-columns: 240px 1fr 320px;
}
}注意:grid-area 值必须和 grid-template-areas 中的字符串完全一致(包括引号、空格、大小写),写成 grid-area: "Nav" 而模板里是 "nav" 就会失效。
立即学习“前端免费学习笔记(深入)”;
gap 是唯一干净的面板间距方案
别给每个卡片加 margin-bottom: 16px,否则响应式换行后,最后一行卡片下方会多出一倍空白。用 gap:
-
gap: 16px同时控制行列间隙,且不撑大容器 - 需要行列不同距?用
row-gap: 16px; column-gap: 24px -
gap不影响容器自身 padding,所以外边距要用padding单独设 - 旧版 Android WebView(Chromium 30)不支持
gap,若需兼容,得 fallback 到grid-column-gap和grid-row-gap
卡片内部高度塌陷是高频坑点
小屏下卡片内容(比如图表容器、指标数字)常被压扁甚至文字重叠,根源是父级没设最小高度或子元素用了绝对定位:
- 卡片本身加
min-height: 200px(别用height: 200px,否则大屏拉伸失效) - 图表区域用
h-full前,确保卡片是flex flex-col,图表盒加flex-1 - 字体大小别跳变,用
text-base sm:text-lg lg:text-xl,而不是text-sm md:text-4xl - Canvas 类仪表盘组件要监听
window.resize并重绘,且canvas.width/canvas.height必须用像素值重设,不能只靠 CSS 缩放
真正难的不是写出第一版 Grid,而是让所有卡片在 320px 宽度下仍可读、可点、不重叠——这要求你从第一行 CSS 就把 minmax()、clamp() 和断点粒度想清楚,而不是等 QA 提 bug 再补 media query。



















