如何通过CSS Grid布局打造类似Windows开始菜单的布局效果?
- 内容介绍
- 文章标签
- 相关推荐
本文共计1254个文字,预计阅读时间需要6分钟。
Windows开始菜单最典型的视觉结构是左栏程序序列表+右栏系统链接/搜索/关机,使用grid-template-areas比浮动或inline-block更可控、更语义化。关键字不是堆叠属性,而是先定义好区域名称再映射。
常见错误是直接套用示例代码却忽略容器尺寸约束:如果父容器没设 display: grid 或没给明确宽高,grid-template-areas 会静默失效,布局退化成普通块级流。
-
grid-template-areas必须配合grid-area在子元素上使用,且名称要完全一致(区分大小写) - 左右两栏宽度不建议写死像素值;用
1fr 2fr或minmax(200px, 1fr) minmax(150px, 1fr)更适应内容变化 - IE 完全不支持
grid-template-areas,若需兼容 IE11,得 fallback 到float或flex,不能只靠 Autoprefixer 补全
示例结构:
.startmenu { display: grid; grid-template-areas: "programs links" "search links" "power links"; grid-template-columns: 1fr 200px; grid-template-rows: auto auto auto; gap: 8px; } <h1>programs { grid-area: programs; }</h1><h1>search { grid-area: search; }</h1><h1>links { grid-area: links; }</h1><h1>power { grid-area: power; }</h1><p>
立即学习“前端免费学习笔记(深入)”;
让搜索框和关机按钮在右栏垂直对齐
右栏通常包含三部分:顶部搜索框、中部常用链接(文档、设置)、底部关机按钮。用 grid-template-rows 硬拆容易导致内容溢出或留白失控——尤其当 #links 条目数量动态变化时。
更稳的做法是把右栏再包一层 display: grid 容器,并用 auto + min-content 控制行高:
- 顶部搜索框设为
grid-row: 1,固定高度(如40px)并加内边距 -
#links设为grid-row: 2,用overflow-y: auto防止撑开整体高度 - 关机按钮设为
grid-row: 3,加margin-top: auto推到底部(注意:这依赖于右栏容器设了display: flex; flex-direction: column;或用align-self: end配合place-items)
纯 Grid 实现底部对齐的可靠写法:
#right-panel { display: grid; grid-template-rows: max-content 1fr max-content; height: 300px; /* 必须有高度约束,否则 1fr 无效 */ } #search { grid-row: 1; } #links { grid-row: 2; overflow-y: auto; } #power { grid-row: 3; justify-self: end; }
响应式下如何折叠右栏或切换为单列
小屏设备上,左右双栏会挤占空间,用户更倾向「点击展开」而非常驻显示。这时候别用 @media 重写整个 grid-template-areas,容易漏掉子元素的 grid-area 值同步更新。
推荐做法是保留区域名,但用 grid-template-rows 和 grid-template-columns 动态切换流向:
- 桌面端:
grid-template-areas: "programs links"+grid-template-columns: 1fr 200px - 移动端:
grid-template-areas: "programs" "links"+grid-template-rows: auto auto,同时移除grid-template-columns - 注意:切换后,原
#links的grid-area: links依然有效,只是它现在独占一行
避免踩坑:不要在媒体查询里只改 grid-template-areas 却忘了重置 grid-column 或 grid-row ——这些显式定位会覆盖区域声明。
图标与文字对齐时 vertical-align 失效怎么办
开始菜单里每个条目通常是 <img> + 文字,用 display: inline-block 时 vertical-align: middle 经常不准,因为图片默认基线对齐,而文字有 descender(如 g、y 下延),造成视觉错位。
Grid 下最干净的解法是放弃 inline-block,改用 display: contents 或直接让 <li> 成为 grid 容器:
- 给每个菜单项(
<li>)设display: grid; grid-template-columns: 24px 1fr; align-items: center; gap: 8px; -
<img>放第一列,文字放第二列,align-items: center自动垂直居中 - 不用管
vertical-align,也不用额外包裹<span>,结构更扁平
示例:
#programs li { display: grid; grid-template-columns: 24px 1fr; align-items: center; gap: 8px; padding: 4px 8px; } #programs img { width: 24px; height: 24px; object-fit: contain; }
真正难的不是写出能跑的 Grid 布局,而是让每一块区域在内容增减、缩放、高对比度模式下都不崩形——这意味着你得反复测试 min-content、max-content 和 fit-content() 的实际表现,而不是只盯着设计稿像素对齐。
本文共计1254个文字,预计阅读时间需要6分钟。
Windows开始菜单最典型的视觉结构是左栏程序序列表+右栏系统链接/搜索/关机,使用grid-template-areas比浮动或inline-block更可控、更语义化。关键字不是堆叠属性,而是先定义好区域名称再映射。
常见错误是直接套用示例代码却忽略容器尺寸约束:如果父容器没设 display: grid 或没给明确宽高,grid-template-areas 会静默失效,布局退化成普通块级流。
-
grid-template-areas必须配合grid-area在子元素上使用,且名称要完全一致(区分大小写) - 左右两栏宽度不建议写死像素值;用
1fr 2fr或minmax(200px, 1fr) minmax(150px, 1fr)更适应内容变化 - IE 完全不支持
grid-template-areas,若需兼容 IE11,得 fallback 到float或flex,不能只靠 Autoprefixer 补全
示例结构:
.startmenu { display: grid; grid-template-areas: "programs links" "search links" "power links"; grid-template-columns: 1fr 200px; grid-template-rows: auto auto auto; gap: 8px; } <h1>programs { grid-area: programs; }</h1><h1>search { grid-area: search; }</h1><h1>links { grid-area: links; }</h1><h1>power { grid-area: power; }</h1><p>
立即学习“前端免费学习笔记(深入)”;
让搜索框和关机按钮在右栏垂直对齐
右栏通常包含三部分:顶部搜索框、中部常用链接(文档、设置)、底部关机按钮。用 grid-template-rows 硬拆容易导致内容溢出或留白失控——尤其当 #links 条目数量动态变化时。
更稳的做法是把右栏再包一层 display: grid 容器,并用 auto + min-content 控制行高:
- 顶部搜索框设为
grid-row: 1,固定高度(如40px)并加内边距 -
#links设为grid-row: 2,用overflow-y: auto防止撑开整体高度 - 关机按钮设为
grid-row: 3,加margin-top: auto推到底部(注意:这依赖于右栏容器设了display: flex; flex-direction: column;或用align-self: end配合place-items)
纯 Grid 实现底部对齐的可靠写法:
#right-panel { display: grid; grid-template-rows: max-content 1fr max-content; height: 300px; /* 必须有高度约束,否则 1fr 无效 */ } #search { grid-row: 1; } #links { grid-row: 2; overflow-y: auto; } #power { grid-row: 3; justify-self: end; }
响应式下如何折叠右栏或切换为单列
小屏设备上,左右双栏会挤占空间,用户更倾向「点击展开」而非常驻显示。这时候别用 @media 重写整个 grid-template-areas,容易漏掉子元素的 grid-area 值同步更新。
推荐做法是保留区域名,但用 grid-template-rows 和 grid-template-columns 动态切换流向:
- 桌面端:
grid-template-areas: "programs links"+grid-template-columns: 1fr 200px - 移动端:
grid-template-areas: "programs" "links"+grid-template-rows: auto auto,同时移除grid-template-columns - 注意:切换后,原
#links的grid-area: links依然有效,只是它现在独占一行
避免踩坑:不要在媒体查询里只改 grid-template-areas 却忘了重置 grid-column 或 grid-row ——这些显式定位会覆盖区域声明。
图标与文字对齐时 vertical-align 失效怎么办
开始菜单里每个条目通常是 <img> + 文字,用 display: inline-block 时 vertical-align: middle 经常不准,因为图片默认基线对齐,而文字有 descender(如 g、y 下延),造成视觉错位。
Grid 下最干净的解法是放弃 inline-block,改用 display: contents 或直接让 <li> 成为 grid 容器:
- 给每个菜单项(
<li>)设display: grid; grid-template-columns: 24px 1fr; align-items: center; gap: 8px; -
<img>放第一列,文字放第二列,align-items: center自动垂直居中 - 不用管
vertical-align,也不用额外包裹<span>,结构更扁平
示例:
#programs li { display: grid; grid-template-columns: 24px 1fr; align-items: center; gap: 8px; padding: 4px 8px; } #programs img { width: 24px; height: 24px; object-fit: contain; }
真正难的不是写出能跑的 Grid 布局,而是让每一块区域在内容增减、缩放、高对比度模式下都不崩形——这意味着你得反复测试 min-content、max-content 和 fit-content() 的实际表现,而不是只盯着设计稿像素对齐。

