响应式设计的未来——Flexbox

在CSS中,浮动几乎代替了表格用来服务于布局,做为替身,比表格好用得多。但他们仍然有限。现在有一个建议的解决方案称为CSS Flexible Box布局模块,一般称为Flexbox。

Flexbox是CSS3推荐方法,用来帮助设计师更好的控制页面的元素,在没有比较好的解决方案之前,Flexbox要比其他现代布局方案要更强。

我们仍然没有大规模使用Flexbox, 是因为它至今还是受到限制的。如果Flexbox得到浏览器友好支持的时候,加上媒体查询的弹性布局会使Web设计师在Web布局上带来革命性的变化。

CSS的痛楚

在写这篇教程时,支持Flexbox的浏览器还是有限的。Chrome浏览器需要添加其自身的前缀“-webkit-”才能识别。其他的Webkit内核浏览器,特别是移动端的Safari和Android浏览支持都是仅仅有限的。而微软IE只有IE10。不过这个Flexbox规范本身是在不断变化,在过去的几年里看到有关于他的许多变化。但随着规范的定案和浏览器后期的开发,Flexbox终将成为一个很重要的属性——用于设计上的布局。下面主要介绍它在响应式设计中应用。

容器(Containers)

一个Flexbox布局需要创建一个包含元素的容器,比如一个“

”,用来包裹一些项目。最基本的,Flexbox会让其伸缩项目放在一个线上(主线、侧线),不需要修改HTML结构就能实现其同一基线上的任意摆放。如下面的示例:著作权归作者所有。

1
2
3
4
5
<div>
<p>1</p>
<p>2</p>
<p>3</p>
</div>

flexbox-flex-direction

在上面的示例中,三个伸缩项目可以通过“flex-direction”属性使用其在伸缩容器中放置在第一和最后,也可以是水平或垂直摆放。在一个web页面中,这意味着,在不改变HTML结构情况之下整个布局可能会重安排。这将是一个名副其实的响应式设计。

当使用“display:block”时元素变成块形式垂直摆放(在不浮动情况之下),“display:inline”会让元素包裹文本保持在同一行,而“display:flex”可以让设计师改变方向、顺序、对齐方式和间距。从列表布局角度出处,Flexbox布局适用于任何系列的产品。Flexbox可用的用途包括:

  • 快速调整列、页眉、页脚和侧边栏位置
  • 自动计算导航间距
  • 意味着更少的HTML使用CSS实现更多的布局
  • 鉴于随机物品在同一个系列,使用.important在顶部随意移动显示。

最重要的是要注意Flexbox对设计的视觉风格的影响。重新排列元素在屏幕上显示的次序并不会影响他们的HTML结构与Javascript的框架或屏幕阅读器的阅读。

对齐(ALIGNMENT)

除了方向,伸缩项目有可能会推到伸缩容器的开始位置(全部靠左)、结束位置(全部靠右)、居中以及有一个的间距。可以在伸缩容器上添加“justify-content”属性来控制伸缩项目之间对齐方式:开始、结束等。

flexbox-justify

上图在伸缩项目排列中隐含的线称为“主轴(main axis)”。这里的示例让导航的链接沿着主轴线(显示的黑线),根据需要自动改变空间。

每个主轴都有一个方向(flex-direction)和一个流(flex-fow):水平方向的有向左或向右(row或row-reverse);垂直方向的有向下和向上(column和column-reverse)。上面例子中的第一个设置了flex-row为row,意思是“flex-start”让伸缩项目向左边推。当flex-row设置为“row-reverse”时,像最后一个示例所示,“flex-start”推到伸缩容器最右边。

包裹(WRAPPING)

当一系列的伸缩项目到达伸缩容器的终点位置时,可以让伸缩项目在一行显示或者多行显示,你就传统的内联元素一样。

flexbox-flex-wrap

上面的属性应用到伸缩容器上。其他的适用于每个伸缩项目。

顺序(ORDER)

最后一个主要属性(有关于响应式设计方面)用来控制元素出现的精确顺序。著作权归作者所有。

flexbox-flex-order

默认情况之下,伸缩容器中的每一个伸缩项目都有一个“order:0”属性。给其中一个伸缩项目设置“order:1”,会让这个伸缩项目沿主轴向右(侧轴向下)推动。如果设置一个伸缩项目的order值小于0,例如:“order:-1”,会让这个伸缩项目沿主轴向左(侧轴向上)推动。

Flexbox的侧轴具有和主轴一样的属性功能。到目前为止,影响响应式设计的主要属性是“flex-direction”、“flexbox-justify”和order。

Flexbox和Media Queries

响应式设计需要在不同屏幕尺寸具有不同的布局。不幸的是,一些布局要求HTML具有一个特定的方式,比如说图片在标题前,或者图片在标题后。Flexbox可以通过CSS来控制更多的移位,这样网页设计师就可以通过媒体查询在不同的屏幕大小中应用不同的配置。

