【问题标题】:Using <style> tags in the <body> with other HTML将 <body> 中的 <style> 标记与其他 HTML 一起使用
【发布时间】:2011-02-19 07:01:57
【问题描述】:
<html>
  <body>
    <style type="text/css">
      p.first {color:blue}
      p.second {color:green}
    </style>

    <p class="first">Hello World</p>
    <p class="second">Hello World</p>

    <style type="text/css">
      p.first {color:green}
      p.second {color:blue}
    </style>

    <p class="first">Hello World</p>
    <p class="second">Hello World</p>
  </body>
</html>

浏览器应该如何呈现非连续的 css?是否应该使用页面上的所有 css 样式生成一些数据结构并将其用于渲染?

或者它是否按照看到的顺序使用样式信息进行渲染?

【问题讨论】:

  • 我会说这是未定义的行为,因为它不是有效的 HTML。有关哪些元素有效哪些无效的更多信息:en.wikipedia.org/wiki/HTML_element
  • 抛开这个问题不谈,将CSSHTML 混用是一种不好的做法。
  • @0x2D9A3 不一定正确。请求外部 CSS 页面比&lt;head&gt; 标签中定义的 CSS 花费更长的时间
  • @KolobCanyon 同意,但作为一般规则,CSS 应该在单独的文件中。如果你有大量的 CSS,它更容易管理(维护、(后)处理、缩小、捆绑)并作为单独的文件提供,并且你的内容 (HTML)可能加载得更快,也可以带来更好的用户体验。但是,与开发一样,一切都是特定于上下文的,所以 YMMW :)
  • @KolobCanyon,这不是 CSS 是否应该在单独的文件中的问题。在这种情况下,问题是关于 &lt;body&gt; 而不是 &lt;head&gt; 中的 CSS。

标签: html css


【解决方案1】:

是的,它可以。我查看了 Mozilla 的页面。 https://developer.mozilla.org/en-US/docs/Web/HTML/Element/style

【讨论】:

  • 从您链接的页面更新:“
【解决方案2】:

坏消息“体型”爱好者:W3C 最近lost the HTML war 反对 WHATWG,其无版本 HTML“生活标准”has now become 是官方的,唉,@987654323 @STYLEBODY。短暂的快乐日子已经过去了。 ;) W3C validator 现在也适用于 WHATWG 规范。 (感谢@FrankConijn 的提醒!)

(注意:这是“从今天开始”的情况,但由于没有版本控制,链接可能随时变为无效,无需通知或控制。除非您愿意链接到其各个源提交GitHub,你基本上不能再稳定引用新的官方HTML standard,AFAIK。如果有正确的规范方法,请纠正我。)

过时的好消息:

是的,STYLE 终于在BODY 中有效,从 HTML5.2 开始!scoped 也不见了。)

来自the W3C specs最后一行!):

4.2.6。样式元素

...

可以使用此元素的上下文:

需要元数据内容的地方。

在作为 head 元素的子元素的 noscript 元素中。

在正文中,需要流动的内容。


元旁注:

尽管“浏览器战争”造成了损失,但我们仍然不得不针对两个ridiculously competing“官方”HTML“标准”(1 standard + 1 standard &lt; 1 standard 的引用)继续开发这一事实,这意味着“回退到-trenches 常识”的 Web 开发方法从未真正停止应用。

现在这可能最终会改变,但引用传统观点:网络作者/开发人员,因此,浏览器最终应该决定规范中应该(和不应该)的内容,当没有充分的理由反对已经存在的内容时在现实中已经完成。大多数浏览器长期以来一直支持STYLE in BODY(以一种或另一种方式;参见例如scoped attr.),尽管它固有的性能(可能还有其他)惩罚(我们应该决定是否支付,而不是规格。)。所以,一方面,我会继续押注他们,不会放弃希望。 ;) 如果 WHATWG 像他们声称的那样尊重现实/作者,他们最终可能会在这里做 W3C 所做的事情。

