Real Use Case of CSS Grid: Extended Sidebar

CSS Grid 真实案例:凸出的侧栏

前言

实际网页很少遇到特殊的视觉会需要动用到 CSS Grid 的情况,而我近期在制作一些比较特殊视觉的网页布局,事后感觉特别适合作为一个 CSS Grid 的启发教材,于是写下了本篇文章帮助通过真实世界案例更深刻了解 CSS Grid

问题

根据示意图制作 2 种大小的 RWD 页面。

问题示意图
问题示意图

解题

会发现该布局并没办法用传统一维版面的方式达成,因为在两种大小中它们需要隶属的容器也不同。

举例 sidebar 来说,它应该要是一起装在 main 的父容器当中,但在大装置尺寸下又要对齐 intro 的顶部,明显这样的需求在传统的 CSS 布局下是很难达成的,不管是用负数 margin 推移还是 position: absolutetransform 都会搞得一团乱很难维护,甚至要动用到 JavaScript 来计算位置 😐。

这时候就可以依靠 CSS Grid 来定义二维的版面布局,并且指派子元素到对应的区块中,通常我会用 CSS Grid Generator🔗 这类工具网站来设置好布局。具体来说可以先拉出网格的外貌:

.grid {
--max-width-main: 800px; /* main 区块最大宽度 */
--width-sidebar: 400px; /* 侧栏宽度 */
--height-topbar: 40px; /* topbar 高度 */
display: grid;
grid-template-columns:
1fr /* 左侧随意伸 */
minmax(0, var(--max-width-main)) var(--width-sidebar) /* main 区块自动伸缩并设置最大宽限制 + sidebar */
1fr; /* 右侧随意伸 */
grid-template-rows: var(--height-topbar) 1fr; /* 一层 topbar、一层随意 */
}

接着只需要把每个区块绑上对应的位置即可,这里可以发现用到一个很新颖的语法: subgrid🔗,简单来说就是让子元素的网格可以继承父元素的网格,这样就不用再重新定义网格了。

.header-area {
grid-area: 1 / 1 / 3 / 5;
display: grid;
grid-template-columns: subgrid;
}
.topbar-area {
height: var(--height-topbar);
display: grid;
grid-template-columns: subgrid;
grid-area: 1 / 2 / 3 / 4;
}
.intro-area {
display: grid;
grid-template-columns: subgrid;
grid-area: 3 / 2 / 4 / 3;
}
.main-area {
grid-area: 3 / 2 / 4 / 3;
}
.sidebar-area {
grid-area: 2 / 3 / 4 / 4;
}

在实际的项目中为了兼顾旧浏览器支持,我是在 header 区块中再重新定义相同的网格,以方便与其他元素对齐,并不会差异太大,就是相同的网格会重复定义一次。

总结

See the Pen extended-sidebar-subgrid by Riceball ( @riecball) on CodePen.

虽然理论上很少会遇到这种特殊的视觉,甚至就我所知现代的 UI 设计软件甚至也没有对应的手段去制作这方面的稿件,只能透过绘制两个版本的平面稿件来传达。这是个宝贵的经验充分的展现了 CSS 网格独一无二的优势。