1、前言
結論先行:css
咱們給body設置背景色,實際咱們看見的未必是body上的背景色:html
- 當html標籤沒有設置背景色時,咱們看見的是做用在瀏覽器畫布上的背景色,不是body上的;
- 當html標籤被設置了背景色時,咱們看見的是真正做用在body上的背景色。
人在前端已經漂泊數年,機緣巧合才發現,這幾年給body寫的背景色,全被瀏覽器給「吃」了。文中涉及的是CSS中關於特殊元素(html/body)的背景渲染的原理,對你而言它也許是塊新大陸,也可能,你早已熟知,那麼正好···能夠一塊兒交流下?前端
2、一個情景
有一個渲染列表的頁面(不定高),要求背景是漸變顏色,效果以下圖:vue
![](http://static.javashuo.com/static/loading.gif)
- 列表內容不足以撐滿一屏時,整屏背景以漸變色填充;
- 列表內容超過一屏高度時,整個頁面背景以漸變色填充;
3、情景破解
姿式有不少,偏心的只有妳這一種。web
PS:破解情景的解法有不少,而下面這種解法能夠引發咱們關於html、body背景渲染原理的思考。canvas
Step 1:首先給body設置顏色漸變
body{ background: linear-gradient(#FFFAD0,#ffffff); } 複製代碼
不出意外,頁面漸變出現了斷層👇瀏覽器
![](http://static.javashuo.com/static/loading.gif)
Step 2:設置html高度爲100%,同時給body設置下min-height
html{ height: 100%;} body{ min-height: 100%; background: linear-gradient(#FFFAD0,#ffffff); } 複製代碼
又不出意外,看起來很OJBK,沒有出現斷層了!dom
忽然,內容漸漸多了起來,超過一屏的高度了···👇ui
![](http://static.javashuo.com/static/loading.gif)
Step3:設置html的背景色
html{ height: 100%; background: red; } 複製代碼
是的,你沒看錯,我給html設置了紅色!不得不服氣,這樣的騷操做居然解決了上面斷層的問題。this
忽然興起的總結
小小梳理下咱們遇到的疑點:
- 首先咱們給body設置了漸變色,即便內容超過一屏,咱們看到的也應該是body那一層,便是漸變色的背景,不該該斷層!
- 爲何給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); } 複製代碼
![](http://static.javashuo.com/static/loading.gif)
![](http://static.javashuo.com/static/loading.gif)
因此,咱們給body設置的背景色被瀏覽器畫布吃掉了!
二、經過html設置背景色的方式解決了斷層問題
咱們給html設置背景色,實際上是讓html去承擔被瀏覽器畫布取色的任務,這時候body的值就是咱們設置的漸變色。以圖舉證:
html{ height: 100%; width: 50%; background: #42b983; } 複製代碼
![](http://static.javashuo.com/static/loading.gif)