【讨论】:

  • 我阅读了规范,但不明白。您能否在验证的body 中给出style 块的示例代码?
  • @FrankConijn:好点,事情发生了变化,更新了答案!这真的很混乱。 5.2 和 5.3 W3C 规范都将STYLE 视为元数据和流内容,但最新的 WHATWG“活”规范讲述了旧的、无聊的“仅元数据”故事(仅允许在 HEAD 中使用)。而且,雪上加霜的是,W3C 验证器似乎遵循 WHATWG 风格。我还没有决定是笑还是哭,但我个人确实决定在“浏览器 + W3C - 验证器”案例中“犯错”,并允许 STYLE 出现在 BODY 中。 (顺便说一句,不要忘记:我们应该是标准的最终来源,实际上。)
  • 我真的认为他们用这个废话跳了鲨鱼,如果你想在模板系统中动态设置背景图像属性,他们基本上别无选择,只能使用线条样式。在您的 html 输出上方放置一个以编程方式生成的样式块的侵入性要小得多。
  • 幸运的是,浏览器似乎不太可能停止支持许多网站所依赖的功能。在 CMS 或第三方插件中,如果没有 in-body 样式会很不方便。就个人而言,如果务实(当我无法轻松访问 &lt;head&gt; 时),我会继续使用此浏览器支持的功能,除非它开始崩溃。
  • 不知何故我对此表示怀疑,例如 Emotion(React 最流行的 CSS 框架,世界上最流行的 JS 框架)默认为 SSR 在正文中插入样式。幸运的是,谷歌和微软现在在浏览器上拥有相当的垄断地位,希望他们能说服那些白痴这是一个有用的东西(就像关于范围属性的争论一样,它的行为非常愚蠢,没有人同意)
【解决方案3】:

我想这可能是关于有限上下文的问题,例如非程序员用户使用的网络系统上的 WYIWYG 编辑器,这限制了遵循标准的可能性。有时(如 TinyMCE),它是一个将您的内容/代码放入 textarea 标记的库,由编辑器呈现为大的 div 标记。有时,它可能是这些编辑器的旧版本。

我假设:

  1. 这些非程序员用户没有与系统管理员(或机构的 webdevs)开放的渠道,要求在系统的stylesheets 中包含一些 CSS 规则。实际上,考虑到他们会收到的请求数量,这对于管理员(或 Web 开发人员)来说是不切实际的。
  2. 此系统是旧系统,仍不支持较新版本的 HTML。

在某些情况下,不使用style 规则,可能是非常糟糕的设计体验。所以,是的,这些用户需要定制。好的,但是在这种情况下,解决方案是什么?考虑到在html 页面中插入 CSS 的不同方法,我想这些解决方案:


第一个选项:询问您的系统管理员

请您的系统管理员在系统的stylesheets 中包含一些 CSS 规则。这将是一个外部或内部 CSS 解决方案。如前所述,这可能是不可能的。


第二个选项:&lt;link&gt; on &lt;body&gt;

body 标签上使用外部样式表,即在您有权访问的区域内部使用link 标签(即,在网站,在body 标签内,而不是在head 标签内)。一些消息来源说这没问题,但“不是一个好习惯”,例如MDN

&lt;link&gt; 元素可以出现在&lt;head&gt;&lt;body&gt; 元素中,具体取决于它是否具有body-ok 链接类型。例如,stylesheet 链接类型为 body-ok,因此在 body 中允许 &lt;link rel="stylesheet"&gt;。但是,这不是一个好习惯。将&lt;link&gt; 元素与正文内容分开,将它们放在&lt;head&gt; 中会更有意义。

其他一些,将其限制在 &lt;head&gt; 部分,例如 w3schools

注意:这个元素只出现在头部,但它可以出现任意次数。

测试

我在这里测试了它(桌面环境,在浏览器上),它对我有用。 创建文件foo.html

<!DOCTYPE html>
<html>
<head></head>
<body>
    <link href="bar.css" type="text/css" rel="stylesheet">
    <h1 class="test1">Hello</h1>
    <h1 class="test2">World</h1>
</body>
</html>

然后是一个 CSS 文件,在同一目录下,名为 bar.css

.test1 { 
    color: green;
};

好吧,如果您知道如何在机构系统的某处上传 CSS 文件,这看起来是可能的。也许会是这样。


第三个选项:&lt;style&gt; on &lt;body&gt;

body 标签上使用internet 样式表,即在您有权访问的区域内使用style 标签(即在网站上的body 内)标记而不是在head 标记中)。这就是 Charles SalviaSz 的答案。选择此选项,请考虑他们的顾虑。


第四、五、六选项:JS方式

警报 这些与修改页面的&lt;head&gt; 元素有关。也许这不会被机构的系统管理员允许。所以,建议先征得他们的同意。

好的,假设授予权限,策略是访问&lt;head&gt;。如何? JavaScript 方法。

