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:根据规范,&lt;body&gt; 内的&lt;style&gt; 应该验证。但是,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 月,&lt;style scoped&gt; 已从 whatwg specification 中删除。

【讨论】:

【参考方案5】:

2020 年更新

在当前的 VueJs 单文件组件中,有一个带有“范围”属性的样式部分,它在“编译”时动态转换 CSS 类,以便它们仅限于组件。

How to correctly use "scoped" styles in VueJS single file components?

就我个人而言,我喜欢这种方法,因为集中式 CSS 往往会变得陈旧和脆弱。新开发人员通常只是将新类添加到项目中,因为他们不想破坏现有设计。清理旧的 CSS 似乎从来没有出现在任何人的待办事项列表中......

【讨论】:

【参考方案6】:

HTML5 的主要目标是正式指定浏览器基本上“永远”实现的行为,而不管以前的 HTML 规范如何。您始终可以在 HTML 文档中的任何位置使用 &lt;style&gt; 标记,因此使用 HTML5 您仍然可以。这不会改变。

如需更多信息,请参阅&lt;style&gt; 元素上当前 HTML5 规范部分的链接:

http://www.w3.org/html/wg/drafts/html/master/document-metadata.html#the-style-element

【讨论】:

以上是关于HTML5 中样式元素的“作用域”属性的当前状态是啥?的主要内容,如果未能解决你的问题,请参考以下文章

PrimeNG 元素没有作用域,不能使用默认的 Angular 2 ViewEncapsulation (Emulated) 设置样式

Vue3样式引入和使用

html5新增的全局属性有哪几个?描述其主要功能。

认识CSS3特性之过渡

伪类与伪元素的区别

vue 中 style 标签中的 scoped 属性(作用域)和 lang 属性的介绍