在 < body > 中与其他 HTML 一起使用 < style > 标记

<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 样式生成一些数据结构并用于呈现?

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

317765 次浏览

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

引用:W3C规范W3Schools

我想这将因浏览器的不同而有所不同:全局显示规则可能会随着浏览器运行代码而更新。

当外部样式表加载延迟时,有时可以在全局显示规则中看到此类更改。类似的事情也可能发生在这里,但在如此短的连续时间内,它实际上没有被渲染。

无论如何,它都不是有效的HTML,所以我认为考虑它是徒劳的。<style>标记属于页面的head部分。

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

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

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

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

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

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

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

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

当我看到大网站的内容管理系统经常把一些<风格>元素(一些,而不是全部)接近于依赖于这些类的内容,我的结论是,马已经出了谷仓。

去看看cnn.com, nytimes.com, huffingtonpost.com,你最近的大城市报纸,等等。他们都这样做。

如果有一个很好的理由放一个额外的<style>部分——例如,如果你实时包含()不同的独立页面元素,并且每个元素都有一个嵌入的<这样,组织就会更清晰、更模块化、更容易理解、更可维护——我要说的是咬紧牙关。当然,如果我们能够拥有具有限制作用域的“本地”样式(如局部变量)会更好,但您使用的是您现有的HTML,而不是您以后可能想要或希望拥有的HTML。

当然,正如其他人所阐述的那样,遵循正统有潜在的缺点和好的(如果不总是令人信服的)理由。但在我看来,这越来越像是对<style>在& lt; body>已经成为主流。

警告:这个答案指的是style标签上的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>
如果你在支持scoped的HTML-5浏览器中呈现上述代码,你会看到样式表的有限范围。

只有一个<强> < / >强劲主要警告…

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

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

因此,考虑到:

  • 目前几乎所有现有的浏览器都会忽略scoped属性
  • 几乎所有现有的浏览器目前都允许在<body> . c中使用<style>标记
  • 将来的实现将需要在<body>中允许(限定范围的)<style>标记

...那么在body中放置<style>标记实际上就是< >强无害< / >强 *,只要你将来用scoped属性来证明它们。唯一的问题是,目前的浏览器实际上不会限制范围的样式表-他们会应用到整个文档。但关键是,出于所有实际目的,你可以<body>中包含<style>标记,前提是你:

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

*当然,除了惹恼HTML验证器…

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


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

我可以用网站报道,自2016年以来,属性已从当前规范中删除。

“身体风格”爱好者的坏消息: W3C最近对WHATWG进行了输掉了HTML之战, WHATWG的无版本HTML“生活标准”现在变成了是官方的,唉,在BODY允许吗 STYLE。短暂的快乐时光一去不复返。,)W3C验证器现在也可以通过WHATWG规范工作。(谢谢@FrankConijn的提醒!)

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

过时的好消息:

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

W3C规范 (享受最后一行!):

4.2.6. 风格元素

...

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

需要元数据内容的地方。

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

在正文中,期望流内容的地方。


元附注:

尽管“浏览器战争”造成了损害,但我们仍然必须继续针对两个可笑的竞争“官方”HTML“标准”(1 standard + 1 standard < 1 standard的引用)进行开发,这一事实意味着“退回到战壕常识”的web开发方法从未真正停止应用。

这可能最终会改变,但引用传统的智慧:web作者/开发人员,因此,反过来,浏览器应该最终决定什么应该(和不应该)在规范中,当没有很好的理由反对已经在现实中做的事情时。大多数浏览器长期以来都在BODY中支持STYLE(以这样或那样的方式;例如,参见scoped attr.),尽管其固有的性能(和可能的其他)惩罚(我们应该决定是否支付,而不是specs.)。所以,首先,我会继续押注他们,不会放弃希望。,)如果WHATWG像他们声称的那样尊重现实/作者,他们可能会在这里做W3C所做的事情。

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

我假设:

  1. 这些而不是程序员用户没有与系统管理员(或机构的webdevs)开放的通道,要求在系统的stylesheets中包含一些CSS规则。实际上,这对管理员(或web开发人员)来说是不切实际的,考虑到他们会有这样的请求数量。
  2. 这个系统是遗留的,仍然不支持更新版本的HTML。

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


第一个选择:询问你的系统管理员

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


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

body标记上使用外部样式表,即使用link标记内部你可以访问的区域(这将是,在网站上,在body标记内,而不是在head标记中)。一些消息来源说这是可以的,但“不是一个好的做法”,如中数:

<link>元素可以出现在<head><body>元素中,取决于它的链接类型是否为body-ok。例如,stylesheet链接类型是body-ok,因此在body中允许使用<link rel="stylesheet">。然而,这并不是一个好的实践;将你的<link>元素从你的body内容中分离出来,把它们放在<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>

然后在同一目录下创建一个CSS文件,名为bar.css:

.test1 {
color: green;
};

好吧,如果你知道如何在机构系统的某个地方上传CSS文件,这将是可能的。也许情况就是这样。


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

body标记上使用互联网样式表,即在您可以访问的区域内使用style标记(即在站点上,在body标记内,而不是在head标记中)。这就是查尔斯鼠尾草深圳的答案。选择这个选项时,要考虑他们的担忧。


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

< p >警报 它们与修改页面的<head>元素有关。也许机构的系统管理员允许这个不会。所以,建议先征求他们的同意

假设允许被授予,策略是访问<head>。怎么做?JavaScript方法。

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

这是第二个选项的另一个版本。在<head>标记上使用外部样式表,即使用<link>元素您可以访问的区域(即,在站点上,不在body标记内,而在head标记内)。这个解决方案符合上面提到的中数w3schools关于第二个选项解决方案的建议。一个新的Link对象将被创建。

要通过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文件,这将看起来是可能的。

第5个选项:在<head>上新建<style>

<head>标记上使用新的内部样式表,即使用一个新的<style>元素你可以访问的区域(这将是,在站点上,不在body标记内,在head标记内)。一个新的Style对象将被创建。

这是通过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);

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

<head>标记上使用一个现有的内部样式表,即使用一个<style>元素你可以访问的区域(也就是说,在站点上,不在body标记内,在head标记内),如果存在的话。将创建一个新的Style对象或使用CSSStyleSheet对象对象(在这里采用的解决方案的代码中)。

从某种角度来看,这是有风险的。 第一个,因为它可能不存在某个<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>

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对象(文档位于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. 还是按照看到的顺序使用样式信息进行渲染?

(引用改编)

为了得到更准确的答案,我建议阅读以下文章:

  • 浏览器如何工作:现代网络浏览器的幕后
  • 渲染树的构造、布局和油漆
  • “渲染”网页意味着什么?
  • 浏览器渲染是如何工作的——在幕后
  • 渲染- HTML标准
  • 10渲染- HTML5

是的,它可以。我查看了Mozilla的网页。 https://developer.mozilla.org/en-US/docs/Web/HTML/Element/style < / p >

我认为你可以得到完全合法的“限定样式”。在现代浏览器中,只需付出少量的努力。考虑下面的HTML文档:

<!doctype html>
<html>
<head>
</head>
<style>p{background:red}</style>
<body>
<template>
<style>p{background:green}</style>
<p>I am green</p>
</template>
<p>I am red!</p>
<script>
document.querySelectorAll('template').forEach((template)=>{
const div = document.createElement('div');
div.remove(); // detach div from document
let shadow = div.attachShadow({mode:'open'});
shadow.replaceChildren(template.content);
template.replaceWith(div);
});
</script>
</body>
</html>

我使用template来包含我想要包含自己的style元素的HTML,该元素不影响template之外的任何HTML。当然,默认情况下,template在呈现期间被忽略。JavaScript代码

  1. 查找文档中的每个模板
  2. 创建一个分离的空div
  3. div一个“影子根”;(本地化style的关键)
  4. template内容复制到影子根目录
  5. 将原来的template替换为包含相同内容的div(除了在影子根中)

几乎任何HTML内容——包括style——在template中都是合法的。

使用最新的Chrome/Firefox/Edge测试。给我一个免费的MacBook Pro,我会用Safari进行测试!: -)

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

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

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

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,最后一个是它。杰夫现在经历了很多事。他是绿色的,因为这是最后一个规则告诉他的,但他也被旋转和定位,里面的文本是白色的,所以我们可以安全地说他读了一切样式标签告诉他的,并且:

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

这就是发生的事情。

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

底线

  1. 是的,你可以在主体中放置样式标签
  2. 是的,正如你所期望的那样
  3. 尽可能避免,它是正在进行的辩论,谁知道我们会在哪里结束。