CSS栅格系统与弹性盒模型:实践比较

来源:互联网 发布:小学免费教学软件 编辑:程序博客网 时间:2024/06/03 22:03

不久以前,所有的HTML页面布局都是通过table、float以及其他CSS属性完成的,但这些方法并不适合构建复杂的web页面。

于是,W3C推出了flexbox(弹性盒模型)——一种专门用于构建健壮的响应式页面的布局模式。使用flexbox可以很容易地对齐页面元素和内容,而它也是现在大多数web开发者首选的CSS系统。

现在,最佳HTML布局系统的称号又多了一个新的竞争者,它就是强大的CSS Grid,3月底,它就已经得到了Firefox 52和Chrome 57的原生支持,其他浏览器相信也会紧随其后。

一个基本布局测试

为了了解两种系统的布局方式,我们会分别用这两种系统构建同一个页面,一次使用flexbox(弹性盒模型),一次使用CSS Grid(栅格系统)。页面如下:

静态页面布局
(一个精简的静态页面布局)

这种设计非常基础——包含一个居中容器,其中放置页头、主体部分、侧边栏和页脚。为了完成这个布局,我们需要解决这几个问题:
1. 对齐布局中的四个部分(页头、主体、侧边栏、页脚)。
2. 响应式设计(在小屏幕上侧边栏置于主体下方)。
3. 对齐页头内容——导航置于左侧,按钮置于右侧。

为了便于比较,我们一切从简,先从第一个问题开始。

挑战一:页面部分定位

Flexbox解决方案

我们首先使用flexbox解决这个问题,为容器添加display:flex,并且垂直定位子元素,也即让每个部分纵向排列。

.container {    display: flex;    flex-direction: column;}

现在我们来让主体部分和侧边栏靠在一起,由于我们已经设置其父容器为纵向,所以我们需要添加一个包装元素,来重新设置主体与侧边栏的定位方式。

<header></header><div class="main-and-sidebar-wrapper">    <section class="main"></section>    <aside class="sidebar"></aside></div><footer></footer>

然后我们将包装元素设置为flex容器(display:flex)并将定位方式设置为横向(flex-direction:row)。

.main-and-sidebar-wrapper {    display: flex;    flex-direction: row;}

最后一步是设置主体与侧边栏的尺寸,我们将其尺寸设置为3:1,使用flex很容易完成这个目标。

.main {    flex: 3;    margin-right: 60px;}.sidebar {   flex: 1;}

我们可以看到,flexbox完美地完成了这项工作,但是我们仍然需要添加大量的CSS属性和一个额外的HTML元素。接下来让我们看看CSS Grid是如何解决这个问题的。

CSS Grid解决方案

CSS Grid有多种使用方法,此处我们使用“栅格模板区域(grid-template-areas)”语法,因为它看起来最适合完成这个任务。
首先来定义四个栅格区域,每个对应页面的一个部分。

<header></header><!-- 注意此处无包装元素 --><section class="main"></section><aside class="sidebar"></aside><footer></footer>
header {    grid-area: header;}.main {    grid-area: main;}.sidebar {    grid-area: sidebar;}footer {    grid-area: footer;}

然后设置网格并且分配每个区域的位置。下面的代码可能乍一看很复杂,但一旦你了解了栅格系统它就会变得极易掌握。

.container {    display: grid;    /*在网格中定义列的数量和大小。      单位fr工作原理与flex类似:      fr列元素将按照其值共享同一行中的可用空间。      下面的代码表示有两列,第一列是第二列的三倍。*/    grid-template-columns: 3fr 1fr;    /*分配前面定义的网格区域。      第一行均为header。      第二行由main和sidebar共享。      第三行均为footer。*/    grid-template-areas:         "header header"        "main sidebar"        "footer footer";    /*每个网格间距60px*/    grid-gap: 60px;}

这样就完成了要求,布局将遵从上述结构,并且使用这种方式我们甚至不用处理内边距和外边距。

挑战二:响应式设计

Flexbox解决方案

这一步与前一步紧密联系在一起,对于flexbox来说我们必须改变包装元素的flex-direction并且调整边距。

@media (max-width: 600px) {    .main-and-sidebar-wrapper {        flex-direction: column;    }    .main {        margin-right: 0;        margin-bottom: 60px;    }}

由于我们的示例很简单,所以此处需要做的工作并不多,但在一个更复杂的布局中,就会有许许多多的内容需要重定义了。

CSS Grid解决方案

由于我们已经定义好了grid-areas,所以我们只需要在媒体查询中对网格进行重排序即可。

@media (max-width: 600px) {    .container {    /* 在移动设备上重排序网格*/        grid-template-areas:             "header header"            "main main"            "sidebar sidebar"            "footer footer";    }}

或者,我们也可以重新定义整个布局,如果你觉得这样可以更简洁些。

@media (max-width: 600px) {    .container {        /*  将页面重新定义为单列布局 */        grid-template-columns: 1fr;        grid-template-areas:             "header"            "main"            "sidebar"            "footer";    }}

挑战三:对齐页头组件

Flexbox解决方案

我们的页头中包括一些导航链接和一个按钮。我们希望将导航置左,按钮置右。导航中的链接必须相邻对齐。

<header>    <nav>        <li><a href="#"><h1>Logo</h1></a></li>        <li><a href="#">Link</a></li>        <li><a href="#">Link</a></li>    </nav>    <button>Button</button></header>

设置CSS样式:

header {    display: flex;    /*平铺页头内容*/    justify-content: space-between;}

现在导航列表和按钮已经正确对齐了,剩下的任务就是使<nav>中的元素水平移动了,最简单的方法是使用display:inline-block,但是为了完全使用flexbox来完成这个任务,我们使用下面这个解决方案:

header nav {    display: flex;    /*项目位于容器的基线上*/    align-items: baseline;}

仅有两行代码,还不错。接下来我们看看CSS Grid是如何解决的。

CSS Grid解决方案

为了分离导航和按钮,我们将<header>设置为2列栅格,另外我们需要额外两行CSS定位它们各自的边界。

header{    display: grid;    grid-template-columns: 1fr 1fr;}header nav {    justify-self: start;}header button {    justify-self: end;}

但此时<nav>中的嵌入式链接,尚未正确对齐,因为CSS Grid中没有类似flexbox的baseline(基线)选项。所以我们必须再定义一个子网格。

header nav {    display: grid;    grid-template-columns: auto 1fr 1fr;    align-items: end; }

很明显CSS Grid在完成这项布局中存在一些问题,但也是意料之中的事——毕竟它主要是用来对齐容器的,而不是容器中的内容,它并不适合做最后的润色。

总结

如果你通读了全文,结论就很显然了——并不存在一个最好的布局系统,flexbox和CSS Grid有各自擅长的领域,完全可以一起使用,而非一个能够替代另一个。
对于没时间通读全文的读者,可以看一看最后的总结:
1. CSS Grid更适用于页面的整体架构,非常易于管理页面布局,甚至可以用于非常规、不对成设计中。
2. Flexbox擅长进行元素中内容的对齐,可以使用flex定位设计中的细节部分。
3. 使用CSS Grid进行2D布局(行和列)。
4. Flexbox更适合一维空间(仅行或列)。
5. CSS Grid和flexbox不是替代关系,两者完全可以搭配使用。

0 0
原创粉丝点击