为什么给 body 设置背景会直接铺满整个视口?

当我们在进行网页开发时,通常会遇到需要设置铺满整个页面的背景图的需求,此时我们可以选择创建一个 width: 100vw; height: 100vh<div> 盒子,并设置其背景,这样就可以铺满整个视口。

为 body 设置背景

当然,我们也会选择直接将背景颜色或背景图片设置在 <body> 标签上,此时背景颜色或背景图片便会自动铺满整个视口。

如图:

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    body {
      background: linear-gradient(to right, #ff7e5f, #feb47b);
    }
  </style>
</head>
<body>
  
</body>
</html>

但当我们查看结构时会发现:<body> 的高度并没有占据整个视口。

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    body {
      background: linear-gradient(to right, #ff7e5f, #feb47b);
    }
  </style>
</head>
<body>
  <p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Doloribus, deleniti.</p>
  ...
  <p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Doloribus, deleniti.</p>
</body>
</html>

这与我们平时使用的盒子模型不相符。

body 的背景

回顾知识点:body 元素的默认尺寸行为

  • 宽度 :作为块级元素,body 默认会继承自其父容器 <html>,而 <html> 的宽度默认等于视口宽度(width: 100%)。
  • 高度:未设置高度时,body 的高度由内容撑开(内容高度 < 视口高度时,body 高度 = 内容高度;内容高度 > 视口高度时,body 高度 = 内容高度)。

当我们给 <body> 设置背景时,浏览器会遵循背景的「画布蔓延」机制进行渲染

背景的「画布蔓延」机制

  • <body> 设置背景且 <html> 元素没有设置背景时,浏览器会将 body 的背景「提升」渲染到根元素(<html>)的绘制层上。
  • 这是 CSS 规范中的特殊处理(CSS2.1 规范 Section 14.2)。

具体表现

  • 视觉覆盖视口 :即使 body 的实际高度小于视口高度,body 的背景颜色/图片会看似覆盖整个视口,因为浏览器将其渲染在 <html> 层。
  • 元素尺寸未改变:此时 body 的实际尺寸仍然由内容决定,开发者工具中检查 body 的高度可能小于视口高度。

验证实验

根据上面的知识,我们可以得出一个结论:如果我们同时给 <html><body> 设置背景,那么 <body> 的背景将不会再占满整个视口,而是正常的将背景渲染在 padding-box

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    html {
      background-color: #ff7e5f;
    }
    body {
      background-color: #feb47b;
    }
  </style>
</head>
<body>
  <p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Doloribus, deleniti.</p>
  <p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Doloribus, deleniti.</p>
  <p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Doloribus, deleniti.</p>
  <p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Doloribus, deleniti.</p>
  <p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Doloribus, deleniti.</p>
  <p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Doloribus, deleniti.</p>
  <p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Doloribus, deleniti.</p>
  <p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Doloribus, deleniti.</p>
</body>
</html>

总结

为什么给 body 设置背景会直接铺满整个视口?

回答:<body> 的背景属性会被提升到根元素 <html> 的绘制层,从而覆盖整个视口(即"画布蔓延")。我们实际看到的背景其实是 <html> 元素绘制层的背景。

规范建议开发者通过 <body> 而非 <html> 设置页面背景,以确保兼容性和预期渲染效果。

REFERENCED

CSS2.1 规范 Section 14.2

For HTML documents, however, we recommend that authors specify the background for the BODY element rather than the HTML element. For documents whose root element is an HTML "HTML" element or an XHTML "html" element that has computed values of 'transparent' for 'background-color' and 'none' for 'background-image', user agents must instead use the computed value of the background properties from that element's first HTML "BODY" element or XHTML "body" element child when painting backgrounds for the canvas, and must not paint a background for that child element. Such backgrounds must also be anchored at the same point as they would be if they were painted only for the root element.

相关推荐
冰暮流星5 分钟前
javascript之双重循环
开发语言·前端·javascript
爱敲点代码的小哥10 分钟前
C#视觉模板匹配与动态绘制实战(绘制和保存,加载tb块,处理vpp脚本的方式)
前端·javascript·信息可视化
南风知我意95730 分钟前
【前端面试3】初中级难度
前端·javascript·面试
霍理迪34 分钟前
JS作用域与预解析
开发语言·前端·javascript
切糕师学AI37 分钟前
.NET Core Web 中的健康检查端点(Health Check Endpoint)
前端·kubernetes·.netcore
rosmis1 小时前
地铁病害检测系统软件改进记录-2-02
开发语言·前端·javascript
css趣多多1 小时前
解决ui组件flex1容器底部被撑开的问题
前端
乔江seven1 小时前
【python轻量级Web框架 Flask 】2 构建稳健 API:集成 MySQL 参数化查询与 DBUtils 连接池
前端·python·mysql·flask·web
Alaaaaaaan1 小时前
[DevOps]使用github-action工具部署docker容器(实现提交代码一键推送部署到服务器)
服务器·前端·docker·容器·github
摇滚侠2 小时前
css 设置边框
前端·css