<html>
和 <body>
之间的区别很容易被忽略。它似乎是那些被认为是琐碎的事情之一。不可否认,我有一个坏习惯,就是将所有全局样式应用到 <body>
,并且当这种情况不足时,我会毫不犹豫地转向 <html>
。
但是,确实存在差异,无论我们是 CSS 资深人士还是新手,了解这些差异都是一个好主意。我们将在本文中讨论这些差异,并考虑一些将一个元素的样式优先于另一个元素的实用应用。
HTML 与 Body 之间的关联
考虑一下基本 HTML 文档的标准结构
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Metadata and such -->
</head>
<body>
<!-- Where the content begins -->
<body>
</html>
规范定义 <html>
作为文档的根元素,我们可以在上面的示例中清楚地看到:<html>
元素是所有其他元素的最顶层。由于没有比该层更高级的层级可以继承样式,因此这里就结束了。
从那里开始,<head>
和 <body>
构成了直接位于 <html>
内部的两个元素。事实上,规范定义 <body>
直接与 <head>
相反,因为它们是唯一需要区分的两个元素。
因此,这里最重要的是,<html>
是文档的根元素,其中 <body>
是包含在其中的子元素。事实上,在 CSS 中有一个 :root
选择器。它们的目标是完全相同的
:root {
}
html {
}
除了 :root
具有更高的特异性:(0, 0, 1, 0)vs(0, 0, 0, 1)。
<html>
上,对吗?
因此,我们应该始终将全局样式放在 我们很容易认为,我们希望在整个文档中继承的所有样式都应该直接应用于 <html>
,因为它是的文档的根元素。<html>
在层次结构中优先于 <body>
,因此它必须包含所有全局样式。
但这并不完全是事实。事实上,以下内容的内联属性在 规范中最初分配给 <body>
- background
- bgcolor
- marginbottom
- marginleft
- marginright
- margintop
- text
虽然这些属性现在被认为已过时,但建议使用 CSS 代替,并使用其对应的 CSS 属性
内联属性 | CSS 属性 |
background | background |
bgcolor | background background-color |
marginbottom | margin-bottom |
marginleft | margin-left |
marginright | margin-right |
margintop | margin-top |
text | font |
鉴于这些 CSS 属性源于为 <body>
编写的内联属性,因此似乎将它们直接应用于 CSS 中的 <body>
也是合适的,而不是将它们推送到 <html>
元素中。
<body>
上,对吗?
因此,我们应该始终将全局样式放在 嗯,也不完全是。在某些情况下,将样式应用于 <html>
更有意义。让我们考虑一下其中的几种情况。
rem
单位
使用 rem
单位相对于文档根目录。例如,当编写类似于以下内容时
.module {
width: 40rem;
}
该 rem
单位相对于 <html>
元素的 font-size
,即文档根目录。因此,无论在根级别设置什么作为用户默认值,.module
类都将以此为比例进行缩放。
Jonathan Snook 有一篇经典文章,很好地说明了如何将 <html>
上的 font-size
设置为百分比可以在使用 rem
单位时用作重置。
background-color
古怪的 在 CSS 中,有一个 奇怪的事情,即 <body>
上的 background-color
会溢出整个视窗,即使元素本身的度量标准没有覆盖整个区域。除非在 html 元素上设置 background-color
,否则不会发生这种情况。
如果目标是溢出,那么从一开始就将其设置在 html 元素上会很明智。
总结
希望这能阐明在 CSS 中使用 <html>
和 <body>
之间的关键区别。在 JavaScript 中也存在差异。例如,您不需要查询这两个元素,html 是 document.rootElement
,body 是 document.body
。
我们当然可以在这两者之间做出更多技术上的区分,但这里的重点是提升我们对它们的理解,以便在编写 CSS 时做出更好的决策。
您还有其他例子吗?在这些例子中,将一个元素的样式优先于另一个元素更有意义?或者您是否有不同的标准来判断何时设置哪个元素的样式?欢迎在评论区告诉我们!
通常,我会将 background-color 放在 html 上,并使用 body 作为包装器。
这样,我就不需要再定义一个带有 “wrapper” 类的额外 div 容器。
另外,感谢您提到了 :root 的特异性比 html 选择器更高的内容。以前并不知道!<3
干杯。
好吧,我觉得自己像个笨蛋。我从未想过将 body 作为包装器。我想我一直以为它很神圣,不应该用于脏兮兮的样式,而它只应该包含背景和字体样式,而不是 margin 等。我不知道这些理论是从哪里来的,它就像那些你从未在野外看到过它们被其他方式使用的东西一样。
我以前使用 body 来设置背景颜色,使用 main 元素来进行包装,但后来我发现 main 元素应该映射到 main ARIA 角色以实现可访问性。所以,我改为使用 div.container。我从未想过将 body 作为包装器。有趣……
除非您要制作一个非常基本的个人博客并且知道自己在做什么——将 body 用作包装器非常棒。您甚至可以疯狂一点,开始将 title 元素显示为可见的页面标题!
好吧,第二个选项太过火了,并且不受所有浏览器的支持。
但是,一旦您转到需要更多功能的网站,就必须使用不同的包装器元素。不幸的是,例如第三方图像查看器和 html 对话框存在太多问题。另外,如果您需要一个页面,其中一行必须再次充满整个宽度怎么办?
尝试修复所有这些问题会得到一个没有人愿意维护的网站。
将 body 用作包装器这个想法很好!我真的很喜欢,我会在我的未来网站上实现它。
我喜欢你的想法。当我看到
<
div class=”wrapper”> 紧接在 BODY 标签之后,总让我感到不舒服。
Rene,你关于全宽的说法很有道理,但我从未在 body-as-wrapper 和第三方 js 中遇到过问题,而且我在中大型网站上使用过它。
当
document.documentElement
返回html
元素时,document.rootElement
返回null
。这种情况什么时候会出现?
就是这样。我同意,
document.documentElement
返回html
元素。https://mdn.org.cn/en-US/docs/Web/API/Document/documentElement
我在 OS X/Chrome 42 中看到了同样的情况。
https://dl.dropboxusercontent.com/u/67362/latest-chrome-rootElement-docElement.jpg
我不知道
:root
的特异性比html
高,我一直想知道它们之间的区别。Geoff 的建议很棒。不确定
document.rootElement
来自哪里,但它没有返回<html>
元素。(我在 Chrome、Firefox 和 Spartan 中测试过。)标准属性应该是document.documentElement
(参见 DOM 规范)。有意思。我确信
document.rootElement
曾经在 Webkit/Blink 中有效。现在它在控制台中显示为自动补全中的属性,但值为null
。无论如何,正如其他人所说,标准 DOM 属性是
document.documentElement
。html {
transform: translate(-60px, 0px);
}
@philtune 我想它有点神圣,因为它是一个你无法移除的包装器,所以,你所有的页面都必须继承它的样式。如果你在里面放一个 .wrapper div,你就可以选择不继承。
但是关于基本的样式,比如背景、字体样式等等,我同意。这就是 body 的作用。
除了在包装器本身添加一个类来区分不同页面的需求非常容易。你可以将基本样式应用于 body 元素,然后使用诸如 .body-home 或 .body-about 这样的类进行调整。
我认为他的意思是,如果你想让一张图片跨越整个视窗宽度,然后让文本具有固定宽度,你最终会将那个额外的包装项添加到 HTML 中。
如果是基本的网站,那当然可以。
html
head
body
header
.wrapper
main
.wrapper
img
.wrapper
footer
.wrapper
在 html 标签上设置背景颜色似乎在渲染过程的早期就应用了,如果你在 body 部分之前在 head 部分有大量的包含,那么你的页面将呈现背景颜色,然后其他内容才会加载。
说得有道理。我认为这是将页面背景样式放在
<html>
上的另一个理由。这样你就会有更多“这里正在发生某些事情”的感觉。我经常放
以防止页面宽度“抖动”。你们认为
html
是这条规则的正确元素吗?是的。没有元素可以覆盖默认的滚动条,所以它实际上是页面(甚至是窗口)根部的滚动条。
你可以选择使用 :root,但这实际上是一样的。
我通常使用 html 标签来处理全站内容(就像 modernizr 类一样),而使用 body 标签来处理页面特定的类,如果这说得通的话。
当我做一个固定到窗口大小的网站时,我倾向于将 body 的高度和宽度与 html 标签一起设置。
在关于背景颜色的奇怪之处,你说
这个结论似乎与第一句话相矛盾。我理解正确了吗?还是我误解了什么?
答案在下面。
感谢上帝.. 这是一些我根本不知道的事情
http://klinikkandungananak.com
即使是谷歌也有 html/css 错误…
http://www.richard-visav.com
你真是个链接垃圾邮件狂魔。别指望我会点击它。
也许值得一提的是,在 Mac 版 Safari 中,html 上的背景颜色会影响滚动条的颜色。如果你的绝对定位侧边栏具有白色背景,而 html 背景为黑色,这可能会令人困惑。将使滚动条几乎不可见(白色在白色上)。http://codepen.io/anon/pen/ZGzgPg
哇,我一直不知道 Mac 会动态渲染滚动条颜色…
感谢这篇帖子,非常有趣的内容。我从未听说过 root: 所以我会确保更深入地研究一下。
我感到困惑。你提到“CSS 中有一个奇怪之处,即在
<body>
上设置的 background-color 会填充整个视窗… 如果目标是填充,那么一开始就在 html 元素上设置它会更明智。”???
如果你有一个 BODY 元素,它没有占用与 HTML 元素相同的空间,并且你在 BODY 上设置了 background-color,而在 HTML 元素上没有设置背景颜色,那么该背景颜色将填充整个页面(该页面可能与 HTML 元素具有相同的尺寸),这意味着这种怪癖会导致在 BODY 元素上设置的背景颜色表现得好像它是在 HTML 元素上设置的一样。所以… 如果你的 BODY 元素没有占用与 HTML 元素相同的空间,但你希望一种背景颜色覆盖 HTML 元素所覆盖的所有内容,那么在 HTML 元素上设置背景颜色比依赖怪癖来完成工作更有意义。
规范明确指出,body 元素上的背景应该传播到 html 元素(当 html 上没有设置背景时),因此不需要指定 html 的 background-color,实际上建议 html 页面作者为 body 指定画布背景,而不是 html。
http://www.w3.org/TR/css3-background/#body-background
这不是“怪癖”,而是规范的重要组成部分。
我认为“在大多数情况下”,你只希望在 html 上设置的属性是 font-size、重置 margin/padding、box-sizing,偶尔是 height(用于 100% 布局)。除此之外,为了获得最佳效果,只需将其保留。
另外,在历史上使用 body 作为包装器很糟糕,并在 ie7 及更早版本中造成了各种问题,尽管这些浏览器现在已经不是问题,但仍然存在着在较新版本的 IE 中缩放时会出现的问题,所以,我认为为了一个包装器元素,你可以一举避免所有这些问题。
使用 body 作为包装器而不是使用 div 的一个问题是,有时你想在文档的主要约束之外将内容嵌套在 body 中。例如,边缘上的内容。如果你将 body 的宽度缩减为视窗宽度的 75%,你仍然可以将内容添加到边缘,但这会导致一些非常难看的代码。
信不信由你,人们在推动身体的神圣性时,知道他们在做什么。使用其他元素来构成内容的主要边界(我建议使用三到四个 - 标题、页脚和文章……然后,也许,导航作为第四个或作为标题 &&/|| 页脚 &&/|| 文章的一部分)。
这里有很多讨论。
html { height:100% }
body { min-height:100% }
如果我错了,请纠正我,但我发现文本中存在矛盾
“CSS 中有一个奇怪的地方,
<body>
上的background-color
会 溢出整个视窗 (……) 除非在 html 元素上设置background-color
,否则它不会。””到目前为止,一切都很好,但是,您说
如果目标是溢出,从一开始就在html 元素上设置它可能很明智。”
这个同样的问题在这个话题中其他地方得到了解答。
我将
<body>
用于所有全局样式有一个特定原因:我将<html>
作为神圣元素,我从不向其应用自定义样式,以便我可以在 JavaScript 中根据它进行计算,知道我在混合的 CSS 中不会弄乱它的属性。它帮助过我很多次,但可能不是必需的。