grid-template-areas 可清晰定义 spa 外壳语义区域布局,配合 minmax() 实现侧边栏弹性宽度,并应优先使用 @container 而非 @media 响应式。

用 grid-template-areas 定义语义化外壳结构
单页应用(SPA)的外壳通常包含 header、nav、main、aside、footer 等固定区域,用 grid-template-areas 能一眼看清布局意图,也方便后续维护和测试。它比纯线性数字定位更抗改、更易协作。
关键点:
-
grid-template-areas中每行字符串对应一行轨道,每个单词代表一个命名区域,.表示空单元格 - 所有子元素必须设置
grid-area且值与命名一致,否则不参与该区域分配 - 命名区域不强制要求所有单词都出现在 DOM 中——比如
aside在小屏下可设为display: none,grid-template-areas仍可保留原定义,不影响其他区域计算
示例:
body {
display: grid;
grid-template-areas:
"header header header"
"nav main aside"
"footer footer footer";
grid-template-columns: 240px 1fr 320px;
grid-template-rows: auto 1fr auto;
min-height: 100vh;
}
用 minmax() + 1fr 控制侧边栏弹性宽度
SPA 外壳里 nav 和 aside 往往需要“最小可用、最大受限”的行为:菜单栏不能太窄影响图标识别,也不能无限撑宽挤占内容;右侧工具栏同理。硬写 240px 或 20% 都不够鲁棒。
推荐写法:
-
nav区域:用minmax(64px, 240px)—— 图标模式下收窄至 64px,展开后最多 240px -
main区域:保持1fr,自动吸收所有剩余空间,不设固定宽或 max-width -
aside区域:用minmax(280px, 320px),兼顾小屏可读性与大屏信息密度 - 避免对
main设max-width,否则在宽屏下留白难看;如需居中阅读体验,应在内部容器上加限制
响应式切换靠 @container,不是 @media
SPA 外壳常嵌在 iframe、弹窗或折叠面板里,视口宽度 ≠ 布局容器宽度。@media (max-width: 768px) 在这类场景下完全失效。
正确做法是启用 container queries:
- 给外壳容器(如
body或最外层div#app)加container-type: inline-size - 用
@container (width 切换布局,例如把三栏变两栏、隐藏 <code>nav、让aside下沉到main下方 - 注意:Chrome / Firefox 已支持,Safari 17.4+ 支持,旧版 Safari 需降级为
@media+ResizeObserver监听容器尺寸变化并切 class - 不要依赖
grid-auto-flow: dense来“填空”——它会打乱 DOM 顺序,影响键盘 tab 流和屏幕阅读器焦点路径
避免 grid-column 数字定位导致的维护陷阱
很多教程教用 grid-column: 2 / 4 这类数字线定位,短期快,长期痛。一旦新增一列或调整顺序,所有相关项都要重算线号,极易漏改、错位、溢出。
真实项目中更稳妥的方式:
- 始终优先用
grid-area+grid-template-areas,视觉结构与代码结构一一对应 - 若必须用数字线(如动态插入的浮层),至少配合
grid-column-start: -2这类负向定位,减少对左侧结构的耦合 - 禁止在多个组件共用的外壳 CSS 中写死
grid-row值——不同模块加载时机不同,DOM 插入顺序不可控,会导致错行 - 所有区域高度应由内容自然撑开,慎用
grid-template-rows: 100px 1fr 50px这类固定值,除非明确要求 header/footer 高度锁定
真正麻烦的不是写第一版外壳,而是半年后加一个新模块时发现 nav 的 grid-column 被另一个同事改过三次,而没人记得当初为什么是 1 / 2 而不是 1 / 3。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











