
双飞翼布局和圣杯布局是很相似的,甚至你可以把它们当作是同一种类型布局。实现方式之类的也是相同的。接下来,就以圣杯布局为例吧,它是 Web 布局中的十大经典布局之一。
圣杯布局看上去像下图这样:
维基百科是这样解释圣杯布局的,详细请点击下面卡片:
它有着几个典型的特征:
构建圣杯布局时,对 HTML 的结构是有一定的要求,即 主内容为先 。早期这样做,是让用户在 Web 页面加载缓慢时,就能先看到主内容。
对于经典的圣杯布局,它有:
它应该具备的能力:
我们来看一个真实的圣杯布局案例:
实现该页面,你可能需要的 HTML 结构如下:
在没有 CSS 加载的情况之下,你看到的圣杯布局会是下图这样:
我们可以像下面这样使用 Flexbox 来构建圣杯布局:
可以结合 CSS 的媒体查询,在小屏幕下调整布局,构建一个具有响应式能力的圣杯布局:
Demo 地址:
如果我们使用 CSS Grid 布局技术的话,它实现一个带有响应式效果的圣杯布局,更容易一些:
另外,到现在为止,经典的“圣杯”布局所包含的内容并不总是都一样的,比如 Facebook、Medium 都在标准的“圣杯”(Holy Grail)布局上做了一个变化,他们去掉了一个突出的页脚。
前面说过了,我们在构建一个标准的圣杯布局时,它所需的 HTML 结构大致如下:
为了在视觉上使 .main 、.nav 和 .sidebar 位置符合要求,比如说在桌面端要求主内容 .main 列位于其他两列(.nav 和 .sidebar)中间。如果你使用的是 Flexbox 布局技术来构建圣杯布局,可以通过改变 Flex 项目的 order 属性的值来调整它们,比如:
但在一些终端上,Flexbox 技术实现起来就有不少的难度,比如要在同一 HTML 结构基础上实现平板端(Tablet)的“圣杯”布局效果,Flexbox 就不太可能了:
Flexbox 是一种一维布局,要实现类似九宫格的布局,总是需要调整 HTML 结构的。但要是换成 CSS 网格布局技术的话,这一切都不再是问题。也就是说,使用 CSS 网格构建一个响应式的圣杯布局要比 Flexbox 技术容易得多。
除了 CSS 网格是一个二维布局之外,CSS 网格布局有着天然的优势, 那就是你可以使用 grid-row 、**grid-column** 和 grid-area 属性,按照网格线的名称或网格区域名称,将网格项目放置到任意你想要的位置上 。
我们来看看,CSS 网格构建具有响应式的圣杯布局的过程和关键性的代码。
你只需要将圣杯布局的容器父元素定义为一个网格,就能达到响应式布局中移动端先行的原则 。即:
它将创建一个一列多行的网格,你就可以使用网格线的名称,将网格项目放置到相应的位置:
你可能已经发现了,默认情况之下,所有元素的高度都是相等的,这不是我们想要的效果。在网格布局中,只需要一行代码就可以用来调整它们的高度。即,使用 grid-template-rows 来指定行网格轨道的高度,比如:
这样一来,页面的“页头(.header)”、“导航栏(.nav)”、“侧边栏(.sidebar)”和“页脚(.footer)” 都将以自身内容来撑高其高度。网格容器在块轴方向剩余的空间都将给主内容(.main):
你还可以在网格容器上设置一个 gap 值,让行与行之间有一定的间距,让视觉上看起来更好看一些:
移动端(浏览器视窗宽度小于 768px)的效果就出来了:
移动端的布局完成之后,我们就可以来调整平板端的布局了。从示意图中可以知道,平板端的圣杯布局是一个两列布局。它对应的是一个 2 x 4 的网格(两列四行)。网格布局中定义行和列的轨道数量以及它的尺寸是通过 grid-template-rows 和 grid-template-columns 两个属性来完成的。也就是说,我们需要在符合浏览器视窗断点条件下,调整 body 的 grid-template-columns 和 grid-template-rows 值:
示例中将 grid-template-columns 的值设置为 220px minmax(0, 1fr) ,它将会告诉浏览器,网格第一列宽度是 220px ,第二列的宽度是 0 ~ 1fr ,即除去第一列宽度和列间距就是它的宽度了。这样做能实现第一列的宽度是一个固定尺寸,第二列的宽度能跟着浏览器视窗宽度自适应的调整。视窗宽度变大,它也能变宽,视窗宽度变小,它也随之变小。
正如上图所示,仅调整网格的 grid-template-rows 和 grid-template-columns 的值是无法达到平板端圣杯布局的效果,我们还需要使用 grid-row 、grid-column 或 grid-area 将网格项目按照圣杯布局的意图来放置到正确的位置:
这样就有了下图的效果,调整浏览器视窗宽度,你可以看到平板端和移动端两个不同断点下,圣杯布局的差异:
按此思路,调整桌面端中 grid-template-rows 和 grid-template-columns 的值,并且重新放置网格项目即可。
这样就完了一个终级版的带有响应式的圣杯布局:
从代码中不难发现,由于不同断点下创建的网格不同,不得不调整每个网格项目的 grid-area 值。其实,在网格布局中,有更优的方案来解决。那就是在不同断点下调整网格容器的 grid-template-areas 的值(给网格区域显示命名),如此一来,只需要把网格项目的 grid-area 值指定为已命名的网格区域名称即可。按这种方案把上面代码优化一下:
最终构建一个具有响应式的圣杯布局所有代码如下所示:
现在你可以往每个网格项目中填充 Web 页面所需的内容。当然,你也可以根据设计稿的需求来调整网格轨道的尺寸,最终构建一个符合自己需求的响应式圣杯布局效果:
Demo 地址:
上面就是 CSS Flexbox和 CSS Grid实现圣杯(或双飞翼)布局的最新方案。要是你对 Web 中其他布局或布局相关技术感兴趣的话,可以移步阅读《现代 Web 布局技术》:
