HTML body中为什么不能使用样式和脚本标签?

45

[这个问题与这个问题有关,但不是关于电子邮件的。]

在许多情况下——尤其是在使用CMS或其他人的框架时,在<body>中嵌入<style>标签和<script>标签比在<head>中嵌入更容易。这在IE6、IE7(Windows)、Firefox 3.x和Safari(OS X)中似乎有效。

严格来说,这样做是否错误?如果是,除了在某些客户端完全被忽略之外,会带来什么负面影响?

注意:很高兴大家都想谈谈DRY和集中样式。现在设想一下,我想在文档中使用样式标签,因为它们不是全局的,而且我没有按页面访问头部的权限。由于某种原因,可能是网站每个页面的不同,或者每个段落的不同,或其他什么原因。我不希望很难追踪和更改。我担心使用body中的样式可能带来的后果。

你把那些应该集中处理的东西集中处理。其他所有的都是在中央样式表中的累赘。


1
请参见此链接:https://dev59.com/MHM_5IYBdhLWcg3w02z8。 - Gumbo
7个回答

28
尽管规范明确规定style标签不允许在body标签中使用,但规范并不是唯一的要素。所有主流浏览器都支持在body中使用style标签,这最终也是用户看到您的网站的方式。尽管长期以来浏览器行业一直在推动更好的标准和标准支持,但同时也一直在努力渲染破损的文档。
谷歌是HTML5规范工作的领头人,同时也通过遗漏属性值引号、使用CSS规范的选择器技巧、包含没有类型或语言的脚本标签以及没有类型的链接标签等违反规范的方式来节省字节。一个纯粹主义者可能会认为互联网上最常用的网站之一违反了规范,并且极有可能被严重地错误呈现。或者,我们可以理解为没有浏览器会进入广泛使用而无法渲染如此广泛使用的规范 hack。
因此,问题更多的是浏览器行业的走向 - 这又是更好的规范之一,但同时也尽最大努力尊重违反这些规范的页面的意图。我打赌style标签将在body中继续有效很长一段时间。
截至本篇翻译时间,Firefox 3+、IE6+、Safari 2+和Chrome 12+在使用HTML5文档类型的情况下支持body中的style标签。支持可能会更早,但这些浏览器在互联网上很少见到。

8
虽然我同意这是最相关的答案,但我认为值得指出的是,只要属性值中不含空格/非法字符,引号对于所有属性都是可选的。 - Sleavely
好的观点-先前的规范不允许这样做。需要大量挖掘(为什么他们要等到第8节才定义属性是什么?),但在规范中找到了:http://www.w3.org/html/wg/drafts/html/master/syntax.html#unquoted 这意味着即使在规范中,现在这也是完全合法的:<a href=://blah.com/blah.gif> - Chris Moschini
2
之前的规范允许这样做,只是不支持XHTML:W3解释了XHTML1和HTML4之间的区别 - Sleavely
是的,Web 经历了 HTML4 -> XHTML -> HTML5 的变化 - 我指的是 XHTML 作为之前的规范。 - Chris Moschini

16

<script><style> 标签的使用场景取决于您使用的文档类型。例如,我假设您正在使用 HTML5 文档类型:

<!DOCTYPE html>

script标签在HTML5 doctype下有三个上下文:

  1. 期望metadata内容的位置。
  2. 期望phrasing内容的位置。
  3. 期望支持脚本的元素的位置。

style标签在HTML5 doctype下具有稍微复杂的上下文结构:

  1. 如果scoped属性不存在:则应该放置在期望metadata内容的位置。
  2. 如果scoped属性不存在:则应该放置在是noscript元素的子元素且父元素是head元素的位置。
  3. 如果scoped属性存在:则应该放置在期望流内容的位置,但要在其他流内容(包括元素间空白和样式元素)之前放置,并且不能作为其内容模型为透明的元素的子元素。

简而言之,这意味着您可以将style标签和script标签放在中,因为是放置流内容和phrasing内容的位置。

始终请参考您使用的文档类型的规范。


10

简短回答:


详细的答案如下:

STYLE 被定义在 head.misc 中:

<!ENTITY % head.misc "SCRIPT|STYLE|META|LINK|OBJECT" -- repeatable head elements -->

元素head.misc的内容只能作为HEAD元素的子元素。因此,STYLE只能是HEAD元素的子元素。

