CSS中固定寬度布局的詳細教程

.布局前的認知
1.1 三種基本方案
多欄布局有三種基本的實現(xiàn)方案:固定寬度、流動、彈性。
固定寬度。布局的大小不會隨用戶調(diào)整瀏覽器窗口大小而變化,一般是 900 到 1100 像素寬(最常見的是 960 像素)。
流動。布局的大小會隨用戶調(diào)整瀏覽器窗口大小而變化。(結(jié)合 CSS 媒體查詢,能夠適應(yīng)最大和最小的屏幕,業(yè)界稱之為 響應(yīng)式設(shè)計。)
彈性。在瀏覽器窗口變寬時,不僅布局變寬,而且所有內(nèi)容元素的大小也會變化。(實現(xiàn)太過復(fù)雜,不多介紹。)
1.2 布局高度
多數(shù)情況下,布局中結(jié)構(gòu)化元素(乃至任何元素)的高度是 不必或者不應(yīng)該設(shè)定的。因為保持元素 height 屬性的默認值 auto 不變,才能使元素根據(jù)自己包含內(nèi)容的增加而在垂直方向上擴展。這樣擴展的元素會把下方的元素向下推,而布局也能隨內(nèi)容數(shù)量的增減而垂直伸縮。
1.3 布局寬度
為了使瀏覽器窗口寬度合理變化,布局能作出適當(dāng)?shù)恼{(diào)整,我們 需要精細地控制 布局寬度。
2.三欄-固定寬度布局
結(jié)構(gòu)如下:
上代碼:
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>三欄-固定寬度布局</title>
- <style>
- * {
- margin: 0;
- padding: 0;
- }
- #wrapper{
- width: 960px;
- margin: 0 auto;
- border:1px solid;
- }
- header{
- background: #f00;
- }
- nav{
- background: #dcd9c0;
- width: 150px;
- float:left;
- }
- article{
- background: #ffed53;
- width: 600px;
- float: left;
- }
- aside{
- background: #6a6b6c;
- width: 210px;
- float: left;
- }
- footer{
- clear:both;
- background: #6a6b6c;
- }
- </style>
- </head>
- <body>
- <div id="wrapper">
- <header>
- This is header.
- </header>
- <nav>
- This is nav<br>
- This is nav<br>
- This is nav<br>
- </nav>
- <article>
- This is article.<br>
- This is article.<br>
- This is article.<br>
- This is article.<br>
- This is article.<br>
- This is article.<br>
- This is article.<br>
- This is article.<br>
- This is article.<br>
- </article>
- <aside>
- This is aside.
- </aside>
- <footer>
- This is footer.
- </footer>
- </div>
- </body>
- </html>
結(jié)果如圖:
說明幾點:
通過給整個外包裝(#wrapper)設(shè)定寬度值(960px),并將其水平外邊距設(shè)定為 auto,就能實現(xiàn)居中。隨著向里面添加內(nèi)容,相關(guān)的欄的高度會增加。
設(shè)置寬度并浮動中間三欄(nav、article 和 aside),讓它們并排顯示。使用屬性:width 和 float。
三欄的總寬度加起來要等于外包裝的寬度(150 + 600 + 210 = 960)。同樣使用該方法就可以加任意多欄,只要它們的總寬度等于外包裝的寬度即可。
頁腳(footer)位于浮動元素后面,所以就會盡量往上移動。解決這個問題的方法就是使用 清除浮動(clear:both;或者使用clear:left;也可以,因為這里只有左浮動元素)。
3.為欄設(shè)定內(nèi)邊距和邊框
在上面的布局中,只要一調(diào)整各欄中的內(nèi)容,布局就可能超過容器寬度,而右邊的欄就可能滑到左邊的欄下方。例如為了讓內(nèi)容與欄邊界空開距離,為欄添加水平外邊距和內(nèi)邊距,或者為了增加愛欄間距,為欄添加外邊距,導(dǎo)致布局寬度增大,進而浮動欄下滑;又或者在欄中添加大圖片,或者沒有空格的長字符串(如長URL),也會導(dǎo)致欄寬大超過布局寬度。
示例:
- article{
- background: #ffed53;
- width: 600px;
- float: left;
- padding: 10px 20px; /* 添加這一行CSS規(guī)則 */
- }
結(jié)果就會變成這樣:
我們把這種現(xiàn)象稱為 浮動滑移,可以使用三種方法來預(yù)防發(fā)生:
從設(shè)定的元素寬度中減去添加的水平外邊距、邊框和內(nèi)邊距的寬度和。
在容器內(nèi)部的元素上添加內(nèi)邊距或外邊距。
使用 CSS3 的 box-sizing 屬性切換盒子縮放方式。應(yīng)該該屬性后,給元素添加邊框和內(nèi)邊距都不會增大盒子,相反會導(dǎo)致內(nèi)容變窄。
下面來討論這三種方法:
3.1 重設(shè)寬度以抵消內(nèi)邊距和邊框
由于上面給 article 欄添加了左右 20px 的水平邊距,故將該欄寬度從 600px 減至 560px,故修改后的 article 欄 css 樣式規(guī)則如下:
- article{
- background: #ffed53;
- width: 560px; /* 這里 */
- float: left;
- padding: 10px 20px; /* 別忘了這里 */
- }
效果如下:
雖然能實現(xiàn),但每次只要調(diào)整內(nèi)、外邊距就要重設(shè)布局寬度,非常煩人,而且還可能導(dǎo)致頁面錯亂。
3.2 給容器內(nèi)部的元素應(yīng)用內(nèi)邊距和邊框
把外邊距和內(nèi)邊距應(yīng)用到內(nèi)容元素上確實有效,前提是這些元素沒有明確地設(shè)定寬度,這樣它們的內(nèi)容才會隨著內(nèi)、外邊距的增加而縮小。
根據(jù)盒模型定義,沒有寬度的元素在水平方向上會適應(yīng)其父元素,其內(nèi)容會隨著外邊距、邊框和內(nèi)邊距的增加而減少。
考慮到將來修改的時候,一欄中可能包含大量不同內(nèi)容的元素,如果想重新調(diào)整內(nèi)容與容器邊界的距離,就必須每個元素都要進行調(diào)整,這樣不僅麻煩,而且容易出錯。況且,給欄添加邊框同樣會增大欄寬,不可能通過為其包含的內(nèi)容元素逐個添加應(yīng)用樣式來做到。
所以說,與其為容器中的元素添加外邊距,不如 在欄中再添加一個沒有寬度的 div,讓它包含所有內(nèi)容元素,然后再給這個 div 應(yīng)用邊框和內(nèi)邊距。如此一來,只要為內(nèi)部 div 設(shè)定一次樣式,就可以把讓所有內(nèi)容元素與欄邊界保持一致的距離。而且,將來再需要調(diào)整時也會很方便。任何新增內(nèi)容元素的寬度都由這個內(nèi)部 div 決定。
還是拿 article 欄來開刀:
- <article>
- <div class="inner"> <!-- 添加一個div -->
- This is article.<br>
- This is article.<br>
- This is article.<br>
- This is article.<br>
- This is article.<br>
- This is article.<br>
- This is article.<br>
- This is article.<br>
- This is article.<br>
- </div>
- </article>
增改樣式如下:
- article{
- background: #ffed53;
- width: 600px;
- float: left;
- }
- article .inner{
- margin: 10px;
- border:2px solid red;
- padding: 20px;
- }
效果如下:
從結(jié)果可以看出,中間欄的寬度并未因此有多少變化,因為內(nèi)容區(qū)減少的寬度抵消了應(yīng)用到內(nèi)部 div 上的外邊距、邊框和內(nèi)邊距的總寬度。于是,我們可以這樣結(jié)論:如果布局中的欄是浮動的,而且都設(shè)定了寬度,你就不要去動它!要動,就把內(nèi)容放在內(nèi)部 div 里,動這個 div。
3.3 使用 box-sizing:border-box
這是最簡單的一個方法。只要在三個浮動的欄的 CSS 規(guī)則中分別 加上 box-sizing:border-box 聲明,再給欄添加內(nèi)邊距(和邊框)就不會導(dǎo)致盒子的寬度變化。此時,既不用調(diào)整欄寬去抵消增加的內(nèi)邊距,也不用使用內(nèi)部 div。添加內(nèi)邊距的結(jié)果就是內(nèi)容收縮。
示例:
以下是簡介清晰的沒有內(nèi)部 div 的標(biāo)記:
- <div id="wrapper">
- <header>
- <!-- 標(biāo)題 -->
- </header>
- <nav>
- <ul>
- <!-- 鏈接 -->
- </ul>
- </nav>
- <article>
- <!-- 文本 -->
- </article>
- <aside>
- <!-- 文本 -->
- </aside>
- <footer>
- <!-- 文本 -->
- </footer>
- </div>
相應(yīng)的,CSS 規(guī)則如下:
- * {
- margin: 0;
- padding: 0;
- }
- #wrapper{
- width: 960px;
- margin: 0 auto;
- border:1px solid;
- }
- header{
- background: #f00;
- }
- nav{
- box-sizing:border-box; /* 這里! */
- background: #dcd9c0;
- width: 150px;
- float:left;
- padding: 10px 20px; /* 添加內(nèi)邊距 */
- }
- article{
- box-sizing:border-box; /* 這里! */
- background: #ffed53;
- width: 600px;
- float: left;
- padding: 10px 20px; /* 添加內(nèi)邊距 */
- }
- aside{
- box-sizing:border-box; /* 還有這里!! */
- background: #6a6b6c;
- width: 210px;
- float: left;
- padding: 10px 20px; /* 添加內(nèi)邊距 */
- }
- footer{
- clear:both; /* 清除浮動,防止頁腳往上移動 */
- background: #6a6b6c;
- }
結(jié)果如下:
box-sizing:border-box 確實起作用了。
多么好用的一個屬性??!當(dāng)然也就少不了 但是 —— IE6 和 IE7 不支持該屬性。
廢話少說,解決方案 如下:
使用一個專門解決這個問題的膩子腳本(polyfill),名叫 borderBoxModel.js.
可以使用 條件注釋 把它添加到 HTML 標(biāo)記之后、結(jié)束的 </body> 標(biāo)簽之前,以保證在加載 DOM 之后再執(zhí)行該腳本:
- <body>
- <!-- HTML 標(biāo)記 -->
- <!-- 只讓 IE8 之前的 IE 加載它 -->
- <!-- [if It IE 8] -->
- <script src="helpers/borderBoxModel.js"></script>
- <![endif]-->
- </body>
相關(guān)文章
CSS中將Span標(biāo)簽設(shè)置為固定寬度的方法
在網(wǎng)頁布局過程中,在某些特殊情況下需要將Span 標(biāo)簽設(shè)置為固定寬度,鑒于新手朋友們比較多,于是經(jīng)驗記錄下來與大家一起分享2014-03-27- CSS三列布局走出HTML布局陰影,兩端固定寬度,中間自適應(yīng)結(jié)構(gòu),下面有個不錯的示例,大家可以參考下2014-02-27
CSS三欄布局探討——中間固定寬度兩邊自適應(yīng)寬度
下面和大家一起探討和學(xué)習(xí)了一種用div+css進行的三列(三欄)布局,而且是中間固定左右兩邊自適應(yīng)寬度,聽起來蠻有意思的。因為以前只是碰到過,左右兩列固定而中間自適應(yīng)2013-12-13