HTML5 中样式元素的“作用域”属性的当前状态是啥?
Posted
技术标签:
【中文标题】HTML5 中样式元素的“作用域”属性的当前状态是啥?【英文标题】:What is the current state of the "scoped" attribute for the style element in HTML5?HTML5 中样式元素的“作用域”属性的当前状态是什么? 【发布时间】:2015-04-22 08:55:02 【问题描述】:这里说http://www.w3.org/TR/html-markup/style.html#style:
允许的父元素
任何可以包含元数据元素的元素,div,noscript, 部分,文章,旁边
<style>
在任何地方都或多或少被允许(允许<div>
的地方)
但是,另一方面,我在这里找到了更详细的信息http://www.w3.org/TR/2012/WD-html5-20121025/the-style-element.html#attr-style-scoped
可以使用该元素的上下文:(注解:style)
If the scoped attribute is absent: where metadata content is expected. If the scoped attribute is absent: in a noscript element that is a child of a head element. If the scoped attribute is present: where flow content is expected, but before any other flow content other than inter-element whitespace, and not as the child of an element whose content model is transparent.
以及本文档后面的内容:
作用域属性是一个布尔属性。如果存在,则表明 样式仅用于以样式为根的子树 元素的父元素,而不是整个 Document。
如果存在作用域属性并且元素有父元素 元素,那么样式元素必须是流内容的第一个节点 在其父元素中,而不是元素间空格,并且 父元素的内容模型不能有透明组件。
这读起来就像有(或将会有)“两个不同的<style>
元素”:一个
<style>
- 全局 - ~~仅在 <head>
内
<"scopestyle">
- 仅(!)具有布尔范围 attr 和 ~~仅在 <div>
的开头
(请把“~~”读成“或多或少”)
但是后面的链接已经超过 2 年了,所有浏览器(我测试过 Chrome、FF、IE、Opera)都将流入 <style>
解释为好像它在标题中一样。 (并忽略 AFAIK 的范围 - 是的 - 仍然没有标准)
所以我的三部分问题
我对 W3C 文档(两种风格 - 逻辑)的解释是否正确?
现在是什么状态 - 2015 年?
而且,可能有人在那里,谁知道即将发生的事情?
【问题讨论】:
如果你导航回w3.org/TR/html-markup,你会发现它已经过时了。由于某种奇怪的原因,通知没有出现在其他任何地方。scoped
属性将来可能会重新引入,请参阅:github.com/w3c/csswg-drafts/issues/3547。总之,有一个polyfill。
W3C Early design review of light-DOM CSS Scope proposal 和Proposal for light-dom scoping/namespacing with re-designed @scope
rule
【参考方案1】:
这里的许多答案已经有些过时了,所以这里简要总结一下 scoped
属性发生的事情。
最初(在 HTML5 之前),<style>
在 <head>
之外不是“有效的”,但大多数或所有浏览器都支持。 “无效”意味着验证器会抱怨它,并且规范(W3C 的 HTML 4 和 XHTML 1 系列)说不应该这样做。但它奏效了。有时这很糟糕:无论<style>
元素出现在文档中的哪个位置,它的规则都适用于整个文档(当然,基于使用的选择器)。这可能会导致作者编写“本地”样式表,该样式表仅适用于文档的某个区域,但可能会意外地重新设置其他区域的样式。
HTML5 的scoped
属性提议旨在解决这个问题:它会告诉浏览器该表单中的样式仅适用于<style>
的父元素及其后代。此外,在某些时候,<style scoped>
也被要求成为其父级的第一个子级,这使得任何阅读 HTML 代码的人都非常清楚范围是什么。不带属性的 style
元素仅在 <head>
元素内有效。
随着时间的推移,没有足够多的供应商实施新功能(Firefox 和 Chrome 包含一些实验性支持),因此最终放弃了。浏览器行为与 HTML 5 之前的行为保持一致,但当前规范至少记录了它:<style>
现在在整个文档中是合法/有效的,但规范警告潜在的副作用(意外地重新设置元素)。
根据当前规范和浏览器行为,实现“范围”样式的最佳和最安全的方法是在 ID 的帮助下明确地这样做,就像在这个 sn-p 中一样:
<div id="myDiv">
<style>
#myDiv p margin: 1em 0;
#myDiv em color: #900;
#myDiv whatever /* ... */
</style>
<p>Some content here... </p>
</div>
div
有一个id
属性,并且样式表中的所有规则都明确使用了一个 id 选择器来确保它们只适用于该 div。当然,这仍然需要避免跨文档的 id 冲突,但唯一性已经是 id
属性的要求。
虽然scoped
属性已被删除,但这种方法可以完成工作,具有合理的可读性(当然,就像任何代码一样,它可能会被混淆,但这不是重点),应该验证,并且应该可以很好地工作几乎所有与 CSS 兼容的浏览器。
PS:根据规范,<body>
内的<style>
应该验证。但是,Nu 验证器(标记为实验性)仍然抱怨它。有一个未解决的问题:https://github.com/validator/validator/issues/489
【讨论】:
【参考方案2】:您对规范的解释似乎是正确的。 MDN page on the style tag 包含scoped
属性的描述。
scoped 如果此属性存在,则样式仅适用于其父元素。如果不存在,则样式适用于整个文档。
scope
属性:
这是一个仅适用于 Firefox 21 到 54 的工作示例。
示例:
<div>
<p>Out of scope.</p>
<div>
<style scoped>
p
background: green;
</style>
<p>In scope (green background).</p>
</div>
<p>Out of scope.</p>
</div>
在不支持scoped
属性的浏览器中,这些样式会全局应用。
:scope
伪选择器:
除了scoped属性,还有the :scope
pseudo-selector可以使用。此实现提供与以前相同的支持。
示例:
<div>
<p>Outside scope.</p>
<div>
<style scoped>
:scope p
background: green;
</style>
<p>In scope (green background).</p>
</div>
<p>Outside scope.</p>
</div>
这个选项还增加了一个可能的好处,如果浏览器不理解scoped
属性,样式将不会被全局应用。唯一的问题是 Safari 7+ 将识别 :scope
伪选择器,即使 scoped
属性不受支持,因此在 Safari 7+ 中失去了优势。
全局样式:
和以前一样,使用不带scoped
属性的style
标记将创建全局样式,因此只有在包含scoped
属性时才会对其进行作用域。
兼容性总结:
此时,对该功能的支持看起来很黯淡。 CSS 范围仅在 Firefox 21 到 54 中受支持。目前任何主流浏览器、Firefox、Chrome、Internet Explorer、Safari 或 Opera 都不支持它。 According to caniuse.com,从 Chrome 20 到 36 可以使用实验标志启用支持,但 support was removed。
【讨论】:
现在任何浏览器都不支持它(2019 年 3 月)。 Shadow DOM 样式可能是此属性的继承者 - 不完全是,但沿袭相同的路线 @Drenai 是的,Firefox 也已将其删除。我已经更新了答案以说明这一点。【参考方案3】:“范围”属性似乎已从 HTML5 规范中完全删除。当前和之前的几个版本都没有提及。
【讨论】:
可悲的是......另请参阅:github.com/w3c/csswg-drafts/issues/137 此建议目前仍处于打开状态:github.com/w3c/csswg-drafts/issues/270 还有这个讨论:github.com/JSFoundation/standards/issues/47【参考方案4】:截至 2016 年 5 月,<style scoped>
已从 whatwg specification 中删除。
【讨论】:
【参考方案5】:2020 年更新
在当前的 VueJs 单文件组件中,有一个带有“范围”属性的样式部分,它在“编译”时动态转换 CSS 类,以便它们仅限于组件。
How to correctly use "scoped" styles in VueJS single file components?
就我个人而言,我喜欢这种方法,因为集中式 CSS 往往会变得陈旧和脆弱。新开发人员通常只是将新类添加到项目中,因为他们不想破坏现有设计。清理旧的 CSS 似乎从来没有出现在任何人的待办事项列表中......
【讨论】:
【参考方案6】:HTML5 的主要目标是正式指定浏览器基本上“永远”实现的行为,而不管以前的 HTML 规范如何。您始终可以在 HTML 文档中的任何位置使用 <style>
标记,因此使用 HTML5 您仍然可以。这不会改变。
如需更多信息,请参阅<style>
元素上当前 HTML5 规范部分的链接:
http://www.w3.org/html/wg/drafts/html/master/document-metadata.html#the-style-element
【讨论】:
以上是关于HTML5 中样式元素的“作用域”属性的当前状态是啥?的主要内容,如果未能解决你的问题,请参考以下文章
PrimeNG 元素没有作用域,不能使用默认的 Angular 2 ViewEncapsulation (Emulated) 设置样式