HTML 中的 <body> 和 <html> 元素,不知道你有沒有注意過。一個作爲 HTML 內容部分的父元素,一個作爲整個網頁的根元素,應用到它們上的樣式表有什麼區別,又究竟會影響到網頁上的哪一部分呢?
最近寫新主頁,遇到了一些麻煩,於是對該問題做了一些研究。
<body> 作爲一個塊元素
<body> 元素定義了 HTML 文檔的內容。W3School 上說,大多數瀏覽器會賦予它下面的樣式:
1
2
3
4
|
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 選擇器加上繼承:
1
2
3
|
html
{ color :
red ; }
|