position:absolute絕對定位解讀
摘要
用四段代碼解釋absolute的定位問題,進而從概念的角度切實解決html布局問題。
一、背景
常常遇到這樣一些問題,很容易混淆。“瀏覽器屏幕”,html,body誰的范圍大?如果一個html文檔中沒有relative元素,那么該absolute元素是相對於哪里進行定位的?左上角?瀏覽器?html?body?等等類似的問題,只要涉及到定位就總要花一些時間去調試。本文的目的在於當遇到問題時,能夠以文中闡述的觀點作為依據,快速定位和解決問題。
二、概念及原理
1、web頁面最外層的約束為body,就是瀏覽器面板能看到的部分。
2、body即可理解為文檔流,從上到下,從左向右。
3、文檔流超過了瀏覽器面板(可視區域),就會出現滾動條。
4、absolute的定制,就會將元素脫離文檔流,不占據文檔流,元素將不出現在文檔流中,當瀏覽器渲染時,不會出現滾動條。
5、在文檔流“流動”時,瀏覽器屏幕(范圍),會在文檔流中截出一塊區域。可以簡記為“第一屏”。
6、當沒有定制relative時,absolute(元素無論大小)即以此定位。
三、現象及解析
body文檔流並非就是元素內容所占據的空間,它就像一段河流,元素是在其上的物體。這是為了解釋當元素內容少於一屏幕時,body的邊界線在哪里,答案是仍然是一個屏幕扣出的一圈邊界線。
1、元素小於屏幕高度
在上述原理的基礎上,可以很好的解釋如下幾種現象。

1 <!DOCTYPE html> 2 <html lang = "en"> 3 <head> 4 <meta charset = "utf-8"> 5 <meta name = "keyword" content = "liao"> 6 <meta name = "description" content = "lllll"> 7 <title>^ <> ^</title> 8 <style> 9 body{ 10 margin:0; 11 } 12 .c0{ 13 background-color:red; 14 height:300px; 15 } 16 .c0 .cell{ 17 background-color:blue; 18 position:absolute; 19 bottom:10px; 20 right:10px; 21 } 22 </style> 23 </head> 24 <body> 25 <div class="c0">aaa 26 <div class="cell">bbb</div> 27 </div> 28 </body> 29 </html>
小藍盒子處於屏幕的右下角。證明在元素內容少於一屏幕時,absolute盒子按照body的屏幕邊界線擺放。
2、元素大於屏幕高度

1 <!DOCTYPE html> 2 <html lang = "en"> 3 <head> 4 <meta charset = "utf-8"> 5 <meta name = "keyword" content = "liao"> 6 <meta name = "description" content = "lllll"> 7 <title>^ <> ^</title> 8 <style> 9 body{ 10 margin:0; 11 } 12 .c0{ 13 background-color:red; 14 height:3000px; 15 } 16 .c0 .cell{ 17 background-color:blue; 18 position:absolute; 19 bottom:10px; 20 right:10px; 21 } 22 </style> 23 </head> 24 <body> 25 <div class="c0">aaa 26 <div class="cell">bbb</div> 27 </div> 28 </body> 29 </html>
這次嘗試可以用前面原理合理的解釋。即absolute盒子按照body的屏幕邊界線擺放。因為滾動條移動時,框出的邊界線向上移動了,所以小藍盒子也隨之移動。
3、哪里是absolute的參考線
用下面的例子再次證明哪里是absolute的參考線。

