CSS Grid 不但对于含长串文字内容的网站来说是好用的布局工具,也很适合拿来做许多传统 UI 的布局。本文将说明 CSS Grid 如何帮助需响应和适应用户互动及动态环境的应用程序改善其布局,同时还能让面板一直顺畅地滚动。
CSS Grid 能建立网站的布局。它让网页设计人员只用很小部分的程序代码,而不必像过去一样大量使用 float 工具,就能创造出绚丽的动态布局。Jen Simmons 多年来大力推广 CSS Grid,希望这个工具能登上浏览器。去年,她的努力终于有了结果:所有主流浏览器的最新桌面与移动版本都开始支持 CSS Grid。
CSS Grid 的功能非常强大,可让你轻松建立动态内容的网站(如这些实例)。不过,Grid 的好不仅限于一块块内容的布局。Grid 让你完全享有布局版面大小的主控权,比如滚动页面(scrolling),因此,以前在原生应用中习以为常的功能,如收合侧边面板和固定工具栏等,现在的操作都变得易如反掌。不用 hacks,也不必 debug,Grid就能办到。
我(作者 Josh Marinacci)在打造网页工具上有很多年的经验。下面是我帮复古角色扮演游戏所设计的工具的截图。Flexbox 刚推出,我就开始采用。当时,我用嵌套(nested)的水平和垂直方框,以及一些公用程序类别(utility classes),如 scrolling 和 stretching,来建立复杂的布局。
Flexbox 虽然比绝对寻址的 divs 和 float 的做法方便许多,但它还是有一些问题。请看下图中两个面板相邻处的近图,看到左右两边下方底线高低不同吗?
这是另一张截图。工具栏下方是涂鸦板。按照我的设计框架,工具栏应该要一直固定在顶端,但只要往下滚动,工具栏就会消失:
虽然这些问题全都能通过更多定位和 float 技巧来解决,但做出来的结果会很脆弱。每次我想增加新面板,就必须重新帮布局排错,还要找出在重设大小时占用额外空间的 div,而且标记(markup)还很丑。嵌套的水平和垂直框变得极其复杂,而我这个例子还只有两层而已。倘若网页的互动性和功能性更复杂些,版面设计的难度还会更高。
增加一个维度
Flexbox 最根本的问题是它只有一个维度,所以,Flexbox 很适合做包括工具栏和导航栏等单一维度的应用。但当我想同时对齐水平和垂直的内容时,它就会很麻烦。我需要做真正的二维布局,于是我开始使用 CSS Grid,因为 Grid 是2D 的。
下面是一个以 CSS Grid 建立的类似布局。
请仔细看看底线,对齐得非常工整。我不是在每块面板下增加边线,而是用grid-gap 来处理框线,一点都不必担心网格线宽度是否一致,一切都水到渠成。
对我来说,CSS Grid 最大的好处是,它能适应环境的变化。我的应用常有侧边面板。我要确定当面板收起或展开时,布局中的东西都能保持正常运作,而且理想上,最好还能省下用 JavaScript 重新计算布局的麻烦。侧边栏包含标头和页脚等多种元素,在变大或变小时,每一个元素都须保持对齐。 靠一个叫minmax() 的神奇功能,Grid 可以轻松办到这件事。
如果你研究过 CSS Grid,就应该知道可以用范本来设置列和行的布局。通过 200px 1fr 200px 这个模板,你可以打造出 200px 宽的侧边栏,中间还会有一块内容区块占掉页面中的其他空间。但若收起面板时会如何?现在,就算内容缩小了,栏宽仍会保持在 200px。不过,我们可以用 minmax,以 min-content 关键词作为最大参数值。
这样一来,网格的行宽就会变得刚好能容纳任意一个使用了最小宽度的行。因此,只要行中有任何部分(如标头)比其他部分宽,该栏就会自动扩大来包含所有的内容。如果行中内容变窄或完全消失,行宽也会随着调整。基本上,这个做法等于是复制了 Flexbox 的展开/收缩行为,但差别在于它不只影响单一元素,而会使调整的部分与行中所有元素一同协调。这才是真正的 2D 布局。
下面是范例画面中其余的程序代码:
为了让上方标头处的开关键能遮住侧边栏,我又加上这个程序代码。如果运用现代的 DOM APIs 和箭头函数,我们只需要几行函数就可以复制好 JQuery。
另外,请注意:CSS Grid 与 Flexbox 之间并无排斥。我们还是会视情况使用 Flexbox,也就是像工具栏等单一维度的内容。下面是我用标头来做工具栏的样式:
spacer 类别会使元素占掉所有的空间。但若在按钮中使用两个 spacer,工具栏便可随情况适时放大和缩小,而且名称还能一直在中间显示。这样就会很像原生工具栏。
你可到 Codepen 试试看,也可混合不同属性使用。
CSS Grid 支持二维的复杂度,非常适用于设计交互式应用。标记的语意可以保留,面板和工具栏也能整齐排列,grid-gap 会自动控制边框。它不需要用到任何一个 JavaScript 码,就能细致地调整布局,还能让我们控制平行和垂直的线。而且,这些全都不需要用到复杂的 CSS 框架。