CSS三欄布局的經(jīng)典實(shí)現(xiàn)方法

三欄是CSS布局中常見(jiàn)的一種布局模式册烈,顧名思義钮孵,就是將網(wǎng)頁(yè)內(nèi)容以三列的形式呈現(xiàn)骂倘。通常,三欄布局中的左欄和右欄是固定寬度的油猫,中欄隨著窗口寬度的變化而變化稠茂。本文探討欄三欄的基本實(shí)現(xiàn)思路和經(jīng)典方法柠偶,對(duì)其中涉及到的知識(shí)點(diǎn)進(jìn)行梳理情妖。

目的:實(shí)現(xiàn)一個(gè)左欄和右欄寬300px,中間欄寬度自適應(yīng)的三欄布局

三欄布局示意圖.png

基本實(shí)現(xiàn)思路

首先诱担,常規(guī)思路毡证,我們寫出3個(gè)div的HTML和CSS,分別是leftColumn(左欄)蔫仙、middleColumn(中欄)和rightColumn(右欄)料睛。

HTML:

<body>    
    <div id="leftDiv">左欄</div>
    <div id="middleDiv">中欄</div>
    <div id="rightDiv">右欄</div>
</body>

CSS:

#leftDiv {
    height: 300px;  /*高度設(shè)為300像素,下同*/
    background-color: rgb(60,139,176);  /*設(shè)置背景顏色*/
}

#middleDiv {
    height: 300px;
    background-color: rgb(225,236,214);
}

#rightDiv {
    height: 300px;
    background-color: rgb(122,122,122);
}

此時(shí)摇邦,得到的網(wǎng)頁(yè)如下圖所示:


示意圖.png

這是因?yàn)閐iv的特性:默認(rèn)寬度最大化(頁(yè)面的100%)恤煞,默認(rèn)高度最小化(根據(jù)內(nèi)容自適應(yīng))。

上面的CSS中施籍,只指定欄高度height:300px居扒,未指定寬度,所以每個(gè)div都以寬度width:100%填滿所在行丑慎。

注意:此時(shí)若嘗試指定每個(gè)div的寬度喜喂,例如給每個(gè)div的CSS添加語(yǔ)句:

width: 100px;

得到的頁(yè)面如下圖左圖,而非右圖竿裂。

示意圖.png

這是因?yàn)閐iv屬于塊級(jí)(block)元素玉吁,默認(rèn)情況下,塊級(jí)元素總是會(huì)另起一行腻异。

為了使塊級(jí)元素能位于同一行进副,最簡(jiǎn)單的方法是使用float屬性。我們對(duì)每個(gè)div的CSS新增語(yǔ)句:

#leftDiv,#middleDiv,#rightDiv {
    float: left;  /*向左浮動(dòng)*/
    height: 300px;  
}

使其向左浮動(dòng),得到的效果如下圖所示:

示意圖.png

可以看到悔常,對(duì)CSS設(shè)置float:left屬性后影斑,三欄位于了同一行,寬度為其內(nèi)容的適應(yīng)寬度这嚣。此時(shí)鸥昏,我們將左欄和右欄寬度設(shè)置為300px:

#leftDiv,#rightDiv {
    width: 300px;  /*設(shè)置寬度為300像素*/
    ... 
}
#middleDiv {
    ...
}

得到的效果如下圖所示:

示意圖.png

此時(shí),中欄的寬度仍為其內(nèi)容的適應(yīng)寬度姐帚,我們?yōu)閙iddleDiv添加如下語(yǔ)句:

width: calc(100% - 600px);  /*設(shè)置middleDiv寬度*/

calc()的作用為動(dòng)態(tài)計(jì)算長(zhǎng)度值吏垮,允許各種單位混合運(yùn)算,運(yùn)算符前后需有空格。

于是我們得到了最終效果膳汪。左欄和右欄各300px寬唯蝶,中欄根據(jù)瀏覽器窗口大小進(jìn)行動(dòng)態(tài)調(diào)整。但需要注意的是遗嗽,當(dāng)瀏覽器窗口寬度小于600px時(shí)粘我,中欄的寬度將小于0。為此痹换,我們可以為瀏覽其設(shè)置最小調(diào)整寬度征字,避免頁(yè)面混亂:

body {
    min-width: 700px;
}

