CSS學習筆記(八) 頁面佈局之三欄-固定寬度佈局

1.佈局前的認知

1.1 三種基本方案

多欄佈局有三種基本的實現方案:固定寬度、流動、彈性。css

  • 固定寬度。佈局的大小不會隨用戶調整瀏覽器窗口大小而變化,通常是 900 到 1100 像素寬(最多見的是 960 像素)。html

  • 流動。佈局的大小會隨用戶調整瀏覽器窗口大小而變化。(結合 CSS 媒體查詢,可以適應最大和最小的屏幕,業界稱之爲 響應式設計。)瀏覽器

  • 彈性。在瀏覽器窗口變寬時,不只佈局變寬,並且全部內容元素的大小也會變化。(實現太過複雜,很少介紹。)app

1.2 佈局高度

多數狀況下,佈局中結構化元素(乃至任何元素)的高度是 沒必要或者不該該設定的。由於保持元素 height 屬性的默認值 auto 不變,才能使元素根據本身包含內容的增長而在垂直方向上擴展。這樣擴展的元素會把下方的元素向下推,而佈局也能隨內容數量的增減而垂直伸縮。ide

1.3 佈局寬度

爲了使瀏覽器窗口寬度合理變化,佈局能做出適當的調整,咱們 須要精細地控制 佈局寬度。佈局

2.三欄-固定寬度佈局

結構以下:spa

圖片描述

上代碼:設計

<!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>

結果如圖:code

圖片描述

說明幾點:htm

  1. 經過給整個外包裝(#wrapper)設定寬度值(960px),並將其水平外邊距設定爲 auto,就能實現居中。隨着向裏面添加內容,相關的欄的高度會增長。

  2. 設置寬度並浮動中間三欄(nav、articleaside),讓它們並排顯示。使用屬性:widthfloat

  3. 三欄的總寬度加起來要等於外包裝的寬度(150 + 600 + 210 = 960)。一樣使用該方法就能夠加任意多欄,只要它們的總寬度等於外包裝的寬度便可。

  4. 頁腳(footer)位於浮動元素後面,因此就會盡可能往上移動。解決這個問題的方法就是使用 清除浮動clear:both;或者使用clear:left;也能夠,由於這裏只有左浮動元素)。

3.爲欄設定內邊距和邊框

在上面的佈局中,只要一調整各欄中的內容,佈局就可能超過容器寬度,而右邊的欄就可能滑到左邊的欄下方。例如爲了讓內容與欄邊界空開距離,爲欄添加水平外邊距和內邊距,或者爲了增長愛欄間距,爲欄添加外邊距,致使佈局寬度增大,進而浮動欄下滑;又或者在欄中添加大圖片,或者沒有空格的長字符串(如長URL),也會致使欄寬大超過佈局寬度。

示例:

article{
    background: #ffed53;
    width: 600px;
    float: left;
    padding: 10px 20px;    /* 添加這一行CSS規則 */
}

結果就會變成這樣:

圖片描述

咱們把這種現象稱爲 浮動滑移,可使用三種方法來預防發生:

  • 從設定的元素寬度中減去添加的水平外邊距、邊框和內邊距的寬度和。
  • 在容器內部的元素上添加內邊距或外邊距。
  • 使用 CSS3 的 box-sizing 屬性切換盒子縮放方式。應該該屬性後,給元素添加邊框和內邊距都不會增大盒子,相反會致使內容變窄。

下面來討論這三種方法:

3.1 重設寬度以抵消內邊距和邊框

因爲上面給 article 欄添加了左右 20px 的水平邊距,故將該欄寬度從 600px 減至 560px,故修改後的 article 欄 css 樣式規則以下:

article{
    background: #ffed53;
    width: 560px;    /* 這裏 */
    float: left;
    padding: 10px 20px;   /* 別忘了這裏 */
}

效果以下:

圖片描述

雖然能實現,但每次只要調整內、外邊距就要重設佈局寬度,很是煩人,並且還可能致使頁面錯亂。

