在<body>中使用<style>标签和其他HTML

Gag*_*gan 183 html css

<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>
Run Code Online (Sandbox Code Playgroud)

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

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

Cha*_*via 303

正如其他人已经提到的,HTML 4要求将<style>标记放在该<head>部分中(即使大多数浏览器允许其中的<style>标记body).

但是,HTML 5包含scoped属性(请参阅下面的更新),该属性允许您创建范围在<style>标记的父元素中的样式表.这也使您可以<style><body>元素中放置标记:

<!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>
Run Code Online (Sandbox Code Playgroud)

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

只有一个重要的警告......

在我写这个答案时(2013年5月),几乎没有主流浏览器目前支持该scoped属性.(虽然显然Chromium的开发人员版本支持它.)

但是,scoped该问题属于一个有趣的含义.这意味着未来的浏览器通过标准强制要求允许<style>元素<body>(只要<style>元素具有范围).

所以,鉴于:

  • 几乎每个现有浏览器当前都忽略该scoped属性
  • 几乎每个现有的浏览器目前都允许使用<style>标签<body>
  • 未来的实现将需要允许(范围)<style>标签<body>

......再有就是字面上没有害处在将*<style>身体内的标签,只要你面向未来他们有scoped属性.唯一的问题是当前的浏览器实际上不会限制样式表的范围 - 它们会将它应用于整个文档.但重点是,出于所有实际目的,您可以<style><body>提供的内容中包含标签:

  • 通过包含scoped属性,为HTML提供面向未来的证明
  • 了解到目前为止,其中的样式表<body>实际上并不是作用域的(因为还没有主流浏览器支持)


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