第四个选项:&lt;head&gt; 上的新 &lt;link&gt;

这是第二个选项的另一个版本。在&lt;head&gt; 标记上使用外部样式表,即在您有权访问的区域外部 使用&lt;link&gt; 元素(这将在网站上,而不是在body 标签内,是在head 标签内)。如上所述,该解决方案符合 MDNw3schools 对第二个选项解决方案的建议。将创建一个新的Link object

通过 JS 解决问题,有很多方法,但在下面的代码行中,我演示了一种简单的方法。

测试

我在这里测试了它(桌面环境,在浏览器上),它对我有用。 创建文件f.html

<!DOCTYPE html>
<html>
<head></head>
<body>
    <h1 class="test1">Hello</h1>
    <h1 class="test2">World</h1>
    <script>
        // JS code here
    </script>
</body>
</html>

script 标签内:

var newLink = document.createElement("link");
newLink.href = "bar.css";
newLink.rel = "stylesheet";
newLink.type = "text/css";
document.getElementsByTagName("head")[0].appendChild(newLink);

然后在 CSS 文件中,在同一目录中,名为 bar.css(与第二个选项相同):

.test1 { 
    color: green;
};

正如我已经说过的:如果您知道如何在机构系统的某处上传 CSS 文件,这看起来是可能的。

第 5 个选项:&lt;head&gt; 上的新 &lt;style&gt;

&lt;head&gt; 标记上使用新的内部样式表,即在您有权访问的区域外部使用新的&lt;style&gt; 元素(即,在网站上,不在body 标签内,是在head 标签内)。将创建一个新的Style object

这是通过JS解决的。下面演示了一种简单的方法。

测试

我在这里测试了它(桌面环境,在浏览器上),它对我有用。 创建文件foobar.html

<!DOCTYPE html>
<html>
<head></head>
<body>
    <h1 class="test1">Hello</h1>
    <h1 class="test2">World</h1>
    <script>
        // JS code here
    </script>
</body>
</html>

script 标签内:

var newStyle = document.createElement("style");
newStyle.innerHTML = 
    "h1.test1 {"+
        "color: green;"+
    "}";
document.getElementsByTagName("head")[0].appendChild(newStyle);

第 6 个选项:在 &lt;head&gt; 上使用现有的 &lt;style&gt;

&lt;head&gt; 标记上使用现有的内部样式表,即在您有权访问的区域外部使用&lt;style&gt; 元素(即,在网站上,不在body 标签内,是在head 标签内),如果有的话。将创建一个新的Style 对象或使用CSSStyleSheet object(在此处采用的解决方案的代码中)。

从某种角度来看,这是有风险的。 首先,因为它可能不存在某些&lt;style&gt; 对象。根据您实施此解决方案的方式,您可能会得到undefined 返回(系统可能使用外部样式表)。 第二,因为您将编辑系统设计作者的作品(作者身份问题)。 第三,因为您所在机构的 IT 安全政策可能不允许这样做。 所以,请务必获得许可(就像在其他 JS 解决方案中一样)

假设再次授予权限:

您需要考虑对这种方式可用的方法的一些限制:insertRule()。建议的解决方案使用默认方案,并在第一个stylesheet 处进行操作(如果存在)。

测试

我在这里测试了它(桌面环境,在浏览器上),它对我有用。 创建文件foo_bar.html

<!DOCTYPE html>
<html>
  <head></head>
  <body>
    <h1 class="test1">Hello</h1>
    <h1 class="test2">World</h1>
    <script>
      // JS code here
    </script>
  </body>
</html>

script 标签内:

function demoLoop(){ // remove this line
    var elmnt = document.getElementsByTagName("style");
    if (elmnt.length === 0) {
        // there isn't style objects, so it's more interesting create one
        var newStyle = document.createElement("style");
        newStyle.innerHTML =
            "h1.test1 {" +
                "color: green;" +
            "}";
        document.getElementsByTagName("head")[0].appendChild(newStyle);
    } else {
        // Using CSSStyleSheet interface
        var firstCSS = document.styleSheets[0];
        firstCSS.insertRule("h1.test2{color:blue;}"); // at this way (without index specified), will be like an Array unshift() method
    }
} // remove this too
demoLoop(); // remove this too
demoLoop(); // remove this too

此解决方案的另一种方法是使用 CSSStyleDeclaration 对象(w3schoolsMDN 的文档)。但考虑到覆盖系统 CSS 上现有规则的风险,这可能并不有趣。


