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

Alex Danilo

Chromium 最近实现了一项 HTML5 中的新功能:范围限定的样式表,也称为<style scoped>。网站作者可以通过在 <style> 元素(即您要将样式应用到的子树的根元素的直接子元素)上设置“scoped”属性,将样式规则限制为仅应用于网页的一部分。这会限制样式仅影响 <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>

然后,它会限制样式规则,以便将其应用于 <style scoped> 元素的父级封闭 <div> 以及仅该 <div> 内的所有内容。我们将其称为“限定范围”,其结果如下所示:

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

当然,这可以在标记中的任何位置完成。因此,如果您愿意冒险,可以根据需要在标记的其他作用域部分中嵌套作用域样式,以便对样式的应用位置进行精细控制。

使用场景

这有什么用?

一个常见的用例是联合发布的内容:当您(作为 Web 作者)想要纳入第三方内容(包括其所有样式),但又不想冒这些样式“污染”网页中其他不相关部分的风险时。这样做的一大优势是,您可以将来自其他网站(例如 yelp、twitter、ebay 等)的内容合并到单个网页中,而无需使用 <iframe> 将它们隔离或动态修改外部内容。

如果您使用的内容管理系统 (CMS) 会向您发送标记代码段,这些代码段会混合在一起显示在最终网页中,那么此功能非常适合确保每个代码段的样式与网页上的任何其他内容分开。这对维基也是同样有用。

当您想在网页上编写一些漂亮的演示版代码时,可以轻松将样式限制为仅适用于演示版内容。这样,您就可以在演示版中尽情使用 CSS,而页面上的其他内容都不会受到影响。

另一种用例是简单封装:例如,如果您的网页有侧边菜单,则可以将特定于该菜单的样式放入标记的该部分的 <style scoped> 部分。在渲染页面的其他部分时,这些样式规则不会产生任何影响,这使得它们与主要内容很好地分隔开来!

最具吸引力的用例之一可能是网站组件模型。Web 组件将成为构建滑块、菜单、日期选择器、标签页微件等内容的绝佳方式。通过提供作用域限定的样式,设计师可以构建微件并将其与样式打包为一个自包含单元,供他人提取并组合到丰富的 Web 应用中。我们计划将 <style scoped> 与 Web 组件和 shadow DOM 搭配使用(您已经可以在 chrome://flags 中设置实验性“shadow DOM”标志来启用 shadow DOM)。目前,没有任何真正有效的方法可以确保样式仅限于 Web 组件,而无需诉诸内嵌样式等不良做法,因此作用域限定的样式非常适合此用途。

为什么要添加父元素?

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

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

这模拟了实现“scoped”时使用样式的效果,但由于选择器更复杂,因此会导致一些运行时性能开销。这种方法的好处在于,在 <style scoped> 获得广泛支持且 ID 选择器可以直接舍弃之前,它可以提供一种妥善的回退方法。

状态

由于作用域限定的样式表的实现仍处于新阶段,因此它们目前在 Chrome 中隐藏在一个运行时标志后面。如需启用这些功能,您需要使用版本号为 19 或更高版本的 Chrome(目前是 Chrome Canary),然后在 chrome://flags 中找到“启用 <style scoped>”(位于底部),点击“启用”,然后重启浏览器。

目前没有已知 bug,但 @global 以及 @keyframes@-webkit-region 的限定版本仍在实现中。此外,由于规范很可能会发生变化,因此目前会忽略 @font-face

我们诚邀对此功能感兴趣的所有用户试用该功能,并告诉我们您的体验:优点、缺点以及(可能存在的)bug。