css经典布局——头尾固定高度中间高度自适应布局
今天說說一個經典布局:頭尾固定高度中間高度自適應布局!
轉文請標明 --- 出處:穆乙 http://www.cnblogs.com/pigtail/
相信做過后臺管理界面的同學,都非常清楚這個布局。最直觀的方式是框架這個我不想多寫費話,因為我們的重心不在這里。如果有不了解的同學可以百度、google。這里我不得不吐下槽!!
百度實在讓我這個“粉絲”失望。就目前情況來說,百度已經完全輪為“有錢人排行榜”!再也不顧及用戶的搜索需求了,因為主導地位實在是:不可撼動!
不相信的同學,可以親身對比下B vs G的搜索結果。別告訴我google如何強大!!
很久以前,百度的搜索結果更符合目標,因為他更了解中國人的習慣,這是不可爭議,現在情況已經完全相反!
雖然google經常是六脈神劍,但我更欣賞它的搜索結果。吐槽打住!!!
?
現在開始正式談論這個經典布局 ——?頭尾固定高度中間高度自適應布局
下面說下要求:
1 頭部固定高度,寬度100%自適應父容器;
2 底部固定高度,寬度100%自適應父容器;
3 中間是主體部分,自動填滿,瀏覽器可視區域剩余部分,內容超出則中間部分出現流動條;
4 整個內容填滿瀏覽器可視區域,并且不超出此區域!
先看下效果圖:
?
相信,做過兩年前端的同學,拿到這個需求,都有一個感覺——這挺簡單的!
是的,本來就挺簡單!
方法一:position:absolute定位,不設高,并改變"包含塊"的尺寸渲染
從我腦海崩出來的第一個念頭就是定位布局——position
而我也是這么做的,因為要固定頭尾,所以,至少頭和尾要用到position定位。因為瀏覽器大小是可以調節的,而且不同尺寸,不同分辨率的瀏覽器可視區域的高度是不固定的,
這就決定是中間主體部分的高度不固定。所以真正的問題核心也正在此。解決了這個問題,整個布局也就解決了一多半。
上代碼,相信這也是符合大部分思路的實現方式:
<!DOCTYPE HTML> <html> <head> <meta charset="gb2312"> <title>頭尾固定中間高度自適應布局</title> <style> html, body {height:100%;margin:0;padding:0 } #dHead {height:100px;line-height:100px;background:#690;width:100%;position:absolute;z-index:5;top:0;text-align:center; } #dBody {background:#FC0;width:100%;overflow:auto;top:100px;position:absolute;z-index:10;bottom:100px; } .mycontent {padding:20px; } #dFoot {height:100px;line-height:100px;background:#690;width:100%;position:absolute;z-index:200;bottom:0;text-align:center; } </style> </head><body> <div id="dHead">固定頭部100px;</div> <div id="dBody"><div class="mycontent"> 中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br></div> </div> <div id="dFoot">固定尾部100px</div> </body> </html>結果也如上圖所示,預期已經達到。經測試:IE7+、firefox、chrome、safari、opera均通過測試!
這里有點要特別說明的地方:當容器被position:absolute或者float:left or right的時候,在沒有設定寬度的情況下窗口的表現為緊貼內容;
<!DOCTYPE HTML> <html> <head> <meta charset="gb2312"> <title>無標題文檔</title> <style> *{padding:0;margin:0} </style> </head><body> <div style="height:200px;position:absolute; background:#FF9900;">內容測試</div> </body> </html>?
看下效果圖:
但是如果在position:absolute下,同時設定left和right或者同時設定top和bottom的話。寬度和高會被拉伸到指定位置,需要說明的這就是寬度或者高度缺省時position:absolute or fixed 情況下,瀏覽器對容器的尺寸解析方式。
需要說明的是,對于一個浮動元素,如果不設定寬度,同樣采用“包含塊”的渲染方式,寬度取決于內容的寬度。但是,如果這個浮動元素內部有一個右浮動的子元素,寬度會擴展到父容器的寬度。這個就不給出具體的例子了,自己可以下去測試。另外可以表現為“包含塊的”還有display:inline-block 當然,IE 如果display inline 如果 has a layout 同樣會表現出“包含塊”渲染。這里就不深入探討了。
下面對于position:absolute or fixed 定位的“包含塊”,做一個渲染測試。
<!DOCTYPE HTML> <html> <head> <meta charset="gb2312"> <title>無標題文檔</title> <style> *{padding:0;margin:0} </style> </head><body> <div style="height:200px;position:absolute; background:#FF9900;left:0;right:0">內容測試</div> </body> </html>下面效果圖:
但這里我要鄭重宣布:IE6除外!經測試:經測試:IE7+、firefox、chrome、safari、opera均遵從此解析模式!IE怪異模式下是不遵從這個原則的。
如果不準備兼容IE6,相信已經可以到此為止了,我不想批評IE6。因為它在整個瀏覽發展歷程中是個代表,也是個經典。沒有一款瀏覽能在如此長的時間在市場上占據如此高的地位。
這當然也得益于它的與xp捆綁推廣策略。但是,就近年web的發展趨勢來看,IE6已經成為一個負擔。就連微軟也力不從心。
好了關于IE6我不想多談什么。因為就目前國內的形式而言,完全放棄IE6只是一個美好的期望。
我們看下IE6下的效果:
?
顯然中高的高度超出了預期。顯然,不應該出現滾動條。需要body或者html overflow:hidden。
<!DOCTYPE HTML> <html> <head> <meta charset="gb2312"> <title>頭尾固定中間高度自適應布局</title> <style> html, body {height:100%;margin:0;padding:0;overflow:hidden } #dHead {height:100px;line-height:100px;background:#690;width:100%;position:absolute;z-index:5;top:0;text-align:center; } #dBody {background:#FC0;width:100%;overflow:auto;top:100px;position:absolute;z-index:10;bottom:100px;_height:100% } .mycontent {padding:20px; } #dFoot {height:100px;line-height:100px;background:#690;width:100%;position:absolute;z-index:200;bottom:0;text-align:center; } </style> </head><body> <div id="dHead">固定頭部100px;</div> <div id="dBody"><div class="mycontent"> 中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br></div> </div> <div id="dFoot">固定尾部100px</div> </body> </html>看下面效果圖:
?
看右下角顯然主體部分被擋住了,并沒達到我們想要的預期!結合兩種IE6下的效果表現。其實,可以歸結為height:100%造成的。也可以歸結于w3c的盒子模型;
這里簡單的介紹一下IE與W3C兩種不同中的盒子模型:
先看一下面兩種盒子的解析圖:
?
從上圖可以看到 IE 盒子模型的范圍也包括 margin、border、padding、content,和標準 W3C 盒子模型不同的是:IE 盒子模型的 content 部分包含了 border 和 pading。
IE的盒子模型后來修復掉了,在標準模式下是表現w3c盒子模型的,在quirks模式下表現自己的盒子模型。
如果在IE6盒子模型下,設定BODY的padding哪么剩余的高度被主體部分繼承,就符合我們的預期了;
(當然css3中有box-sizing可以改變盒子的模型,從這方面看IE6的盒子模型,是符合邏輯的。連w3c都做了兼容吸收)
那現在就是怎么觸發IE6的quirks的問題了。
這里我只說幾種常見的方法,其它方法,讀者自已搜索:
1、 去除掉DOCTYPE聲明,顯然這不是我們想看到的結果;
2、DOCTYPE 之前有一個?XML?聲明:<?xml version="1.0" encoding="GBK"?>,這只是針對IE6的方式;
3、如果 DOCTYPE 之前有任何語句,quirks 模式在任何版本的 IE 中(截至?IE 9)同樣會被觸發,例如:
<!-- This comment will put IE 6, 7, 8, and 9 in quirks mode -->加一個注釋我這里采用了第二種方式,其實第三種方式更合理些,因為我們不想觸發quirks模式,造成瀏覽的不一致。但現在我們只需要在IE6下觸發quirks模式,所以采用了第二種方法。
<?xml version="1.0" encoding="GBK"?> <!DOCTYPE html> <html> <head> <meta charset="gb2312"> <title>頭尾固定中間高度自適應布局</title> <style> html,body{height:100%;} body {margin:0;overflow:hidden;_padding:100px 0; } #dHead {height:100px;line-height:100px;background:#690;width:100%;position:absolute;z-index:5;top:0;text-align:center; } #dBody {background:#FC0;width:100%;position:absolute;z-index:100;top:100px;bottom:100px;overflow:auto;_position:relative;_top:0;_bottom:0;_height:100%;_overflow:auto } .mycontent {padding:20px; } #dFoot {height:100px;line-height:100px;background:#690;width:100%;position:absolute;z-index:200;bottom:0;text-align:center; } </style> </head><body> <div id="dHead">固定頭部100px;</div> <div id="dBody"><div class="mycontent"> 中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分-----------------------------------<br></div> </div> <div id="dFoot">固定尾部100px</div> </body> </html>經測試達到預期!這樣我們想要的結果都有了。當然如果,不設定body的padding設dBody的上下border也是一樣的,這個留給讀者自己下去自己測試吧。這里就不貼Demo了。
缺點:為ie6做了太多的bug處理,同時還觸發了IE6的怪異模式,使得盒子解析模式跟W3C不符,這樣會影其它版塊的盒子書寫。
?
?方法二:利用boxsizing改變盒子模型
?其實,第二種方法跟第一種方法,有部分重疊。其中“滋味”,讀者自己體會吧!萬變不離其宗。
其實這個方法是藍色理想上看到的一辦法。
實現原理是,先為html設定box-sizing然后,加上上下padding值。布局模塊均采用position:relative定位。
然后,頭部采用負向margin向上平移(因為有了html padding),如查采用負top的話需要為每個布局版加上負top;看實現代碼:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta name="author" content="Chomo" /> <link rel="start" href="http://www.14px.com" title="Home" /> <title>利用box-sizing實現div仿框架</title> <style type="text/css"> * {margin:0;padding:0; } html {-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:100px 0;overflow:hidden; } html, body {height:100%; } .top {position:relative;top:-100px;height:100px;background:#f60; } .side {top:-100px;position:relative;height:100%;background:#fc0;overflow:auto;width:200px;float:left;margin-right:0 !important;margin-right:-3px;overflow:auto; } .main {top:-100px;position:relative;overflow:auto;height:100%;background:#f30; } .bottom {top:-100px;position:relative;height:100px;background:#f60;clear:both; } </style> </head> <body> <div class="top"> top </div> <div class="side"> side <br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /> </div> <div class="main"> main <br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /> </div> <div class="bottom"> bottom </div> </body> </html>了解box-sizing的同學們應該知道,它來自離微國比較遙遠的css3世界,因此IE6/IE7是不支持的,但經過驗證正常兼容IE6/IE7。
IE6/IE7下,<html>的box-sizing默認值本就是border-box(注:IE7有一點點不正常,overflow:hidden后神志有所恢復)。
這種方法看起更加完美,因為它不用觸發ie6的怪異模式,不會影響整體布局。
另外如果給頭部是absolute定位的話也是可以實現的。
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta name="author" content="Chomo" /> <link rel="start" href="http://www.14px.com" title="Home" /> <title>利用box-sizing實現div仿框架</title> <style type="text/css"> * {margin:0;padding:0; } html {-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:100px 0;overflow:hidden; } html, body {height:100%; } .top {position:absolute;top:0;left:0;width:100%;height:100px;background:#f60; } .side {height:100%;background:#fc0;width:200px;float:left;margin-right:0 !important;margin-right:-3px;overflow:auto; } .main {overflow:auto;height:100%;background:#f30; } .bottom {position:relative;height:100px;background:#f60;clear:both; } </style> </head> <body> <div class="top"> top </div> <div class="side"> side <br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /> </div> <div class="main"> main <br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /> </div> <div class="bottom"> bottom </div> </body> </html>?
?方法三:這個方法其實是從方法一和方法二結合實現的
?其它瀏覽器依然采用position定位,不設高度,然后,觸發“包含塊”的尺寸。
IE6下,采用html的box-sizing默認為box-border來實現。具體的原理上面都已經講過了直接上代碼:
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=gb2312" /> <title>頭尾固定的自適應內容布局</title> <style type="text/css"> <!-- * {margin:0;padding:0; } html{_padding:100px 0 100px 0;_overflow:hidden; } html,body {height:100%;width:100%; }.wrap {background:#FF8C00;width:100%;overflow:auto;position:absolute;z-index:20;left:0;top:100px;bottom:100px;_height:100%; } .top {height:100px;width:100%;left:0;top:0px;background:#6B8E23;position: absolute;z-index:100 } .footer {height:100px;width:100%;background: #EE4063;position: absolute;bottom:0;left:0;z-index:100 }--> </style> </head> <body> <div class="top">固定頭部100px;</div> <div class="wrap"> 中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分<br>中間自適應部分-----------------------------------<br> </div> <div class="footer">固定尾部100px</div> </body> </html>這里就不重復發效果圖了,有興趣的可以測試一下demo。
優點:不用觸發怪異模式
缺點:為IE6加了hack
方法四: 設置,主體部分的box-sizing
思路一旦打開,解決問題的辦法也就多起來了。既然有box-sizing這個好東西可以利用。那么不如設置主體部分的box-sizing:border-box;然后為主體部分加上上下border,看起來問題同樣可以解決。事實也是如此!
看實現代碼:
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=gb2312" /> <title>頭尾固定的自適應內容布局</title> <style type="text/css"> <!-- * { margin:0; padding:0; } html, body { height:100%; width:100%; overflow:hidden } .wrap { background:#FF8C00; width:100%; overflow-y:scroll; height:100%; position:absolute; top:0; z-index:0; -webkit-box-sizing:border-box; -moz-box-sizing:border-box; -ms-box-sizing:border-box; box-sizing:border-box; border-top:100px solid #fff; border-bottom:100px solid #fff; } .top { height:100px; width:100%; background:#6B8E23; position:absolute; top:0; left:0; z-index:100; } .footer { height:100px; width:100%; background: #EE4063; position: absolute; bottom:0; left:0; z-index:100 } --> </style> </head> <body> <div class="top">固定頭部100px; </div> <div class="wrap">中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分<br> 中間自適應部分-----------------------------------<br> </div> <div class="footer">固定尾部100px </div> </body> </html>?
經測試,確實可以。問題在于IE 6/7這兩個不支持box-sizing。
但有解決辦法,這里說兩個常用的辦法:
1 依然是觸發IE的怪異模式,采用上面說的第三種辦法,因為要兼容IE 6/7兩個條件:<!--quirks IE 6/7-->;
2 采用boxsizing.htc的方式,讓IE 6/7支持box-sizing。至于選哪個,這是見仁見智的事情了。這里附下:下載地址 https://github.com/Schepp/box-sizing-polyfill
?這里我就不發,具體代碼了,自己去測試一下吧。
方法五:js來設置中間的高度
對于這種辦法,我就不多說了,相信大部同學都是可以很輕松的搞定的!
至于采用哪種模式,自己選擇吧
轉載于:https://www.cnblogs.com/wfblog/p/8944902.html
總結
以上是生活随笔為你收集整理的css经典布局——头尾固定高度中间高度自适应布局的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何避免过度依赖腾讯元宝?
- 下一篇: 怎么看待腾讯元宝对就业市场的影响?