摘要:引言圣杯布局盡管這是一個很古老的話題了,而且網上早就有許多相關的文章,但作為前端入門和面試的必備知識之一,還是覺得有必要溫故而知新一番。
引言
「圣杯布局」—— 盡管這是一個很古老的話題了,而且網上早就有許多相關的文章,但作為前端入門和面試的必備知識之一,還是覺得有必要溫故而知新一番。尤其是在拜讀了「yuanzm」的博客《我是如何同時拿到阿里和騰訊offer的》文章后,更感到對于任何別人的知識至少都需要花點時間自己實踐一下,了解一下它的原理甚至是歷史,而不應盲目引用和浮于表面。謹以此文表示感謝~
圣杯的由來圣杯布局是討論「三欄液態布局」的實現,它最早出自于誰或許不得而查了,但最早的完美實現是來自于 Matthew Levine 于2006年在「A LIST APART」上寫的一篇文章,它主要講述了網頁中關于最佳圣杯的實現方法。
所謂液態布局是相對固態布局而言的,固態布局就是固定值不變的布局,液態就好比在容器里到了一杯水,它可以隨著容器寬度的變化而自適應寬度。
在這篇文章中,作者指出了當時的一些實現方式所存在的問題,如:必須按照源順序(在 DOM 中表現為先寫 Left,然后 Middle,最后,Right)等,它將可能導致代碼不夠靈活,尤其是從 DOM 的載入順序上來說,中間的內容不能被首先加載。
因此他給出一個方案,它將:
兩邊帶有固定寬度中間可以流動(fluid);
允許中間一欄最先出現;
允許任意一欄放在最上面;
僅需一個額外的 div 標簽
僅需非常簡單的 CSS,帶上最少的兼容性補丁
文中還提到了他的這個想法是基于「One True Layout」 和 「 Eric Meyer’s adaptation」兩篇文章帶來的靈感。
在這里你可以看到「圣杯布局」的最終效果:http://alistapart.com/d/holygrail/example_1.html
實現方式接下來就言歸正傳,說下具體的實現思路:
首先我們需要布局的 HTML 代碼如下,作者在這里為了便于表達,對標簽使用了非語義化的 id,他建議在其他任何正式項目中盡量使用語義化的 id。例如,我們需要實現的是左側寬度為 200px,右側寬度為 150px,中間是流動的布局。
#header#center#left#right
正如他先前提到的,只是加了一層額外的 div 它的 id 是 container。它的 CSS 內容非常簡單,具體代碼如下:
body { min-width: 550px; /* 2x LC width + RC width */ } #container { padding-left: 200px; /* LC width */ padding-right: 150px; /* RC width */ } #container .column { height: 200px; position: relative; float: left; } #center { background-color: #e9e9e9; width: 100%; } #left { background-color: red; width: 200px; /* LC width */ right: 200px; /* LC width */ margin-left: -100%; } #right { background-color: blue; width: 150px; /* RC width */ margin-right: -150px; /* RC width */ } #footer { clear: both; } #header, #footer { background-color: #c9c9c9; } /*** IE6 Fix ***/ * html #left { left: 150px; /* RC width */ }
下面我們來分步觀察它的實現邏輯:
第1步 建立框架先寫 header, footer 和 container 三個 div
#header
我們將 container 的內邊距設置為左右兩邊各自的寬度。它看起來就像這樣:
第2步 加入三欄此時我們有了基本框架,可以把三欄塞進去了。
#header#center#left#right
接著我們給每一欄配上合適的寬度,并將它們設為浮動。同時我們需要清除 footer 的上下環境,以免遭跟上面三欄一起浮動。
#container .column { float: left; } #center { width: 100%; } #left { width: 200px; /* LC width */ } #right { width: 150px; /* RC width */ } #footer { clear: both; }
注意這里中間一欄的 100% 寬是基于它的父容器 container 的寬度而言的,由于 container 設置了內邊距,因此中間欄看起來就處在了網頁的中間,但左右兩欄由于排在中間欄的后面,且因為空間不夠被擠到了中間欄的下面,如下圖所示:
第3步 把左側欄放上去中間欄已經就位,剩下的事情就是把左右兩欄放上去了,接下來我們先放左側欄。
為了詳述過程,這里將分為兩個小步驟。首先,我們先將它的外邊距設置為 -100%,這樣一來,由于浮動的關系,左側欄就能上位,與中間欄交疊在一起,并占據了左邊。而右側欄由于左側欄的上位,自動向前浮動到了原來左側欄的位置。
接著我們要用到相對定位屬性(relative),并設置一個與左側欄等寬的偏移量:
#container .columns { float: left; position: relative; } #left { width: 200px; /* LC width */ margin-left: -100%; right: 200px; /* LC width */ }
可以看到,它設置的 right 屬性就是相對于 container 的右邊線向左偏移 200px,如此一來,它就完美地跑到了 container 左內邊距的位置,也就是我們希望它呆的地方,如下圖所示:
第4步 把右側欄放上去最后,我們需要把右側欄放上去,此時只需利用上面的原理把他放到 container 的右外邊距的位置即可,我們需要再一次設置一個負外邊距的值,它等于右側欄的寬度:
#right { width: 150px; /* RC width */ margin-right: -150px; /* RC width */ }
至此,所有的欄目都就位了~
源碼地址https://jsfiddle.net/DotHide/pg47fucg/1/
參考文章《In Search of the Holy Grail》 by Matthew Levine
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/115093.html
摘要:圣杯布局左寬度為右邊寬度為效果如圖雙飛翼布局效果如圖兩種布局的區別這兩種布局實現的都是兩邊固定寬度,中間自適應,中間欄放在最前面優先渲染。不同的是,雙飛翼布局多創建一個包裹的,去掉了相對定位,相對少寫一些。 圣杯布局html: center left right css: #container { padding: 0 100px ...
摘要:圣杯布局左寬度為右邊寬度為效果如圖雙飛翼布局效果如圖兩種布局的區別這兩種布局實現的都是兩邊固定寬度,中間自適應,中間欄放在最前面優先渲染。不同的是,雙飛翼布局多創建一個包裹的,去掉了相對定位,相對少寫一些。 圣杯布局html: center left right css: #container { padding: 0 100px ...
摘要:于是,淘寶軟對針對圣杯的缺點做了優化,并提出雙飛翼布局。綜合來看,不管的大小高低如何,雙飛翼布局都能正常顯示,嗯確實很優秀。錘子和釘子綜上所見,雙飛翼布局更勝一籌。 showImg(https://segmentfault.com/img/bVYtjF?w=922&h=561); 前言 突然有一天,腦之里不知怎地蹦出一個詞,「雙飛翼」,這是很久以前的淘寶提出的一種三欄布局優化方案,然而...
摘要:參考文章同學的關于圣杯布局,圣杯布局和雙飛翼布局的區別經典布局圣杯布局實現的效果主要在中,和固定寬度,首先渲染,且自適應寬度。 ps: 參考文章 DotHide同學的關于圣杯布局,圣杯布局和雙飛翼布局的區別 經典布局 圣杯布局 showImg(https://segmentfault.com/img/remote/1460000015851268?w=682&h=247); #hea...
閱讀 2804·2021-11-24 09:39
閱讀 2777·2021-09-23 11:45
閱讀 3403·2019-08-30 12:49
閱讀 3352·2019-08-30 11:18
閱讀 1907·2019-08-29 16:42
閱讀 3344·2019-08-29 16:35
閱讀 1321·2019-08-29 11:21
閱讀 1912·2019-08-26 13:49