使用 CSS Regions 轻松实现高级布局

合著:Beth Dakin 和 Mihnea-Vlad Ovidenie

CSS Regions 是一项令人兴奋的技术,它使得在网页内容中创建丰富、杂志般的布局比以往任何时候都更容易。Regions 在 WebKit 中已经开发了一段时间,我们很高兴地告诉您,它们已可在 iOS 7 上的 Safari、Mavericks 上的 Safari 7 以及 Mountain Lion 上的 Safari 6.1 中使用。

杂志般布局

于是我为我的个人博客写了这篇小文章

这很酷,但是如果它有这样一个更有趣的布局,难道不会更酷吗?

太棒了!没有 Regions,实现这样的布局非常麻烦。你必须准确地找出文章的哪些部分可以放入每个框中,然后将文章内容硬编码到相应的框中。而且经过所有这些工作之后,如果用户更改字体大小,设计就会完全乱套!布局看起来很酷,但这样做工作量很大,而且一点也不灵活。

Regions 让实现这种布局变得非常容易。它们允许作者指出,内容的某些部分旨在定义文档一部分的整体布局模板,而标记的其他部分则表示旨在填充该模板的内容。将流经模板的语义相关内容称为“命名流”(named flow)。在我们上面的例子中,命名流就是我文章的文本。一旦被命名,命名流就会被分发到称为区域(regions)的不相连容器中,这些区域可以以任何方式定位以实现所需的布局。

我们这个简单的例子只是 Regions 功能的冰山一角。稍后我们将介绍更复杂的应用,但首先让我们仔细看看代码。

什么是命名流?

命名流是 HTML 元素的一个集合,这些元素从文档的正常流中提取并单独显示。任何 HTML 元素都可以是命名流的一部分。当一个元素被收集到命名流中时,它的所有子元素也会一起被收集。

通过使用 CSS 属性 -webkit-flow-into,您可以将 HTML 元素的集合标识为命名流。 在我们的例子中,命名流将是包含文章文本的元素。

<style>
    #flow-content { -webkit-flow-into: pizza-manifesto; }
</style>
<div id="flow-content"><h1>Pizza is amazing</h1></div>

我们的 例子只有一个,但一个文档可以有任意数量的命名流,每个流都有自己的名称。

流入区域

区域(Region)是一个块级元素,它显示来自命名流的内容而不是其自身内容。区域可以具有任何大小,并可以定位在文档中的任何位置。它们不需要是同级元素,也不需要紧邻布局中的其他区域。

一个区域消费单个命名流的内容。大多数情况下,为了实现有趣的布局,会有一个命名流关联多个区域,在这种情况下,这些区域会形成一个区域链(region chain)。当命名流中的内容无法容纳在一个区域内时,内容就会自动流入链中的下一个区域。

将一个元素设为区域就像添加 -webkit-flow-from CSS 属性一样简单。在我们的例子中,这些区域是构成文档整体设计的布局模板的元素。

<style>
    .region { -webkit-flow-from: pizza-manifesto; }
</style>
<div class="region" id="region-1"></div>
<img src="pizza.jpg" width="512" height="342">
<div class="region" id="region-2"></div>
<div class="region" id="region-3"></div>
<div class="region" id="region-4"></div>
<div class="region" id="region-5"></div>

查看实际文档的代码,可以同时看到区域的代码和命名流的代码。

关于区域,需要记住的一个关键点是它们只是视觉容器。区域元素不会成为流入其内部元素的 DOM 父级;它们仅建立视觉上约束流内容的边界框。

高级区域功能

CSS Regions 规范中的一个很酷的功能是区域样式(region styling)。通过区域样式,设计师可以根据内容最终流经哪个区域来对其进行样式设置。例如,如果您想更改文章流中第二个区域显示的文本颜色,您可以使用区域样式来实现。

@-webkit-region #region-2 {
    p { color: green; }
}

每当区域中的文章内容布局发生变化时,额外的样式都会在幕后动态应用。因此,例如,如果用户调整浏览器窗口大小,并且不同的内容片段最终流经样式化的区域,内容将动态更新。目前,您只能使用 CSS 属性 colorbackground-color 为区域设置样式,但我们打算逐步增加对更多属性的支持,敬请期待!同时,请查看我们使用区域样式的文章此版本

还有一个完整的对象模型可用于在 JavaScript 中与区域和命名流进行交互。提议的 API 将使创建适应布局变化的流畅设计变得更加容易。例如,作者可以使用该 API 来确定是否有足够的区域来显示命名流中的内容。非常方便!

区域的梦想

CSS 区域功能强大,当它们与其他高级 CSS 功能(如形状、滤镜、弹性盒、转换和媒体查询)结合使用时,可以创造出令人难以置信的复杂设计。

早在二月,在 CodePen 主办的 CSS 区域模式竞技(pattern rodeo)中,Tyler Fry 和 Joshua Hibbert 制作了一些很棒的区域演示。Tyler 凭借他用区域和转换制作的阅读轮播图赢得了比赛,而 Joshua 则创作了一本爆炸书,在打开书时展现出漂亮的悬停效果。

Adobe WebPlatform 团队与国家地理合作,使用区域功能制作了一些非常有说服力的演示。查看这篇文章,它无缝地整合了文本和照片,创造了灵活的设计。Adobe 还制作了一个非常前沿的演示,您需要下载 WebKit Nightly 才能正确查看。这个 精美的原型 使用了区域功能,因此文章内容会自动在不同的容器中分割,如果字体大小或窗口大小改变,或者用户放大,所有内容都会自动重排。在此处查看源代码 此处

我们对区域这项技术感到非常兴奋,也很高兴它们已经可以在已发布的浏览器中使用。我们计划继续完善 WebKit 中的实现并添加更多功能,所以请务必回来查看改进。