第 7 个选项:内联 CSS

使用内联 CSS。这解决了问题,尽管取决于页面大小(以代码行为单位),代码的维护(由作者本人或其他指定人员)可能非常困难。

但根据您在机构中的角色背景或其网络系统安全政策,这可能是您唯一可用的解决方案。

测试

创建文件_foobar.html:

<!DOCTYPE html>
<html>
  <head></head>
  <body>
    <h1 style="color: green;">Hello</h1>
    <h1 style="color: blue;">World</h1>    
  </body>
</html>

严格回答 Gagan 提出的问题

浏览器应该如何呈现不连续的 css?

  1. 是否应该使用页面上的所有 css 样式生成一些数据结构并将其用于渲染?
  2. 还是按照它看到的顺序使用样式信息进行渲染?

(引用改编)

为了更准确的答案,我建议谷歌这些文章:

  • 浏览器的工作原理:现代网络浏览器的幕后花絮
  • 渲染树构造、布局和绘制
  • “呈现”网页是什么意思?
  • 浏览器渲染的工作原理 — 幕后
  • 呈现 - HTML 标准
  • 10 渲染——HTML5

【讨论】:

  • +1 好主意,包括脚本标签和使用 javascript 添加 css,对于愚蠢的 WYSIWYG CMS 编辑器来说是完全合法的 HTML
【解决方案4】:

正如其他人已经提到的,HTML 4 要求将&lt;style&gt; 标记放在&lt;head&gt; 部分(尽管大多数浏览器允许&lt;style&gt; 标记在body 中)。

但是,HTML 5 包含 scoped attribute(请参阅下面的更新),它允许您创建在 &lt;style&gt; 标记的父元素范围内的样式表。这也使您可以将&lt;style&gt; 标签放在&lt;body&gt; 元素中:

<!DOCTYPE html>
<html>
<head></head>
<body>

<div id="scoped-content">
    <style type="text/css" scoped>
        h1 { color: red; } 
    </style>

    <h1>Hello</h1>
</div>

    <h1>
      World
    </h1>

</body>
</html>

如果您在支持scoped 的支持HTML-5 的浏览器中呈现上述代码,您将看到样式表的范围有限。

只有一个主要警告...

在我写这个答案的时候(2013 年 5 月),目前几乎没有主流浏览器支持 scoped 属性。 (虽然显然developer builds of Chromium 支持它。)

但是,与此问题有关的 scoped 属性有一个有趣的含义。这意味着未来的浏览器通过标准强制要求在&lt;body&gt; 中允许&lt;style&gt; 元素(只要&lt;style&gt; 元素在范围内。)

所以,鉴于:

  • 目前几乎所有现有浏览器都会忽略scoped 属性
  • 目前几乎所有现有浏览器都允许在&lt;body&gt; 中添加&lt;style&gt; 标签
  • 未来的实现将需要在&lt;body&gt; 中允许(范围)&lt;style&gt; 标签

...那么在正文中放置&lt;style&gt; 标签实际上是没有害处 *,只要您将来用scoped 属性证明它们.唯一的问题是当前的浏览器实际上不会限制样式表的范围 - 他们会将其应用于整个文档。但关键是,出于所有实际目的,您可以&lt;body&gt; 中包含&lt;style&gt; 标签,前提是您:

  • 通过包含scoped 属性使您的 HTML 面向未来
  • 请理解,截至目前,&lt;body&gt; 中的样式表实际上不会被限定范围(因为尚不存在主流浏览器支持)


* 当然,除了惹恼 HTML 验证器...


最后,关于在 HTML 中嵌入 CSS 的普遍(但主观)说法是不好的做法,应该注意的是,scoped 属性的全部意义是为了适应典型的现代开发框架允许开发人员将 HTML 块导入为模块或联合内容。嵌入的 CSS 应用于特定的 HTML 块非常方便,以便开发具有特定样式的封装模块化组件。


自 2019 年 2 月起更新,根据 Mozilla documentationscoped 属性已被弃用。 Chrome 在版本 36 (2014) 和 Firefox 版本 62 (2018) 中停止支持它。在这两种情况下,用户都必须在浏览器的设置中明确启用该功能。没有其他主流浏览器支持它。

