惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

V
V2EX
C
Check Point Blog
博客园_首页
B
Blog
D
Docker
U
Unit 42
量子位
I
InfoQ
有赞技术团队
有赞技术团队
Martin Fowler
Martin Fowler
GbyAI
GbyAI
L
LangChain Blog
云风的 BLOG
云风的 BLOG
博客园 - Franky
美团技术团队
T
The Blog of Author Tim Ferriss
阮一峰的网络日志
阮一峰的网络日志
月光博客
月光博客
Vercel News
Vercel News
Recent Announcements
Recent Announcements
雷峰网
雷峰网
大猫的无限游戏
大猫的无限游戏
小众软件
小众软件
Google DeepMind News
Google DeepMind News

cuihao->blog

留言板备份 - cuihao->blog 局域网中通过 TUN 和软路由实现链路聚合 - cuihao->blog 雾霾中的星空 - cuihao->blog 把 /usr/share 压成 squashfs,以及写 systemd 的 mount 单元 负整数的整除和取余运算 - cuihao->blog 一些关于读书的事 - cuihao->blog Archlinux on ThinkPad L430 - cuihao->blog NetworkManager 配合使用 chnroutes (至少适用于 Arch) 【火狐三则】增强组件的PKGBUILD;不错的dial插件;同步profile到内存盘 - cuihao->blog unzip 6.10b测试版,解决ZIP乱码问题 - cuihao->blog 最后还是堕落到宋体了 - cuihao->blog
网页中的 <body> 和 <html> 元素及其样式
cuihao · 2015-02-26 · via cuihao->blog

HTML 中的 <body> 和 <html> 元素,不知道你有没有注意过。一个作为 HTML 内容部分的父元素,一个作为整个网页的根元素,应用到它们上的样式表有什么区别,又究竟会影响到网页上的哪一部分呢?

最近写新主页,遇到了一些麻烦,于是对该问题做了一些研究。

<body> 作为一个块元素

<body> 元素定义了 HTML 文档的内容。W3School 上说,大多数浏览器会赋予它下面的样式:

body {
    display: block;
    margin: 8px;
}

这两条告诉了我们什么呢:

  • body 被渲染成一个块元素;
  • body 有 margin,可见它外面还有东西?

用一个简单的例子试一试:

其实 <body> 的行为就和一个普通的 <div> 差不多嘛:

  • 如果不指定宽度,则宽度自动占满其父元素(?);
  • 如果不指定高度,则高度设为刚好能容下内部元素;
  • 默认 overflow 行为是显示溢出内容。

可是,你有没有想到什么问题?

<body> 的背景为什么溢出去了?

我们经常使用 body{ background: xxx; } 来设置整个网页的背景。但如果 <body> 真的是一个普通的块元素,而且还带有 margin,那么为什么这个 background 设置能应用到整个网页的绘画区域呢?

栈溢出  Applying a background to <html> and/or <body> 给出了解释。这是一个特例,概括来讲如下:

  • 根元素 <html> 的背景决定了整个绘画区域的背景。但如果 <html> 元素背景为透明(默认值),就会取其 <body> 子元素的背景作为 <html> 的背景,其位置等属性变成相对于 <html> 元素的。

这和我们的日常观感一致(背景 svg:画布大小 128x128,在 (64,64) 处有一个半径为 64 的红色实心圆):

如果给 <html> 设置了背景,那么 <body> 的背景行为就和块元素一致了(点上面的“设置html背景”试一试)。

可是,上面是不是用到了 <html> 的背景来着?可见 <html> 元素也有样式、也需要绘制咯?

如果尝试用 F12 或者加 border 的方法来查看 <html> 元素在整个绘画区域中的位置,很容易产生“<html> 的确就是比 <body> 长宽更多一点的外围元素”这样的错觉。可是,你有没有注意过……

网页的滚动条是怎么来的?

突然转向了一个奇怪的话题。为什么网页太长了,就会出现滚动条(默认行为如此)?

我们都知道,一个块元素设置 overflow 样式为 auto,当其中内容过长超过块元素长宽时,就会出现滚动条。

——其实,网页有滚动条是因为 <html> 默认拥有 overflow:auto 的样式!而 <html> 元素的尺寸,正是窗口的尺寸。

来验证一下吧。DOM 中 document.documentElement 代表的其实就是 <html> 元素,访问 clientWidth、clientHeight 就可以得到其宽高(其实不太科学,详见此文)。我们搞了个超大的 <body>:

看一看 <html> 的尺寸,果然没有因为 <body> 而变大。改变浏览器窗口大小,还会发现其尺寸也会跟着变化。看来,<html> 也可以看作一个块元素咯。

不过,上面例子中给 <html> 设置的 border,位置好像不太对劲儿,纵向一直延续到底了。这个嘛,我还不知道怎么解释,没查到资料。但鉴于一般也没人会给 <html> 设置 border,姑且先搁置了吧。

这里有一篇简明的文章,探讨本节的问题。

<html> 和 <body> 上的 CSS

在 <html> 上应用 CSS 的机会并不多。而在 <body> 上,最重要的应用就是设置背景了。在 CSS2 中,不能在 background 属性中指定两个图片。所以以前有在 <html> 中指定另一个背景图片这样的应用。当然,除非为了兼容古代 IE,否则已经没必要这么做了。

此外,前面提到一般浏览器都会给 <body> 加上 margin。有时候想要让内部元素紧贴窗口边界,可以通过 margin: 0 来重置掉这一设置。

另外一个在 <html> 或 <body> 上设置 CSS 的情景,是让子元素继承样式。比方说设置全局字体样式,“*”选择器杀伤力可能有点大。可以用 html 选择器加上继承:

html {
    color: red;
}