最后,对于常见的(但主观)声称嵌入HTML中的CSS的不良做法,应该指出的是,整点的的scoped属性,以适应典型的现代开发框架,使开发人员可以导入HTML的块为模块或联合内容.嵌入式CSS 适用于特定的HTML块非常方便,以便开发具有特定样式的封装模块化组件.


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

  • 支持@KiranSubbaraman:我刚刚(2016年7月)阅读了关于mozilla开发的内容:*"仅在Chrome和Firefox进行了有限的实验性采用后,**范围属性已从规范**中删除.**您应该避免使用它**,因为它几乎肯定会很快被删除."*>> https://developer.mozilla.org/en-US/docs/Web/HTML/Element/style#A_scoped_stylesheet (50认同)
  • `scoped`属性已从当前的HTML5规范中删除. (8认同)
  • 支持`@scoped`或`scoped`似乎正在消亡:[这里](https://github.com/whatwg/html/issues/552)和[here](https://github.com/ W3C/csswg-汇票/问题/ 137) (5认同)
  • 截至今天,只有Firefox支持范围样式元素(根据http://caniuse.com/#feat=style-scoped).而且由于常见的浏览器只支持BODY中的STYLE元素,我会在必要时使用它.如果CSS应该在作用域中应用,则可以使用包装器的ID /类为CSS源中的每个选择器添加前缀.我实际上是在一个Web应用程序中做到这一点,它在服务器端加载HTML报告并通过AJAX呈现它们.CSS可以在JavaScript中以简单的正则表达式作为前缀:cssString.replace(/(^ | \})([^ {] +)(\ {)/ g,'$ 1'+前缀+'$ 2 $ 3') (4认同)
  • @RobertMcKee:你真的测试了吗?我希望通常在渲染之前解析整个html页面(包括所有内联样式),因为通常它并不是很大并且浏览器在准确渲染之前等待(非常短),以避免可能发生的闪烁的无格式内容由于css链接在`head`.*如果*这是你唯一的css,**如果*页面很大而且*如果*网络连接不是很快,那么也许你会看到一些没有样式的内容,但它在大多数时候让我感到惊讶实际情况. (3认同)
  • @NickG因为几乎没有浏览器在开始渲染之前等待整个HTML文件.在使用它之前,您不需要完整地构建DOM树.你的两个陈述都是不正确的. (2认同)
  • 即使截至2017年10月3日,W3C推荐文档还指出,"样式元素仅限于出现在文档的头部." [参考文献](https://www.w3.org/TR/2017/REC-html51-20171003/document-metadata.html#the-style-element) (2认同)
  • 一个注释 - 虽然`scoped`已被删除,`<style>`在`<body>`中技术上无效,google.com,bing.com和support.apple.com都依赖于`<style>` `<BODY>`.我相信,假设嵌套将继续工作(没有范围界定)是非常安全的.希望最终,规范将更新以匹配. (2认同)
  • @TristanBerger这是什么意思 - google,bing和apple依赖于头脑中的风格?作为搜索引擎?用于渲染?你有这个来源吗?这似乎与我(公认的主观)经历不一致.最新的HTML5规范允许在体内使用`style`,它将其列为流内容和[element spec](https://www.w3.org/TR/html5/document-metadata.html#elementdef-style)状态`可以使用这个元素的上下文:在体内,预期流内容 (2认同)

Sz.*_*Sz. 52

耶,STYLE终于在有效的BODY,作为HTML5.2的! (也STYLE已经消失了.)

规格(津津乐道的最后一行!):

4.2.6.样式元素

...

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

预期元数据内容的位置.

在一个noscript元素中,它是head元素的子元素.

在体内,预计流量含量.

  • 我真的认为他们用这种废话跳了鲨鱼,如果你想在模板化系统中动态设置背景图像属性,他们基本上别无选择,只能在线条样式中使用。将以编程方式生成的样式块放在 html 输出上方的侵入性要小得多。 (4认同)
  • 我看了规格,但听不懂。您能否在可以验证的“ body”中提供“ style”块的示例代码? (3认同)
  • 不知怎的,我对此表示怀疑,例如 Emotion(React 中最流行的 CSS 框架,世界上最流行的 JS 框架)默认情况下会在 SSR 的正文中插入样式。幸运的是,谷歌和微软现在在浏览器上拥有相当的垄断地位,希望他们能够说服那些白痴,这是一件有用的事情(就像正在进行一场关于范围属性的争论,它的行为非常愚蠢,没有人同意) (3认同)
  • 所有这些关于标准的讨论都很有趣,但从 Web 开发的角​​度来看,除了您关心 W3C 验证器或其他验证器是否喜欢您的代码的程度之外,有点无关紧要。“现实世界”中重要的是浏览器如何呈现 HTML 和 CSS。而且我从未遇到过任何浏览器在正文中存在“&lt;style&gt;”元素问题,即使在据称不允许的 HTML 类型中也是如此。因此,即使它的形式很糟糕并且可能存在理论上的风险,但在实践中我从未见过它造成任何危害。 (3认同)
  • @FrankConijn:好点,事情变了,更新了答案!真是令人困惑。5.2和5.3 W3C规范都将“样式”视为元数据和流内容,但是最新的WHATWG“生存”规范却讲述了古老而乏味的“仅元数据”故事(仅在HEAD中允许使用)。而且,更糟的是,W3C验证程序似乎遵循WHATWG的风格。我还没有决定是笑还是哭,但我个人决定决定对“浏览器+ W3C-验证程序”案例“犯错”,并允许STYLE进入BODY。(顺便说一句,别忘了:_实际上我们应该成为标准的最终来源。) (2认同)
  • 幸运的是,浏览器似乎不太可能停止支持许多网站所依赖的功能。如果没有体内样式,在 CMS 或第三方插件中会很不方便。就个人而言,当务实时(当我无法轻松访问“&lt;head&gt;”时),我将继续使用此浏览器支持的功能,除非它开始损坏。 (2认同)

小智 28

当我看到大型网站内容管理系统经常将一些<style>元素(一些,而不是全部)放在靠近依赖这些类的内容时,我得出的结论是,这匹马不在谷仓里.

去看看来自cnn.com,nytimes.com,huffingtonpost.com,你最近的大城市报纸等的页面来源.所有这些都是这样做的.

如果有充分的理由在实体中的某处放置一个额外的<style>部分 - 例如,如果你实时包含()多样化和独立的页面元素,并且每个元素都有自己的嵌入式<style>,并且该组织将更清洁,更模块化,更易理解,更易于维护 - 我只想咬紧牙关.当然,如果我们可以拥有限制范围的"本地"样式(如局部变量),但是您可以使用您拥有的HTML,而不是您可能希望或希望稍后使用的HTML.

当然,正如其他人所阐述的那样,存在潜在的缺点和良好的(如果不总是令人信服的)理由遵循正统观念.但对我来说,它看起来越来越像在<body>中经常使用<style>已经成为主流.

  • 实用主义FTW! (3认同)
  • 你是对的。例如,我在插件中的 &lt;body&gt; 中使用了 &lt;style&gt; 标签。为什么,因为它是时尚插件内容的最简单方法。但是有一段时间,所有 css 类对于我的插件数据都是唯一的。 (2认同)

小智 8

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

我假设:

  1. 这些非程序员用户没有与系统管理员(或机构的 webdevs)的开放渠道,要求在系统的stylesheets. 实际上,考虑到他们将拥有的请求数量,这对于管理员(或网络开发人员)来说是不切实际的。
  2. 该系统是旧系统,仍然不支持较新版本的 HTML。

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


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

要求您的系统管理员在系统的stylesheets. 这将是一个外部或内部 CSS解决方案。如前所述,这可能是不可能的。


第二个选项:<link><body>

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

<link>元件可以在任一发生<head><body>元件,这取决于它是否有链路类型,它是身体-OK。例如,stylesheet链接类型是 body-ok,因此<link rel="stylesheet">在 body 中是允许的。但是,这不是一个好的做法。将<link>元素与正文内容分开,将它们放在<head>.

其他一些,将其限制在该<head>部分,例如w3schools

注意:此元素仅出现在 head 部分,但它可以出现任意次数。

测试

我在这里测试了它(桌面环境,在浏览器上),它对我有用。创建一个文件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>
Run Code Online (Sandbox Code Playgroud)

然后在同一目录中的 CSS 文件名为bar.css

.test1 { 
    color: green;
};
Run Code Online (Sandbox Code Playgroud)

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


第三个选项:<style><body>

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


第 4、5、6 选项:JS 方式

Alert 这些与修改<head>页面元素有关。也许机构的系统管理员不会允许这样。因此,建议先征得他们的许可。

好的,假设授予权限,策略是访问<head>. 如何?JavaScript 方法。

第四选项:新<link><head>

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

要通过 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>
Run Code Online (Sandbox Code Playgroud)

里面的script标签:

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

然后在 CSS 文件中,在同一目录中,调用bar.css(如第二个选项):

.test1 { 
    color: green;
};
Run Code Online (Sandbox Code Playgroud)

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

5日选项:新<style><head>

在标签上使用新的内部样式表<head>,即在您有权访问的区域使用新<style>元素(即在网站上,不在标签内,是在标签内)。将创建一个新对象bodyheadStyle

这是通过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>
Run Code Online (Sandbox Code Playgroud)

里面的script标签:

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

第 6 个选项:使用现有<style><head>

在标签上使用现有的内部样式表<head>,即,在您有权访问的区域之外使用<style>元素(即,在站点上,不在标签内,是在标签内),如果存在的话。将创建一个新对象或使用一个对象(在此处采用的解决方案的代码中)。bodyheadStyleCSSStyleSheet

这在某些方面是有风险的。 首先,因为它可能不存在某个<style> 对象。根据您实施此解决方案的方式,您可能会得到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>
Run Code Online (Sandbox Code Playgroud)

里面的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
Run Code Online (Sandbox Code Playgroud)

该解决方案的另一种方法是使用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>
Run Code Online (Sandbox Code Playgroud)

严格回答加根提出的问题

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

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

(报价改编)

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

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


nic*_*ico 7

无效的HTML,无论如何几乎每个浏览器似乎只考虑第二个实例.

在Fedora下的FF和谷歌Chrome的最新版本以及XP下的FF,Opera,IE和Chrome下测试.


Jos*_*ola 6

<style>标签所属的<head>部分中,从所有的内容分开.

参考文献:W3C SpecsW3Schools

  • 不解决问题.那些僵硬的指导方针被现实所淹没.在许多情况下,作者无法在html头中定义/包含他们的样式. (49认同)
  • 这可能在2010年是正确的,但今天还远远不能接受。 (3认同)

Pek*_*ica 6

我想这会因浏览器而异:全局显示规则可能会随着浏览器在代码中的运行而更新.

有时在外部样式表加载延迟时,您可以在全局显示规则中看到此类更改.类似的东西可能会在这里发生,但是在如此短暂的连续中它实际上并没有被渲染.

无论如何它都不是有效的HTML,所以我想说这是一件无用的事情.<style>标签属于head页面的部分.


Not*_*tMe 5

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

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


dke*_*ner 5

浏览器真正做什么...

再次强调,这是一场理论与实践的争论。没有真正的赢家。
首先让我向您展示一个CodePen:

https://codepen.io/dkellner/pen/gOzXGjz?editors=1100

    CSS:

.jeff { background:red; transform:rotate(2deg); color:white; }
Run Code Online (Sandbox Code Playgroud)

HTML:

<style> .jeff { margin:20% 0 0 20%; width:400px; } </style>
<div class="jeff">
  
    This is Jeff.

    <style> .jeff {background:blue; padding:40px;} </style>
</div>

<style> .jeff {background:green} </style>
Run Code Online (Sandbox Code Playgroud)

解释

在这个例子中,我使用了 4 个不同样式的块。直接在 CodePen 的 CSS 框中,他们会把它放在一个不错的地方,可能在头部,无论如何。下一个位于div之前,然后是 div内部,最后一个位于div之后。杰夫现在正在经历很多事情。他是绿色的,因为这是最后一条规则告诉他的,但他也旋转和定位,并且里面的文本是白色的,所以我们可以有把握地说他已经阅读了样式标签告诉他的所有内容,并且:

  • 所有style块均已应用;
  • 它们以正确的顺序应用;
  • 他们适当地相互凌驾;
  • 整个事情就像一个大的样式表。

就是这样。

再说一遍,浏览器是有耐心的野兽。他们希望你享受互联网,而创建网站的人并没有很好的纪律,因此浏览器进化到容忍他们的疯狂行为。

底线

  1. 是的,您可以在正文中放置样式标签
  2. 是的,它按您的预期工作
  3. 尽可能避免,这是一个持续的争论,谁知道我们最终会在哪里。