iOS7 中 CSS 模糊透明标题效果

Avatar of Fabrice Weinberg
Fabrice Weinberg 发布

DigitalOcean 为您旅程的每个阶段提供云产品。立即开始使用 $200 免费积分!

以下文章由 Fabrice Weinberg 撰写。Fabrice 是我们网站的常客撰稿人。他总是对最新的技术和可能性充满期待。在 iOS7 发布之初,他研究了如何重现一种您可能猜不到在 Web 上也能实现的效果。这很棘手,使用了尖端功能,但却是可行的!

让我们从背景故事开始。@simurai 很久以前就问过,是否可以在任意 DOM 节点上应用模糊效果,以模拟 iOS7 控制中心的半透明效果(您可以在此找到他的 Pen 这里)。

我不会详细解释如何为控制中心构建这种效果,而是专注于如何构建与您在 iOS7 中的 iMessage 和许多其他应用程序中找到的模糊标题效果类似的效果。但是,您将学习到的技巧可以让您构建控制中心效果。

iOS 7 上的 iMessage

使用的技术

此解决方案大量使用 CSS 区域,它仍然是工作草案,但由于 Adobe 的支持,它在今天的 WebKit/Blink 中得到了实现。

随着 iOS7 的发布,Mobile Safari 是第一个默认启用此功能的浏览器(仍然是 -webkit- 前缀)。在 Google Chrome 29 中,您只需要启用 experimental-webkit-features。在 Google Chrome 30+ 中,它是 experimental-web-platform-features,位于 about:flags 下。

CSS 区域

CSS 区域快速入门:它完全是关于将页面的结构与内容分离。有两个新的 CSS 属性 flow-into: named-region;flow-from: named-region;,这两个属性用于定义一个所谓的 named-region。您可以将其视为一个变量,它将保存任意内容。

具有 flow-into 的元素就像一个内容容器。该内容“流入”具有 flow-onto 的其他元素中。

一个简单的例子

查看 Pen %= penName %>,作者是 Fabrice Weinberg (@FWeinb),发布于 CodePen

假设您的浏览器支持区域,您将能够看到结构与内容是分开的。使用 flow-into: content,来自具有 .main-content 类的 div 的内容将通过使用 flow-from: content; 的两个具有 .region 类的 div 流动。

要更深入地了解 CSS 区域,请阅读 Arno Gourdol 的精彩文章 CSS3 区域:使用 HTML 和 CSS3 进行丰富的页面布局

入门

让我们从定义 HTML 结构开始。它很简单。我们需要一个标题和一个用于消息的容器。由于使用了 CSS 区域,另一个容器是必需的,用于保存将通过标题和消息容器流动的内容。

查看 Pen #,作者是 Fabrice Weinberg (@FWeinb),发布于 CodePen

这里有 CSS 用于模糊 .header

就像第一个示例一样,任何不适合 .header 的内容都将通过 .content-container 流动。

这不是我们想要的行为。我们希望所有内容都在 .content-container 中,并且只模糊被 .header “隐藏”的内容。让我们解决这个问题。

使用 CSS 区域来“传输”DOM

这部分有点hacky,因为将 overflow-y: auto 放置在获取 CSS 属性 flow-into: named-region; 的元素上的行为在规范中没有描述,因此取决于实现。

CSS 区域允许我们定义任意 DOM 节点的流动,甚至让我们添加 overflow-y: auto 来使内容可滚动。此外,还需要定义高度。

让我们使用上面的示例,在 .main-content 中添加固定高度和 overflow-y: scroll

查看 Pen %= penName %>,作者是 Fabrice Weinberg (@FWeinb),发布于 CodePen

看起来还不够好。滚动工作正常,但 .header 仍然是空的。

有趣的部分现在来了,我们将要从 .main-content “传输”内容到 .header 元素。这可以通过 CSS3 和使用 transform: translateY().main-content 的整个内容层向上移动 .header 高度来实现。

查看 Pen %= penName %>,作者是 Fabrice Weinberg (@FWeinb),发布于 CodePen

看起来好多了!但是仍然有些地方看起来不对。现在总是有一些内容被 .header 隐藏。要解决这个问题,我们只需要将 .header 的高度作为 padding-top 添加到 .main-content 中,以适应所占空间。

查看 Pen b8cc5b9a310ff94de8c707c24a3c99d0,作者是 Fabrice Weinberg (@FWeinb),发布于 CodePen

就是这样。这是实现 iOS7 半透明/模糊效果的核心技术。基于这种技术,我构建了这个 小游乐场,您可以在其中自定义标题,甚至添加色调颜色。

查看 Pen iOS7 半透明 CSS,作者是 Fabrice Weinberg (@FWeinb),发布于 CodePen

性能很重要

让我们看看这种效果的渲染性能

Chrome DevTools“之前”时间线
提示:在 CodePen 上使用 调试视图 来测量时间线。请务必禁用所有插件。只需导航到 http://codepen.io/[用户名]/debug/[penid]。请记住,这仅适用于您拥有的 Pen 且登录时才有效。

上面是您在向上和向下滚动时看到的时间线,您可以看到几乎一半的帧时间(16.66 毫秒)用于绘制。在我们深入了解之前,我想告诉您 Chrome DevTools 中一个很棒的新功能:层。它是 DevTools 中的一个新标签,您可以看到 Chrome 在文档中将哪些元素提升到其自己的层。它仍然是实验性的,因此您必须在 about:flags 中启用 devtools-experiments 标志。请务必重启 Chrome。然后,要激活层实验,请打开开发者工具,单击右下角的扳手图标(或按 ?)打开设置。

启用层面板

使用层标签

在上面,您可以看到层标签已打开。Chrome 仅为整个文档创建了一个层,这意味着页面上的任何更改都将触发整个文档的重绘。这很昂贵!您可能已经注意到左上角的复选框。它用于在 .header 元素上应用 transform: translateZ(0)。您可以在此找到 Pen 这里transform: translateZ(0) hack 用于将元素提升到 GPU 上的自己的层。

提示:您可以通过鼠标拖动来旋转层标签中的层。

如您所见,现在 div.header 还有一个额外的层。让我们再做一次时间线,现在使用 transform: translateZ(0) hack

Chrome DevTools“之后”时间线

看起来好多了。现在绘制成本仅占每帧总时间的约 1/10。有了新的层标签,现在可以更容易地看到 Chrome 在哪里创建了层,以及看到潜在的性能瓶颈。

总结

很高兴看到这在今天的 WebKit/Blink 中是可能的。但(总是会有个但是)这种技术尚未准备好投入生产。尽管它在台式机上运行良好,但在目前的 iOS7 上却无法使用,它很慢,而且滚动根本无法正常工作

我创建了一个GitHub 仓库,您可以在其中找到游乐场的源代码。

如果有人知道如何在 iOS7 上实现滚动(最好是不用 JavaScript 的方法),请告诉我!我希望您能学到一两招新技巧。感谢您的阅读!