【讨论】:

  • @RobertMcKee:你真的测试过吗?我希望通常在渲染之前解析整个 html 页面(包括所有内联样式),因为通常它不是很大并且浏览器在精确渲染之前等待(非常短)以避免可能发生的无样式内容的闪烁由于 head 中链接的 css。 如果这是你唯一的css,并且如果页面很大并且如果网络连接不是很快,那么也许你会看到一闪而过的无样式内容,但在大多数实际情况下会让我感到惊讶。
  • 到目前为止,只有 Firefox 支持作用域样式元素(根据caniuse.com/#feat=style-scoped)。由于普通浏览器只支持 BODY 中的 STYLE 元素,如果有必要我会使用它。如果 CSS 应该应用在一个范围内,您可以在 CSS 源代码中的每个选择器前面加上包装器的 ID/类。我实际上是在一个加载 HTML 报告服务器端并通过 AJAX 呈现它们的 Web 应用程序中做到这一点的。然后可以在 JavaScript 中为 CSS 加上简单的正则表达式: cssString.replace(/(^|\})([^{]+)(\{)/g, '$1' + prefix + '$2$3')跨度>
  • @scopedscoped 的支持似乎正在消失:herehere
  • 支持@KiranSubbaraman:我刚刚(2016 年 7 月)在 mozilla dev 上阅读:scoped 属性已从规范中删除,仅在有限和实验性之后被 Chrome 和 Firefox 采用。您应该避免使用它,因为它几乎肯定会很快从这些浏览器中删除。" >> developer.mozilla.org/en-US/docs/Web/HTML/Element/…
  • scoped 属性已从当前的 HTML5 规范中删除。
【解决方案5】:

&lt;style&gt; 标签属于&lt;head&gt; 部分,与所有内容分开。

参考:W3C SpecsW3Schools

【讨论】:

  • 不解决问题。那些僵硬的指导方针被现实超越了。在许多情况下,作者无法在 html 头部定义/包含他们的样式。
  • 这在 2010 年可能是正确的,但今天还远不是一个可以接受的答案。
【解决方案6】:

当我看到大型站点内容管理系统经常将一些

查看来自 cnn.com、nytimes.com、huffingtonpost.com、离您最近的大城市报纸等的页面来源。他们都这样做。

如果有充分的理由在正文的某处放置一个额外的

当然,正如其他人所阐述的那样,遵循正统观念有潜在的缺点和好的(如果不总是令人信服的)理由。但在我看来,在

中深思熟虑地使用

【讨论】:

  • 实用主义FTW!
  • 是的,你是对的。例如,我在插件内的 中使用
【解决方案7】:

因为这是 HTML 无效,对结果没有任何影响……这只是意味着 HTML 确实符合标准(仅出于组织目的)。为了有效起见,它可以这样写:

<html>
<head>
<style type="text/css">
  p.first {color:blue}
  p.second {color:green}
</style>
</head>
<body>
<p class="first" style="color:green;">Hello World</p>
<p class="second" style="color:blue;">Hello World</p>

我的猜测是浏览器会应用它遇到的最后一个样式。

【讨论】:

    【解决方案8】:

    不是有效的 HTML,无论如何几乎每个浏览器似乎都只考虑第二个实例。

    在 Fedora 下的 FF 和 Google Chrome 的最新版本以及 XP 下的 FF、Opera、IE 和 Chrome 下测试。

    【讨论】:

      【解决方案9】:

      正如其他人所说,这不是有效的 html,因为样式标签属于头部。

      但是,大多数浏览器并没有真正强制执行该验证。相反,一旦加载了文档,就会合并并应用样式。在这种情况下,第二组样式将始终覆盖第一组,因为它们是最后遇到的定义。

      【讨论】:

        【解决方案10】:

        在您的示例中,浏览器“不应该”做任何事情。 HTML 无效。要么触发错误恢复,要么解析器按照自己的意愿进行处理。

        在一个有效的实例中,多个样式表被视为一个接一个出现,cascade 被正常计算。

        【讨论】:

          【解决方案11】:

          我想这会因浏览器而异:全局显示规则可能会随着浏览器执行代码而更新。

          您有时会在延迟加载外部样式表时看到全局显示规则中的此类更改。这里可能会发生类似的事情,但时间很短,实际上并没有被渲染。

          无论如何它都不是有效的 HTML,所以我想说这是徒劳的事情。 &lt;style&gt; 标签属于页面的head 部分。

          【讨论】:

            猜你喜欢
            • 2018-06-23
            • 1970-01-01
            • 2019-06-15
            • 2020-08-01
            • 1970-01-01
            • 2021-07-26
            • 2017-07-24
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多