至此,一個(gè)三欄布局就完成了娇豫。這種實(shí)現(xiàn)思路比較符合人的思維定勢(shì)匙姜,但也存在一定的缺陷:瀏覽器加載和渲染頁(yè)面遵循從上到下的原則,這種方法中冯痢,HTML的middleDiv(中欄)位列于leftDiv(左欄)之后氮昧,所以會(huì)在leftDiv之后加載,而middleDiv往往是頁(yè)面的核心浦楣,需要優(yōu)先加載展示給用戶袖肥。

于是,我們思考將middleDiv放在HTML中的首位:

<body>    
    <div id="middleDiv">中欄</div>
    <div id="leftDiv">左欄</div>
    <div id="rightDiv">右欄</div>
</body>

CSS中振劳,我們?nèi)匀辉O(shè)置middleDiv(中欄)的寬度為100% - 600px:

#middleDiv {
    width: calc(100% - 600px);
    ...
}

此時(shí)的界面如圖所示:

示意圖.png

可以看到椎组,由于我們?cè)贖TML中將middleDiv(中欄)放在欄首位,所以瀏覽器窗口中澎迎,中欄顯示在最前面庐杨。這時(shí),我們需要為leftDiv(左欄)騰出空間夹供,可以使用margin-left或padding-left灵份。

margin和padding分別為盒模型的外邊距和內(nèi)邊距,此處使用兩者皆可哮洽,此處唯一的區(qū)別是padding會(huì)被底色填充而margin不會(huì)填渠。因?yàn)閎ackground-color的填充區(qū)域?yàn)閏ontent+padding+border。

還有一點(diǎn)需要注意的是鸟辅,padding值不能為負(fù)氛什,對(duì)于需要取負(fù)值時(shí),僅可使用margin匪凉。

為middleDiv(中欄)添加以下語(yǔ)句:

margin-left: 300px;

此時(shí)效果如下圖所示:

示意圖.png

可以看到枪眉,由于增加了300px的外邊距,第一行的橫向空間被middleDiv(中欄)和leftDiv(左欄)填滿再层,rightDiv(右欄)被迫位列第二行贸铜。

此時(shí)堡纬,我們使用relative屬性對(duì)左欄和右欄進(jìn)行處理:

#leftDiv {
    position: relative;  /*相對(duì)定位*/
    left: calc(300px - 100%);  /*左移*/
    ...
}

#rightDiv {
    position: relative;
    top: -300px;  /*上移*/
    left: calc(100% - 300px);  /*右移*/
    ...
}

至此,我們?cè)诒WCmiddleDiv(中欄)先行加載渲染的條件下蒿秦,完成了三欄布局烤镐。基本思路為通過(guò)相對(duì)定位實(shí)現(xiàn)棍鳖。

經(jīng)典方法

CSS三欄布局的方法有很多種炮叶,其中最經(jīng)典的方法莫過(guò)于圣杯布局和雙飛翼布局。圣杯布局因形似圣杯而得名渡处,即中欄為杯身镜悉,左右兩欄為杯耳。雙飛翼布局則是圣杯布局的一種改進(jìn)骂蓖,去掉了relative屬性积瞒,并為主體部分增加了內(nèi)容嵌套。

圣杯布局(In Search of the Holy Grail)

圣杯布局和雙飛翼布局都需要在HTML中為div增加一層“容器(container)”登下。這個(gè)容器的目的主要是為了利用padding對(duì)中欄進(jìn)行調(diào)整。

<body>  
    <div id="container">  
        <div id="middleDiv">中欄</div>
        <div id="leftDiv">左欄</div>
        <div id="rightDiv">右欄</div>
    </div>
</body>

首先叮喳,仍然設(shè)置float:left屬性使div浮動(dòng)被芳,使其位于一行。

#leftDiv,#middleDiv,#rightDiv {
   float: left;
   ...
}

然后馍悟,將middleDiv(中欄)的寬度width設(shè)為100%:

#middleDiv {
    width: 100%;
    ...
}

得到如下圖所示的布局:

示意圖.png

此時(shí)畔濒,需要將leftDiv置于第一行左側(cè):

margin-left: -100%;  /* 左側(cè)邊界前移100% */