这里有一个挑战性的案例:一个新闻网站想要展示其最新的文章片段。每个片段都有一个缩略图和不同数量的文本。需要有三种布局风格:桌面宽屏;笔记本的中等大小屏和智能手机的320px宽。可访问性,它必须保持导航在或者接近网站的标题,但出版本商想尽可能的突出大标题显示。

flexbox-flex-direction

HTML结构

为了结构的清晰,这个示例使用了简单的HTML结构:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<html>
<body>
<div class="wrapper">
<header>
<img src="images/trendy-logo.png" />
</header>
<nav>
<a href="#">home</a>
<a href="#">about</a>
<a href="#">other</a>
<a href="#">contact</a>
</nav>
<section>
<article>
<figure><img src="images/box.png" /></figure>
<div>
<h2>Sample headline goes here</h2>
<p>Sample text sample text sample text sample text sample text sample text sample text </p>
</div>
</article>
<article></article>
</section>
</div>
</body>
</html>

有一些重要的事项:

  • 一个<div>容器包裹了整个页面。
  • 标题和导航链接在文章列表区域<section>前面
  • 每一篇文章都是一个独立的章节放在<section>里面。

Media Queries条件

我们设置了三个响应式断点:窄屏、中屏和宽屏。

1
2
3
4
5
6
7
8
9
@media only screen and (max-width: 480px) {
/* 窄屏 */
}
@media only screen and (min-width: 481px) and (max-width: 960px) {
/* 中屏 */
}
@media only screen and (min-width: 961px) {
/* 宽屏 */
}

窄屏:交替图标和重排结构

1、首先指定每个<article>元素作为伸缩容器。在这些例子中,我们使用-webkit-前缀来支持Chrome。

1
2
3
4
5
article {
display: -webkit-flex;
-webkit-align-items: start;
}

2、接下来为所有的文章列表设置方向:

1
2
3
4
5
6
article:nth-child(odd) {
-webkit-flex-direction: row;
}
article:nth-child(even) {
-webkit-flex-direction: row-reverse;
}

3、把内容优先于导航显示,我们需要把“.wrapper”设置为伸缩容器,并设置伸缩流的方向为“column”:

1
2
3
4
5
.wrapper {
display: -webkit-flex;
-webkit-flex-direction: column;
}

4、最后,把<nav>元素也设置成伸缩容器,使用“justify-content”属性设置导航链接之间的间距工:

1
2
3
4
5
6
nav {
-webkit-order: 999;
display: -webkit-flex;
-webkit-justify-content: space-around;
}

设置了“order”为999是为了过度的布局,而没有设置二到八这样的数值,其实任何正数都可以工作。但设置999是为了应对未来order的变化,999是一个安全的数值,但有一些网站将会超过导航998节。

中屏:一个纵列

浏览器在480px到800px之间宽,可能有足够的高度连续展示文章列表供用户阅读。这个布局,我们要做到的就是这一点:

1、像窄屏的布局一样,将导航栏变成弹性布局,并给导航链接留有一定的空间:

1
2
3
4
5
6
nav {
display: -webkit-flex;
-webkit-flex-direction: row;
-webkit-justify-content: space-between;
}

2、Flexbox布局不需要花哨,这个例子演示的了如何让Flexbox制作一个等宽列,可用来代替以前那种依靠浮动和清除浮动的布局

1
2
3
4
5
6
article {
display: -webkit-flex;
-webkit-justify-content: start;
-webkit-flex-direction: row;
}

宽屏:使用额外的空间

宽屏的布局主要利用“.wrapper”伸缩容器的空间,把文章列表像tiling一样的铺置。

1、把“.wrapper”变成伸缩容器,将把导航放在左边:

1
2
3
4
5
.wrapper {
display: -webkit-flex;
-webkit-flex-direction: row;
}

如果想把导航放在右边,可以使用“row-reverse”来替代“row”。

2、标题和导航叠加是个很棘手的事情,因为我们把”.wrapper”变成了伸缩容器,同时也使标题、导航和section的文章列表变成了水平展示。意思就是标题、logo和左边的导航叠加在一列中。

解决这样的问题,我们要有一点手法:使用一个负的margin-left和padding-top,将导航拉到logo的下面。

1
2
3
4
5
6
7
8
9
10
11
12
nav {
width: 25%;
margin-left: -50px;
}
nav a {
display: block;
padding: 10px 0;
}
nav a:first-child {
padding-top: 120px;
}

3、文章列表要像Tile一样展示,需要给section设置成伸缩容器,然后缩小让其放置在同一行

1
2
3
4
5
6
7
8
9
10
section {
display: -webkit-flex;
-webkit-flex-wrap: wrap;
-webkit-align-items: flex-start;
}
article {
width: 180px;
margin: 10px;
}

结果:三种不同的布局,利用空间来实现响应式布局是最好的。

下一步

虽然Flexbox布局还不能得到广泛的支持,但后结随着规范的落定和各大浏览器厂商的支持力度提高,Flexbox将会成为CSS布局的好工具。

英文原文地址

中文译文地址