SCRIPT被定义为在head.miscspecial中。

<!ENTITY % special
   "A | IMG | OBJECT | BR | SCRIPT | MAP | Q | SUB | SUP | SPAN | BDO">

而且,special 被定义为在 inline 中:

<!ENTITY % inline "#PCDATA | %fontstyle; | %phrase; | %special; | %formctrl;">

此外,SCRIPT 元素也可以是 BODY 元素的子元素。因此,在 HEAD 元素中和任何允许 内联 的地方都允许使用 SCRIPT 元素。

那么大多数浏览器解析主体部分意味着什么?这意味着它无论如何都不应该被使用吗? - Dan Rosenstark
@yar:是的,它不是标准的一部分,因此不应该使用,尽管它在大多数浏览器中可能有效。 - Gumbo
1
请注意,此答案参考的是HTML4规范,而@Sampson的参考的是HTML5规范,因此存在一些小差异。 - Denise Draper

3

在body中使用两种可能的样式:

  1. 使用内联样式。确实,您将失去内部和外部样式的优势,但如果您无法访问页眉,则无法访问页眉。

  2. 在style元素中使用scoped属性。这是HTML5中的新功能,但其想法是将CSS的作用范围限制在页面的一部分,例如单个div中。坏消息是它还不被支持(截至2011年7月),也不向后兼容。但是有(据称)一个JQuery插件可以帮助。了解更多信息:


当我看到“该属性已被从当前规范中删除”时,我差点哭了 - 请参见http://caniuse.com/#search=scoped - 所以显然它们不会很快被正式引入。 但是,由于每个浏览器都在准备这个,因此在任何地方使用<style>标记是完全安全的。 - dkellner

2

你遇到了将样式和脚本直接嵌入内容的问题。这里的主要原则是DRY(不要重复自己)原则。你可能会在多个地方使用一个脚本或特定的样式。当该样式或脚本需要修改时,你现在必须去寻找存在该代码的所有位置。将你的样式和脚本放在一个公共的地方是理想的。

另一方面,如果它只是一个小的样式问题(像素推动或仅涉及一个视图的东西),那么这可能没问题。


1
显然,我们在谈论只使用一次的东西。在多个地方使用的东西会被集中管理。 - Dan Rosenstark

1

但是为什么你会在正文中使用style标签呢?样式本来就是全局的,所以我找不到任何逻辑上的理由。

为了更简化和分离事物,您应该使用外部样式表。

脚本是允许的,并且有其原因:它们可能会产生输出,应在特定时间运行等其他原因。


1
一些MVC开发人员将特定的样式表加载到视图内容中,这可能会将它们嵌入模板的某个位置,因此在正文中。 - Sampson
1
你应该把所有的样式都放到一个样式表(或者一组样式表)中,然后让它们一直被包含,或者根据不同的视图生成一个样式表。如果你需要为每个视图都分别使用独立的样式表,那么你就误解了 CSS 的基本原则之一。以前一直都是用固定的样式表(或一组样式表)来实现的,为什么现在不能这样做呢? - Arve Systad
1
我们应该把这个对话限制在你是否能做到的范围内。我可能会在某些情况下有特定的样式,但这些样式并不是全局的,而是基于每个段落或每个页面的。使用样式比使用style=""属性更易读。 - Dan Rosenstark
这就是为什么有类选择器的原因 :-) 您还可以向 body 元素添加 ID 属性,并相应地更改内容。愚蠢的例子:body#about p { font-weight: bold; } - Arve Systad
如果你的代码示例“深入嵌套表格”中,你可能会遇到比正文内样式标签更糟糕的问题 :-)。事实是,规范不允许在正文内使用样式,如果你真的因为某种原因需要在那里使用它,那么在我看来,现在是重新设计前端的时候了。正文内的样式只是为了那个看似方便的瞬间而采取的“捷径”。 - Arve Systad
显示剩余2条评论

0

我认为最大的问题是方便性。如果要更改页面的样式,则将所有的样式和脚本信息放在一个区域中会更容易。样式/脚本信息可以位于


我不同意最后一点。在我看来,HTML和CSS非常不可预测。如果我不知道某个客户端的情况,忽略我的样式可能比以一种未知的方式进行尊重更加安全。 - Dan Rosenstark

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接