<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样式,并使用它进行渲染?

还是按照看到的顺序使用样式信息进行渲染?


当前回答

对于“体内风格”爱好者来说,有一个坏消息:W3C最近在与WHATWG的HTML战争中失败了,WHATWG的无版本HTML“生活标准”现在已经成为官方标准,唉,它不允许体内风格。短暂的快乐时光一去不复返。,)W3C验证器现在也根据WHATWG规范工作。(谢谢@FrankConijn的提醒!)

(注意:这是“今天”的情况,但由于没有版本控制,链接可能在任何时候无效,而不通知或控制。除非你愿意链接到它在GitHub上提交的单个源代码,否则你基本上不能再稳定地引用新的官方HTML标准AFAIK。请纠正我,如果有一个规范的方法来正确地做这件事。)

过时的好消息:

耶,STYLE终于在BODY中生效了,从HTML5.2开始! (scoped也消失了。)

来自W3C规范(注意最后一行!):

4.2.6. 风格元素 ... 可以使用此元素的上下文: 需要元数据内容的地方。 在noscript元素中,它是head元素的子元素。 在正文中,期望流内容的地方。


元附注:

尽管遭受了“浏览器战争”的破坏,但我们仍然必须继续针对两个相互竞争的“官方”HTML“标准”(1个标准+ 1个标准< 1个标准)进行开发,这意味着“退回到战壕常识”的web开发方法从未真正停止应用。

This may finally change now, but citing the conventional wisdom: web authors/developers and thus, in turn, browsers should ultimately decide what should (and shouldn't) be in the specifications, when there's no good reason against what's already been done in reality. And most browsers have long supported STYLE in BODY (in one way or another; see e.g. the scoped attr.), despite its inherent performance (and possibly other) penalties (which we should decide to pay or not, not the specs.). So, for one, I'll keep betting on them, and not going to give up hope. ;) If WHATWG has the same respect for reality/authors as they claim, they may just end up doing here what the W3C did.

其他回答

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

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

不是有效的HTML,反正几乎每个浏览器都只考虑第二个实例。

在Fedora下测试FF和谷歌Chrome的最新版本,在XP下测试FF、Opera、IE和Chrome。

警告:这个答案指的是样式标签上的scoped属性,不应该再使用!

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

然而,HTML 5包含scoped属性(参见下面的更新),它允许您在<style>标记的父元素中创建范围内的样式表。这也允许你在<body>元素中放置<style>标签:

<!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>

如果您在支持限定作用域的HTML-5浏览器中呈现上述代码,您将看到样式表的限定作用域。

这里有一个重要的警告……

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

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

因此,考虑到:

目前几乎所有现有的浏览器都忽略了scoped属性 几乎所有现有的浏览器目前都允许<style>标签在<body>中 未来的实现将需要在<body>中允许(scoped) <style>标记

...那么在主体中放置<style>标记实际上没有什么害处,只要您将来使用一个作用域属性来证明它们。唯一的问题是,当前的浏览器实际上并没有限制样式表的作用域——它们将它应用于整个文档。但关键是,出于所有实际目的,你可以在<body>中包含<style>标签,前提是你:

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


* except of course, for pissing off HTML validators...

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


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

网站Can I Use报告称,自2016年以来,“属性已从当前规范中删除”。

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

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

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

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