這樣處理的結(jié)果是leftDiv(左欄)被置于第一行最左端,但會(huì)覆蓋middleDiv(中欄)的部分內(nèi)容锣咒。我們需要將中欄的內(nèi)容從被覆蓋的地方拉出來(lái)侵状。一個(gè)簡(jiǎn)便的方法是對(duì)父容器container使用margin:

#container {
    margin: 0 300px 0 300px;
}

此處使用padding:0 300px 0 300px; 效果相同。

此時(shí)毅整,leftDiv(左欄)也會(huì)受父容器的影響向右移動(dòng)300px趣兄,仍然覆蓋著middleDiv(中欄)的一部分,所以我們使用相對(duì)定位讓其向左移動(dòng):

#leftDiv {
    position: relative;
    left: -300px;
    ...
}

此時(shí)的布局如下圖所示:

示意圖.png

對(duì)rightDiv(右欄)作類似處理:

#rightDiv {
    margin-left: -300px;  /*左側(cè)邊界前移300px*/
    position: relative;
    right: -300px;  /*右側(cè)邊界右移300px*/
    ...   
}

不要忘記為body設(shè)定最小寬度:

body {
    min-width: 800px;
}

至此完成悼嫉。

可以看到艇潭,圣杯布局的實(shí)現(xiàn)思想是給div套上一個(gè)父容器,通過(guò)調(diào)整父容器的padding和div左右欄的相對(duì)定位來(lái)實(shí)現(xiàn)三欄布局戏蔑。

雙飛翼布局

雙飛翼布局蹋凝,源于淘寶UED,是圣杯布局的一種改進(jìn)总棵,或者說(shuō)是另一種三欄實(shí)現(xiàn)思路鳍寂。其創(chuàng)新點(diǎn)在于額外為middleDiv(中欄)增加一個(gè)子div存放其內(nèi)容。

<body>  
    <div id="container">
        <div id="middleDiv">
            <div id="content">中欄</div>
        </div>
        <div id="leftDiv">左欄</div>
        <div id="rightDiv">右欄</div>
    </div>
</body>

仍然使用float屬性來(lái)對(duì)div進(jìn)行浮動(dòng):

#leftDiv,#middleDiv,#rightDiv {
   float: left;
   ...
}

與圣杯類似情龄,設(shè)置middleDiv(中欄)寬度為100%迄汛,且將leftDiv(左欄)拉到最左側(cè)候味,將rightDiv(右欄)作類似處理:

#middleDiv {
    width: 100%;
    ...
}

#leftDiv {
    margin-left: -100%;
}

#rightDiv {
    margin-left: -300px;
}

到這一步為止,雙飛翼布局方法和圣杯CSS方法并不不同隔心。

此時(shí)白群,由于雙飛翼布局方法為middleDiv(中欄)單獨(dú)添加了一個(gè)div存放其內(nèi)容,所以對(duì)于中欄的處理硬霍,可以使用該div的margin屬性:

#content {
    margin: 0 300px 0 300px;
}

此處使用padding:0 300px 0 300px; 效果相同帜慢。

同樣,不要忘記為body設(shè)定最小寬度:

body {
    min-width: 800px;
}

至此完成唯卖。

可見(jiàn)粱玲,圣杯布局方法與雙飛翼布局方法的區(qū)別在于圣杯布局采用相對(duì)位置屬性(position:relative)來(lái)調(diào)整左欄和右欄位置,并使用margin/padding屬性調(diào)整中欄拜轨。而雙飛翼布局方法無(wú)需相對(duì)位置屬性抽减,而是采用為中欄內(nèi)容創(chuàng)建div的方式,通過(guò)margin/padding來(lái)實(shí)現(xiàn)布局橄碾。

總結(jié)

本文探討了三欄布局的CSS基本實(shí)現(xiàn)方法卵沉,首先以基本思路對(duì)三欄布局進(jìn)行實(shí)現(xiàn),發(fā)現(xiàn)不足法牲,進(jìn)行調(diào)整史汗。文章第二部分闡述了流行的圣杯布局方法和雙飛翼布局方法的細(xì)節(jié)和異同。除本文所述布局方法外拒垃,還存在絕對(duì)定位法停撞、table布局法、網(wǎng)格布局法悼瓮,以及十分方便的flex布局法等多種方法戈毒,各有利弊。

