HTML/BODY的背景渲染原理

HTML/BODY的背景渲染原理

1、前言

结论先行:css

咱们给body设置背景色,实际咱们看见的未必是body上的背景色:html

  1. 当html标签没有设置背景色时,咱们看见的是做用在浏览器画布上的背景色,不是body上的;
  2. 当html标签被设置了背景色时,咱们看见的是真正做用在body上的背景色。

人在前端已经漂泊数年,机缘巧合才发现,这几年给body写的背景色,全被浏览器给「吃」了。文中涉及的是CSS中关于特殊元素(html/body)的背景渲染的原理,对你而言它也许是块新大陆,也可能,你早已熟知,那么正好···能够一块儿交流下?前端

2、一个情景

有一个渲染列表的页面(不定高),要求背景是渐变颜色,效果以下图:vue

需求很简单:

 

  • 列表内容不足以撑满一屏时,整屏背景以渐变色填充;
  • 列表内容超过一屏高度时,整个页面背景以渐变色填充;

3、情景破解

姿式有不少,偏心的只有妳这一种。web

PS:破解情景的解法有不少,而下面这种解法能够引发咱们关于html、body背景渲染原理的思考。canvas

Step 1:首先给body设置颜色渐变
body{ background: linear-gradient(#FFFAD0,#ffffff); } 复制代码

不出意外,页面渐变出现了断层👇浏览器

 

Step 2:设置html高度为100%,同时给body设置下min-height
html{ height: 100%;} body{ min-height: 100%; background: linear-gradient(#FFFAD0,#ffffff); } 复制代码

又不出意外,看起来很OJBK,没有出现断层了!dom

忽然,内容渐渐多了起来,超过一屏的高度了···👇ui

呃···这是什么状况?超过一屏以后又断层了![what the fuck & 掀桌].jpg

 

Step3:设置html的背景色
html{ height: 100%; background: red; } 复制代码

是的,你没看错,我给html设置了红色!不得不服气,这样的骚操做居然解决了上面断层的问题。this

忽然兴起的总结

小小梳理下咱们遇到的疑点:

  1. 首先咱们给body设置了渐变色,即便内容超过一屏,咱们看到的也应该是body那一层,便是渐变色的背景,不该该断层!
  2. 为何给html元素设置一个背景色就能够完美解决这个断层?

4、原理解析

咱们这个问题涉及到了三个对象:html元素、body元素和浏览器画布,咱们须要了解它们三者之间渲染背景色的机制。

The document canvas is the infinite surface over which the document is rendered. [CSS2] Since no element corresponds to the canvas, in order to allow styling of the canvas CSS propagates the background of the root element (or, in the case of HTML, the element) as described below. However, if no boxes are generated for the element whose background would be used for the canvas (for example, if the root element has display: none), then the canvas background is transparent.

The background of the root element becomes the background of the canvas and its background painting area extends to cover the entire canvas. However, any images are sized and positioned relative to the root element as if they were painted for that element alone. (In other words, the background positioning area is determined as for the root element.) The root element does not paint this background again, i.e., the used value of its background is transparent.

以上是w3c对特定元素(根元素)背景的定义说明,总结为如下两点:

  • CSS根据根元素(html/body)给文档画布(该画布是无限大的,咱们姑且理解为浏览器画布)渲染背景颜色,同时背景色的定位区域就是根元素的区域;
  • 根元素再也不绘制该背景色,即根元素背景的使用值是透明的。

基于这两点解答前面咱们的疑问:

一、给body设置了渐变色背景,内容超过一屏的时候,出现了断层

真相是,浏览器画布首先获取根节点的背景样式,因为html咱们没有设置,因此它获取了body的背景色,从而致使浏览器画布也是渐变色背景;

其次,浏览器画布背景色的定位区域取决于根元素的区域,这里的根元素是html,而咱们对html作了 height:100% 的设置。因此浏览器画布以该区域的背景色重复渲染。

用图举证: 给html设置50%的width,那么左侧看到的是咱们的页面dom内容,右侧则是浏览器画布

html{ height: 100%; width: 50%; } body{ min-height: 100%; background: linear-gradient(#FFFAD0,#ffffff); } 复制代码

 

能够发现,左右两侧的背景色是一致的: 证实了浏览器画布取了body的背景色进行渲染,而body的背景色实际上是透明值,必然地,咱们在body看见的是会断层的渐变色。

 

因此,咱们给body设置的背景色被浏览器画布吃掉了!

二、经过html设置背景色的方式解决了断层问题

咱们给html设置背景色,实际上是让html去承担被浏览器画布取色的任务,这时候body的值就是咱们设置的渐变色。以图举证:

html{ height: 100%; width: 50%; background: #42b983; } 复制代码

 

对的,红色不喜欢,我决定了换成vue的主题绿。如此,浏览器画布取了html的背景色,左侧就能够正常看见body的渐变背景了。
相关文章
相关标签/搜索