前言
实际网页很少遇到特殊的视觉会需要动用到 CSS Grid 的情况,而我近期在制作一些比较特殊视觉的网页布局,事后感觉特别适合作为一个 CSS Grid 的启发教材,于是写下了本篇文章帮助通过真实世界案例更深刻了解 CSS Grid。
问题
根据示意图制作 2 种大小的 RWD 页面。
解题
会发现该布局并没办法用传统一维版面的方式达成,因为在两种大小中它们需要隶属的容器也不同。
举例 sidebar
来说,它应该要是一起装在 main
的父容器当中,但在大装置尺寸下又要对齐 intro
的顶部,明显这样的需求在传统的 CSS 布局下是很难达成的,不管是用负数 margin
推移还是 position: absolute
、 transform
都会搞得一团乱很难维护,甚至要动用到 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 网格独一无二的优势。