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

时间:2010-05-13 21:03:09

标签: 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>

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

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

11 个答案:

答案 0 :(得分:289)

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

但是,HTML 5包含scoped attribute(请参阅下面的更新),它允许您创建范围在<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>

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

只有一个 主要 警告......

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

但是,scoped属性有一个与此问题相关的有趣含义。这意味着未来的浏览器通过标准强制要求允许<style>中的<body>元素(只要<style>元素具有作用域。)

所以,鉴于:

  • 目前几乎所有现有浏览器都会忽略scoped属性
  • 目前几乎所有现有浏览器都允许<style>
  • 中的<body>个标签
  • <style>
  • 中允许(范围内的)<body>标记需要未来实施

...然后在将<style>标记置于正文中时,确实存在 无伤害 *,只要您将来使用{{ 1}}属性。唯一的问题是当前的浏览器实际上不会限制样式表的范围 - 它们会将它应用于整个文档。但问题是,出于所有实际目的,您可以scoped中包含<style>代码,前提是您:

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


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


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


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

答案 1 :(得分:45)

是的, STYLE终于在BODY中有效,自HTML5.2起!scoped也消失了。)

来自the specs津津乐道的最后一行!):

  

<强> 4.2.6。样式元素

     

...

     

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

     

预期元数据内容。

     

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

     

在正文中,预计会有流量内容。

答案 2 :(得分:26)

当我看到大型网站内容管理系统经常提出一些&lt; style&gt;元素(有些,不是全部)接近依赖于这些类的内容,我得出的结论是这匹马不在谷仓里。

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

如果有充分的理由增加额外的&lt; style&gt;在身体的某个部分 - 例如,如果你实时包含()各种独立的页面元素,并且每个元素都有一个嵌入的&lt; style&gt;它本身,组织将更清洁,更模块化,更易理解,更易于维护 - 我说只是咬紧牙关。当然,如果我们可以拥有限制范围的“本地”样式(如局部变量),那么你会更好地使用你拥有的HTML,而不是你以后想要或希望拥有的HTML。

当然,正如其他人所阐述的那样,有可能存在缺点和良好(如果不总是令人信服的)理由遵循正统观念。但对我来说,它看起来越来越像是对&lt; style&gt;的深思熟虑的使用。在&lt; body&gt;中已经成为主流。

答案 3 :(得分:8)

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

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

答案 4 :(得分:6)

<style>标记属于<head>部分,与所有内容分开。

参考文献:W3C SpecsW3Schools

答案 5 :(得分:6)

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

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

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

答案 6 :(得分:5)

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

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

答案 7 :(得分:3)

在您的示例中,浏览器不“应该”做任何事情。 HTML无效。触发错误恢复,或解析器按原样进行错误恢复。

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

答案 8 :(得分:1)

因为这是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>

我的猜测是浏览器会应用它遇到的最后一种风格。

答案 9 :(得分:0)

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

我想是这样的:

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

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


第一个选择:询问您的sysadm

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


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

body标记上使用外部样式表,即在您有权访问的区域 内使用link标记(这将在网站上位于body标记内,而不位于head标记内)。一些消息来源说这还可以,但是“ {@ 3}}这样的做法不是很好”:

  

<link>元素可以出现在<head><body>元素中,具体取决于其链接类型是否为 body-ok 。例如,stylesheet链接类型为body-ok,因此<link rel="stylesheet">被允许在body中使用。但是,这不是遵循的好习惯。将您的<link>元素与身体内容分开,将其放入<head>中是更有意义的。

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

  

注意:该元素仅出现在头部,但可以出现多次。

测试

我在这里(台式机环境,在浏览器上)对其进行了测试,并且对我有用。 创建文件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文件,那么这似乎才有可能。也许是这种情况。


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

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


第四,第五和第六选项:JS方式

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

好的,假设已授予许可,则该策略是访问<head>。怎么样? JavaScript方法。

第四个选项:<link>上的新<head>

这是第二个选项的另一个版本。在<head>标签上使用外部样式表,即在您有权访问的区域 之外使用<link>元素(即网站,不在body标签内,而在head标签内)。此解决方案符合上面提到的第二选项解决方案的 MDN w3schools 的建议。将创建一个新的w3schools

要通过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文件,那么这才有可能。

第五个选项:<style>上的新<head>

<head>标签上使用新的内部样式表,即,在您有权访问的区域 之外使用新的<style>元素( (在网站上,不在body标记内,而在head标记内)。将创建一个新的Link 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);

第六个选择:在<style>上使用现有的<head>

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

从某种角度上讲这是有风险的。 第一,因为它可能不存在某些<style>对象。根据实现此解决方案的方式,您可能会获得undefined的回报(系统可能使用外部样式表)。 第二,因为您将编辑系统设计作者的作品(作者问题)。 第三,因为您所在机构的IT安全政策可能不允许这样做。 因此,一定要征得许可才能这样做(与其他JS解决方案一样)。

再次假设已授予权限:

您将需要考虑对这种方法可用的一些限制:CSSStyleSheet object。提出的解决方案使用默认方案,如果存在的话,则在第一个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对象(位于insertRule()w3schools的文档)。但是,考虑到覆盖系统CSS上现有规则的风险,这可能并不有趣。


第7个选项:内联CSS

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

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

测试

创建文件_foobar.html

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

严格回答加根提出的问题

  

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

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

(引用改编)

为获得更准确的答案,我建议Google推荐以下文章:

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

答案 10 :(得分:0)

是的。我检查了Mozzila的页面。  https://developer.mozilla.org/en-US/docs/Web/HTML/Element/style