<!DOCTYPE html> <html lang = "en"> <head> <meta charset = "utf-8"> <meta name = "keyword" content = "liao"> <meta name = "description" content = "lllll"> <title>^ <> ^</title> <style> body{ margin:0; } .pghead{ background-color:blue; height:50px; color:white; } .pgbody .menu{ position:absolute; background-color:yellow; left:0; width:180px; color:white ; } .pgbody .rtbody{ position:absolute; background-color:pink; top:50px; bottom:20px; left:185px; right:0; color:black; } </style> </head> <body> <div class="pghead">HHH </div> <div class="pgbody"> <div class="menu"> <h1>0123</h1><h1>123</h1><h1>123</h1><h1>123</h> </div> <div class="rtbody"> <h1>0123</h1><h1>123</h1><h1>123</h1><h1>123</h1><h1>123</h1><h1>123</h1><h1>123</h1><h1>123</h1><h1>123</h1><h1>123</h1><h1>123</h1><h1>123</h1><h1>123</h1><h1>123</h1><h1>123</h1><h1>123</h1> </div> </div> </body> </html>
范例中,因為文字屬於特殊的元素,當設定盒子absolute,bottom為10px時,原來被文字撐起的盒子只能到第一屏的邊界線向上10px的位置,所以文字超出了盒子的范圍,也超出了瀏覽器屏幕的范圍,於是出現滾動條。而並不是像一些觀點認為背景色會布滿整個文檔流,一直到距離最底部10px的位置。
下面的例子,使用了overflow:auto,並且absolute盒子,四面都定制了到body的邊距。正是因為absolute以第一次瀏覽器框出body的邊界線為基准,才能呈現出多於瀏覽器屏幕的內容輔助滾動條在一屏幕內顯示的效果。

1 <!DOCTYPE html> 2 <html lang = "en"> 3 <head> 4 <meta charset = "utf-8"> 5 <meta name = "keyword" content = "liao"> 6 <meta name = "description" content = "lllll"> 7 <title>^ <> ^</title> 8 <style> 9 body{ 10 margin:0; 11 } 12 .pghead{ 13 background-color:blue; 14 15 height:50px; 16 color:white; 17 } 18 19 .pgbody .menu{ 20 position:absolute; 21 background-color:yellow; 22 left:0; 23 24 width:180px; 25 color:white ; 26 } 27 28 .pgbody .rtbody{ 29 position:absolute; 30 background-color:pink; 31 top:50px; 32 bottom:20px; 33 overflow:auto; 34 left:185px; 35 right:0; 36 color:black; 37 } 38 </style> 39 </head> 40 <body> 41 <div class="pghead">HHH 42 </div> 43 <div class="pgbody"> 44 <div class="menu"> 45 <h1>0123</h1><h1>123</h1><h1>123</h1><h1>123</h> 46 </div> 47 <div class="rtbody"> 48 <h1>0123</h1><h1>123</h1><h1>123</h1><h1>123</h1><h1>123</h1><h1>123</h1><h1>123</h1><h1>123</h1><h1>123</h1><h1>123</h1><h1>123</h1><h1>123</h1><h1>123</h1><h1>123</h1><h1>123</h1><h1>123</h1> 49 </div> 50 </div> 51 </body> 52 </html>
4、圖片的基准線
圖片的基准線依然是上文說到的第一次瀏覽器框出body的邊界線。請看下面的例子。

<!DOCTYPE html> <html lang = "en"> <head> <meta charset = "utf-8"> <meta name = "keyword" content = "liao"> <meta name = "description" content = "lllll"> <title>^ <> ^</title> <style> body{ margin:0; } .c0{ background-color:blue; position:absolute; bottom:10px; right:10px; } </style> </head> <body> <div class="c0"> <img src="zhuomian.jpg" style = "width:3000px;height:3000px;"> <div class="cell">bbb</div> </div> </body> </html>
四、小結
本次驗證基於幾種常見的網頁元素如不同大小的盒子,圖片等。最終得出absolute以body的最開始的瀏覽器邊界線為基准的結論。
總結兩種驗證方法。方法一:1)先將常見的元素列出,2)將各種元素常見的狀態列出,然后一一做實驗驗證。3)最后得出歸一化的共性的結論。
方法二:1)先根據一到兩個現象猜測出基本原理,2)然后根據原理推想出其他元素的結果,若符合預期則說明猜想的原理正確,3)最后歸納得出結論。