本文僅探討了三欄布局的基本實(shí)現(xiàn)思路與方法横堡,詳細(xì)的實(shí)現(xiàn)過(guò)程希望能夠幫助大家深入理解CSS埋市。關(guān)于其他方法的討論將在以后實(shí)際應(yīng)用時(shí)進(jìn)行總結(jié)。??

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末翅萤,一起剝皮案震驚了整個(gè)濱河市恐疲,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌套么,老刑警劉巖培己,帶你破解...
    沈念sama閱讀 218,122評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異胚泌,居然都是意外死亡省咨,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門玷室,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)零蓉,“玉大人笤受,你說(shuō)我怎么就攤上這事〉蟹洌” “怎么了箩兽?”我有些...
    開封第一講書人閱讀 164,491評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)章喉。 經(jīng)常有香客問(wèn)我汗贫,道長(zhǎng),這世上最難降的妖魔是什么秸脱? 我笑而不...
    開封第一講書人閱讀 58,636評(píng)論 1 293
  • 正文 為了忘掉前任落包,我火速辦了婚禮,結(jié)果婚禮上摊唇,老公的妹妹穿的比我還像新娘咐蝇。我一直安慰自己,他們只是感情好巷查,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,676評(píng)論 6 392
  • 文/花漫 我一把揭開白布有序。 她就那樣靜靜地躺著,像睡著了一般吮便。 火紅的嫁衣襯著肌膚如雪笔呀。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,541評(píng)論 1 305
  • 那天髓需,我揣著相機(jī)與錄音,去河邊找鬼房蝉。 笑死僚匆,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的搭幻。 我是一名探鬼主播咧擂,決...
    沈念sama閱讀 40,292評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼檀蹋!你這毒婦竟也來(lái)了松申?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,211評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤俯逾,失蹤者是張志新(化名)和其女友劉穎贸桶,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體桌肴,經(jīng)...
    沈念sama閱讀 45,655評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡皇筛,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,846評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了坠七。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片水醋。...
    茶點(diǎn)故事閱讀 39,965評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡旗笔,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出拄踪,到底是詐尸還是另有隱情蝇恶,我是刑警寧澤,帶...
    沈念sama閱讀 35,684評(píng)論 5 347
  • 正文 年R本政府宣布惶桐,位于F島的核電站撮弧,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏耀盗。R本人自食惡果不足惜想虎,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,295評(píng)論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望叛拷。 院中可真熱鬧舌厨,春花似錦、人聲如沸忿薇。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,894評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)署浩。三九已至揉燃,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間筋栋,已是汗流浹背炊汤。 一陣腳步聲響...
    開封第一講書人閱讀 33,012評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留弊攘,地道東北人抢腐。 一個(gè)月前我還...
    沈念sama閱讀 48,126評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像襟交,于是被迫代替她去往敵國(guó)和親迈倍。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,914評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 問(wèn)答題47 /72 常見(jiàn)瀏覽器兼容性問(wèn)題與解決方案捣域? 參考答案 (1)瀏覽器兼容問(wèn)題一:不同瀏覽器的標(biāo)簽?zāi)J(rèn)的外補(bǔ)...
    _Yfling閱讀 13,753評(píng)論 1 92
  • 第一部分 HTML&CSS整理答案 1. 什么是HTML5啼染? 答:HTML5是最新的HTML標(biāo)準(zhǔn)。 注意:講述HT...
    kismetajun閱讀 27,486評(píng)論 1 45
  • 一、負(fù)邊距在讓元素產(chǎn)生偏移時(shí)和position: relative有什么區(qū)別? 負(fù)margin和position:...
    婷樓沐熙閱讀 870評(píng)論 0 4
  • 一、負(fù)邊距在讓元素產(chǎn)生偏移時(shí)和position: relative有什么區(qū)別? 負(fù)邊距在讓元素產(chǎn)生偏移的時(shí)候其自身...
    dengpan閱讀 308評(píng)論 0 0
  • CSS 定位問(wèn)題 主要就是經(jīng)典的絕對(duì)定位蜗字,相對(duì)定位問(wèn)題打肝。 10個(gè)文檔學(xué)布局:通過(guò)十個(gè)例子講解布局脂新,主要涉及相對(duì)布局...
    強(qiáng)哥科技興閱讀 362評(píng)論 0 1