3.2 給容器內部的元素應用內邊距和邊框

把外邊距和內邊距應用到內容元素上確實有效,前提是這些元素沒有明確地設定寬度,這樣它們的內容纔會隨着內、外邊距的增長而縮小。

根據盒模型定義,沒有寬度的元素在水平方向上會適應其父元素,其內容會隨着外邊距、邊框和內邊距的增長而減小。

考慮到未來修改的時候,一欄中可能包含大量不一樣內容的元素,若是想從新調整內容與容器邊界的距離,就必須每一個元素都要進行調整,這樣不只麻煩,並且容易出錯。何況,給欄添加邊框一樣會增大欄寬,不可能經過爲其包含的內容元素逐個添加應用樣式來作到。

因此說,與其爲容器中的元素添加外邊距,不如 在欄中再添加一個沒有寬度的 div,讓它包含全部內容元素,而後再給這個 div 應用邊框和內邊距。如此一來,只要爲內部 div 設定一次樣式,就能夠把讓全部內容元素與欄邊界保持一致的距離。並且,未來再須要調整時也會很方便。任何新增內容元素的寬度都由這個內部 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;
}

效果以下:

圖片描述

圖片描述

從結果能夠看出,中間欄的寬度並未所以有多少變化,由於內容區減小的寬度抵消了應用到內部 div 上的外邊距、邊框和內邊距的總寬度。因而,咱們能夠這樣結論:若是佈局中的欄是浮動的,並且都設定了寬度,你就不要去動它!要動,就把內容放在內部 div 裏,動這個 div。

3.3 使用 box-sizing:border-box

這是最簡單的一個方法。只要在三個浮動的欄的 CSS 規則中分別 加上 box-sizing:border-box 聲明,再給欄添加內邊距(和邊框)就不會致使盒子的寬度變化。此時,既不用調整欄寬去抵消增長的內邊距,也不用使用內部 div。添加內邊距的結果就是內容收縮。

示例:

如下是簡介清晰的沒有內部 div 的標記:

<div id="wrapper">
    <header>
        <!-- 標題 -->
    </header>
    <nav>
        <ul>
            <!-- 連接 -->
        </ul>
    </nav>
    <article>
        <!-- 文本 -->
    </article>
    <aside>
        <!-- 文本 -->
    </aside>
    <footer>
        <!-- 文本 -->
    </footer>
</div>

相應的,CSS 規則以下:

* { 
    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;       /* 添加內邊距 */
}
article{
    box-sizing:border-box;    /* 這裏! */
    background: #ffed53;
    width: 600px;
    float: left;
    padding: 10px 20px;       /* 添加內邊距 */
}
aside{
    box-sizing:border-box;    /* 還有這裏!! */
    background: #6a6b6c;
    width: 210px;
    float: left;
    padding: 10px 20px;        /* 添加內邊距 */
}
footer{
    clear:both;     /* 清除浮動,防止頁腳往上移動 */     
    background: #6a6b6c;
}

結果以下:

box-sizing:border-box 確實起做用了。

圖片描述

當咱們取消勾選該屬性時,footer 欄就會因爲 article欄的推擠產生了浮動滑移,移位到 nav欄下方。

圖片描述

多麼好用的一個屬性啊!固然也就少不了 可是 —— IE6 和 IE7 不支持該屬性。

廢話少說,解決方案 以下:

使用一個專門解決這個問題的膩子腳本(polyfill),名叫 borderBoxModel.js.
可使用 條件註釋 把它添加到 HTML 標記以後、結束的 </body> 標籤以前,以保證在加載 DOM 以後再執行該腳本:

<body>
<!-- HTML 標記 -->
<!-- 只讓 IE8 以前的 IE 加載它 -->
<!-- [if It IE 8] -->
<script src="helpers/borderBoxModel.js"></script>
<![endif]-->
</body>

備忘:【關於表現性標記的思考】、【子-星選擇符】、【預防過大的元素】。


參考資料

相關文章
相關標籤/搜索