<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,所以我认为考虑它是徒劳的。<style>标签属于页面的头部部分。

其他回答

浏览器的真正功能是什么?

这又是一场理论与实践的辩论。没有真正的赢家。 首先让我给你们看一个CodePen:

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

CSS:

.jeff { background:red; transform:rotate(2deg); color:white; }

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>

解释

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

应用了所有的样式块; 它们的应用顺序是正确的; 它们完全凌驾于彼此之上; 整个过程就像一个大样式表。

这就是发生的事情。

同样,浏览器是耐心的野兽。他们想让你享受互联网,而创建网站的人没有很好的纪律,所以浏览器进化到可以容忍他们疯狂的行为。

底线

是的,你可以在主体中放置样式标签 是的,正如你所期望的那样 尽可能避免,这是一个持续的争论,谁知道我们最终会在哪里结束。

警告:这个答案指的是样式标签上的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遵循标准(仅仅是出于组织目的)。为了有效,可以这样写

<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,所以我认为考虑它是徒劳的。<style>标签属于页面的头部部分。

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

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