新的实验性功能 - 限定范围的样式表

Alex Danilo

Chromium 最近在 HTML5 中实现了一项新功能:作用域样式表(也称为<style scoped>。网页作者可以将样式规则限制为仅应用于网页的一部分,方法是在 <style> 元素上设置“scope”属性(该元素是您希望应用样式的子树的直接子级元素)。这会限制样式,使其仅影响作为 <style> 元素的父元素及其所有后代元素。

示例

下面是一个使用标准样式的简单文档:

<html>
<body>
    <div>a div! <span>a span!</span></div>
    <div>
        <style>
        div { color: red; }
        span { color: green; }
        </style>
        a div! <span>a span!</span></div>
    <div>a div! <span>a span!</span></div>
</body>
</html>

指定的样式规则将为所有 <div> 红色和任何 <span> 绿色内的文本设置颜色:

一个 div! 一个 span!
一个 div! 一个 span!
一个 div! 一个 span!

不过,如果我们在 <style> 元素上设置 scoped

<html>
<body>
    <div>a div! <span>a span!</span></div>
    <div>
        <style scoped>
        div { color: red; }
        span { color: green; }
        </style>
        a div! <span>a span!</span></div>
    <div>a div! <span>a span!</span></div>
</body>
</html>

那么它会对样式规则加以限制,以便将其应用于封闭 <div>(即 <style scoped> 元素的父级)以及该 <div> 内的任何内容。我们将此方法称为“作用域”,结果如下所示:

一个 div!一个跨度!
一个 div! 一个跨度!
一个 div!一个跨度!

当然,您可以在标记中的任何位置执行此操作。因此,如果您喜欢尝试新事物,可以根据需要将限定了作用域的样式嵌套在标记的其他作用域部分中,以便精细控制样式的应用位置。

用例

现在这样做有什么好处呢?

一个常见的用例是联合内容:您作为网络作者想要整合来自第三方的内容(包括其所有样式),但又不想让这些样式“污染”网页中其他不相关的部分。这样做的一大优势是能够将来自其他网站(如 yelp、Twitter、eBay 等)的内容合并到一个网页中,而无需使用 <iframe> 隔离它们或即时编辑外部内容。

如果您使用的内容管理系统 (CMS) 会向您发送标记片段,这些片段全都拼合到最终网页显示中,那么这个功能非常实用,可以确保每个片段的样式设置独立于网页上的其他任何内容。这对 Wiki 也一样有用。

如果您想在网页上编写一些不错的演示代码,可以轻松地将样式限制为仅包含演示内容。这让您可以在演示中使用 CSS,但网页上的其他任何内容都不会受到影响。

另一个用例是简单地封装:例如,如果您的网页有侧边菜单,则最好将特定于该菜单的样式放入标记的相应部分的 <style scoped> 部分中。在呈现网页的其他部分时,这些样式规则不会有任何作用,因为它们可以与主要内容很好地分离开来!

Web 组件模型或许是最具吸引力的用例之一。Web 组件将是构建滑块、菜单、日期选择器、标签页微件等内容的绝佳方式。通过提供作用域样式,设计人员可以构建微件,并将其与样式打包为独立的单元,其他人可以获取并组合到丰富的 Web 应用中。我们计划在 Web 组件和 shadow DOM(可通过在 chrome://flags 中设置实验性“shadow DOM”标记)大量使用 <style scoped>。目前,没有什么好方法可以确保样式仅限于 Web 组件,而不依靠内嵌样式等不良做法,因此作用域样式非常适合这种情况。

为什么要添加父元素?

最自然的方式是添加父元素,以便 <style scoped> 规则可以为整个作用域设置某种通用背景颜色。此外,它还允许为尚不支持 <style scoped> 的浏览器“防御”编写限定了范围的样式表,方法是在规则前添加一个 ID 或类选择器作为后备:

<div id="menu">
    <style scoped>
    #menu .main { … }
    #menu .sub { … }
    …

这样可以模拟在实现“作用域”的情况下使用样式的效果,但由于选择器更为复杂,运行时性能会有所下降。这种方法的优点是,它支持一种优雅的回退方法,直到 <style scoped> 得到广泛支持,且可以简单地丢弃 ID 选择器。

状态

鉴于限定作用域的样式表的实现仍然是一项新技术,目前它们隐藏在 Chrome 中的运行时标记后面。如要启用这些功能,您需要安装版本号为 19 或更高的 Chrome 浏览器(目前为 Chrome Canary 版),然后在 chrome://flags(靠近末尾)中找到“启用 <style scoped>”条目,点击“启用”,然后重启浏览器。

目前尚无已知 bug,但 @global 以及 @keyframes@-webkit-region 的作用域版本仍在实施过程中。此外,@font-face 会被暂时忽略,因为规范很有可能会发生改变。

我们鼓励所有对此功能感兴趣的人都试用一下,并让我们了解您的体验:好的、坏的,以及(可能会)有缺陷的。