为什么给 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.

相关推荐
纸上的彩虹12 分钟前
半年一百个页面,重构系统也重构了我对前端工作的理解
前端·程序员·架构
be or not to be39 分钟前
深入理解 CSS 浮动布局(float)
前端·css
LYFlied1 小时前
【每日算法】LeetCode 1143. 最长公共子序列
前端·算法·leetcode·职场和发展·动态规划
老华带你飞1 小时前
农产品销售管理|基于java + vue农产品销售管理系统(源码+数据库+文档)
java·开发语言·前端·数据库·vue.js·spring boot·后端
小徐_23331 小时前
2025 前端开源三年,npm 发包卡我半天
前端·npm·github
GIS之路2 小时前
GIS 数据转换:使用 GDAL 将 Shp 转换为 GeoJSON 数据
前端
JIngJaneIL2 小时前
基于springboot + vue房屋租赁管理系统(源码+数据库+文档)
java·开发语言·前端·数据库·vue.js·spring boot·后端
天天扭码2 小时前
以浏览器多进程的角度解构页面渲染的整个流程
前端·面试·浏览器
你们瞎搞2 小时前
Cesium加载20GB航测影像.tif
前端·cesium·gdal·地图切片
南山安3 小时前
Tailwind CSS:顺风CSS
javascript·css·react.js