谈谈布局

最初接触到前端是在大一,跟很多人一样,是从模仿写一个页面开始的。当时理所当然的拿了学校主页去写, 且暂不说第一次写得多么难堪,那个时候我只是想着自己布局一定要布好,这也成为了当时的一种动力,觉得写一个前端,以布局为大。

一些历史

犹记得那个时候的学校首页是用table来布局的,一种很古老的布局方式。它用一系列复杂的嵌套的行跟列来标识HeaderNavigationFooter等等语义化的标签。这也是我后来了解到的很久以前开发者们在网页布局的方式。而当时自己模仿写的时候是采用了另外两种布局方式的,一种是流动式的布局,一种则是divposition的定位布局。

然而前端的变化发展很快,开发者们认为当今html应该更具语义化,为了日后项目维护的可持续和方便性。所以也就有了语义化的布局,不再是<div id="header">,或许这种更符合当今开发者们对html语义化的理解。

<body>
    <header><h1>Header</h1></header>
    <article>
        <h1>Title</h1>
        <p>balabala</p>
    </article>
    <aside><h1>Aside</h1></aside>
    <footer><h1>Footer</h1></footer>
</body>

又或者,如果你接触过很多css的framework,你可能听过grid这词,一种内嵌在框架中的栅格系统。最初自己接触到这词是在blueprint框架中,后来再次遇见是在 bootstrap中。前者只提供预定义宽度的列,而后者亦适用于流动式布局, 更侧重响应式、mobile-first。

/* blueprint */
.span-1 {width: 30px}
.span-2 {width: 70px}
.span-3 {width: 110px}
.span-4 {width: 150px}

/* bootstrap2 */
.span1 {width: 60px}
.row-fluid .span1 {
  width: 6.382978723404255%;
  *width: 6.329787234042553%;
}

如源码中所见,grids是为你预先定义好了固定宽度和媒体查询,你可以使用它所定义的这些类去布局。换句话说, 如果你想改变自己的布局你就需要相应的增删这些类名。

Susy

用过一段时间栅格系统后,我接触到了Susy

Your MARKUP, YOUR DESIGN, YOUR OPINIONS | OUR MATH.

这是Susy官网的原话,很明显,Susy是完全根据开发者主观意想来为你构建不同grids的一种工具,这意味着你不再需要任何预先设定好的一系列的grids,你可以用susy自己来定义想要的grid,而且,它是完全分离css跟html的。 Susy有多简单?如果你用过compass,相信你会上手非常快。

比如我们构建一个最简单的页面,只包含content、sidebar和底部的gallery图标。

<div class="container">
    <div class="content">Content</div>
    <div class="sidebar">Sidebar</div>
</div>
<div class="footer">
    <div class="gallery">
        <ul>
            <li class="gallery-item"><img src="http://placehold.it/100x100" alt=""></li>
            <li class="gallery-item"><img src="http://placehold.it/100x100" alt=""></li>
            <li class="gallery-item"><img src="http://placehold.it/100x100" alt=""></li>
            <li class="gallery-item"><img src="http://placehold.it/100x100" alt=""></li>
            <li class="gallery-item"><img src="http://placehold.it/100x100" alt=""></li>
            <li class="gallery-item"><img src="http://placehold.it/100x100" alt=""></li>
            <li class="gallery-item"><img src="http://placehold.it/100x100" alt=""></li>
            <li class="gallery-item"><img src="http://placehold.it/100x100" alt=""></li>
        </ul>
    </div>
</div>

我们可以自己定义在最小屏幕分辨率600px下content和sidebar横向对齐,底部图标一横排开。而在手机页面则是content和 sidebar垂直挨着,底部图标呈两横四列。

desktop mobile

你可能想到媒体查询,没错,我们来看看使用Susy会有多畅快。

$susy: ( column: 12);

.content {
    background-color: #fbeecb;
    @include breakpoint(600px) {
        @include span(8 of 12);
    }
}

.sidebar {
    background-color: #71dad2;
    @include breakpoint(600px) {
        @include span(4 of 12 last);
    }
}

.gallery {
    @include clearfix;
    background: black;
    padding: gutter();
    .gallery-item {
        @include gallery(2 of 8);
        margin-bottom: gutter(8);

        @include breakpoint(600px) {
            @include gallery(1 of 8);
            margin-bottom: 0;
        }
    }
}

抛开其他繁琐的问题,我们只关注Susy如何快速构建我们所要的布局,我们先声明了Susy全局默认下应该有12列,然后根据 breakpoint这个mixin来进行媒体查询。你可能疑惑breakpoint最后输出的媒体查询是什么样的。

@media (min-width: 600px) {
    .content {
        width: 66.10169%;
        float: left;
        margin-right: 1.69492%;
    }
}

没错,这就是我们预先定义最小屏幕分辨率下的媒体查询,然后我们使用span函数来声明content和sidebar分别占据的宽度, span(8 of 12)代表content占据整个12列宽度的8列,你可能会对of关键字感兴趣,实际上,Susy的这个函数还有许多关键字都有特定含义,比如atlast。Susy会自动帮你计算出特定条件下的宽度,当然它还拥有许多toolkit比如gallery。

如果你此时对Susy感兴趣,你可以移步官网去获取更多资源。实际上,接触Susy后我一直在使用Susy,当然你可能还需要去接触sass、compass 等等。

Flexbox

Susy面向传统的布局设计,你可以依靠它把各种浏览器兼容抛开。然而如果不讲兼容性,Flexbox绝对是大杀器。

Child elements in a flexbox can be laid out in any direction and can have flexible dimensions to adapt to the display space.

你可以在MDN上获取相关的文档。 拿一个含有header、article、sidebar和footer的页面来说,flexbox看起来是这样的。

<div id="container">
    <header>Header</header>
    <article>Article</article>
    <aside>Aside</aside>
    <footer>Footer</footer>
</div>
#container {
  display: -webkit-flex;
  display: flex;
  -webkit-flex-flow: row wrap;
  flex-flow: row wrap;
}
#container header, #container footer {
  -webkit-flex: 1 0 100%;
  flex: 1 0 100%;
}
#container header {
  background: #4dff4d;
}
#container footer {
  background: #ffffcc;
}
#container article {
  -webkit-flex: 2 1 30em;
  flex: 2 1 30em;
  background: #ff4dff;
}
#container aside {
  -webkit-flex: 1 0 15em;
  flex: 1 0 15em;
  background: #ccccff;
}

在Flexbox中,我们可以自动调整子元素的高和宽,来很好的填充任何显示设备中的可用显示空间,收缩内容防止内容溢出。

Summary

目前自己常用的是Susy,但相信未来Flexbox也将大放光彩。

Reference

build-web-layouts-easily-susy Using_css_flexible_boxes