網頁佈局對於一個前端開發者而言相當重要,掌握好佈局知識有助於咱們更好的實現CSS界面的設計和開發。佈局是有限空間內的元素排列方式,由於頁面設計橫向不滾動,縱向無限延伸,因此大多數時候討論的佈局都是對水平方向進行分割。經常使用的佈局方式爲單列布局、兩列布局、三列布局、粘連佈局等。html
單列表佈局是將一個元素做爲佈局容器,一般設置一個較小的(最大)寬度來保證不一樣像素寬度屏幕下顯示一致。前端
<body> <div class="header">頭部</div> <div class="content">單列布局</div> <div class="footer">底部</div> </body>
<style> body{ margin: 0; padding: 0; } .header { margin: 0 auto; max-width: 720px; height: 100px; background: red; } .content { margin: 0 auto; /*寬度足夠的時候元素居中顯示*/ max-width: 720px; /*設置一個最大寬度,保證各類屏幕顯示一致*/ height: 400px; background: green; } .footer { margin: 0 auto; max-width: 720px; height: 100px; background: blue; } </style>
單列布局的優點在於基本上能夠適配超過佈局容器寬度的各類顯示屏幕,能夠保證在超過設置的最大寬度的屏幕上瀏覽網站看到的效果是一致的。而它的缺點就是屏幕空間的浪費,在屏幕空間足夠大的狀況下,頁面兩側顯示了大量空白,若是屏幕特別大,兩側空白的區域可能會比頁面內容更寬。瀏覽器
兩列布局就是將頁面分割成左右寬度不等的兩列,寬度較小的列設置爲固定寬度,剩餘寬度由另外一列撐滿。這種佈局適用於內容上具備明顯主次關係的網頁。
① float + margin方式
經過讓左側浮動,而後給右側設置一個margin-left,值爲左側元素的寬度便可。app
<div class="container"> <div class="left"> 左側定寬 </div> <div class="right"> 右側自適應 </div> </div>
<style> .container { min-width: 500px; height: 100px; } .left { background: red; width: 200px; height: 100px; float: left; /*讓左側元素浮動*/ } .right { background: green; width: 100%; height: 100px; margin-left: 200px; /*給右側元素添加一個margin-left,爲左側區域留出空間*/ } </style>
② 絕對定位
首先給父容器設置一個相對定位,而後給左側元素設置一個絕對定位,給右側也設置一個絕對定位,left值爲左側元素的寬度,right值爲0,便可。佈局
<style> .container { height: 100px; min-width: 500px; position: relative; /*父容器設置爲相對定位*/ } .left { background: red; width: 200px; height: 100px; position: absolute; left: 0; } .right { background: green; height: 100px; position: absolute; left: 200px; /*值爲左側定寬元素的寬度*/ right: 0; /*同時設置left和right能夠實現寬度的自適應效果*/ } </style>
③ Float + BFC
所謂BFC就是Block fomatting context(塊級格式化上下文),對於BFC盒子而言,其擁有一個獨立的佈局環境,BFC容器裏面的子元素不會影響到外面的元素,反之亦是如此。
BFC容器相對於普通的盒子而言,有一些特性:
a. 在同一個文檔流中,BFC的區域不會與float box重疊。
b. 爲了避免影響BFC容器外元素的佈局,計算BFC的高度時,浮動元素也會參與計算。flex
如何讓一個普通的盒子變成BFC容器?網站
<style> .container { height: 100px; min-width: 500px; } .left { background: red; width: 200px; height: 100px; float: left;/*左側浮動*/ } .right { background: green; height: 100px; overflow: hidden; /*讓右側變成一個BFC容器,避免與左側浮動元素重合 */ } </style>
④ Flex實現
主要就是給父容器設置成flex佈局容器,而後給右側設置flex爲1便可讓右側變成自適應。spa
<style> .container { height: 100px; min-width: 500px; display: flex; /*給父容器設置爲flex容器*/ } .left { background: red; width: 200px; height: 100px; } .right { background: green; height: 100px; flex: 1; /*給右側設置成自適應*/ } </style>
三列布局按照左中右的順序進行排列,一般中間列最寬(自適應),左右兩列次之。三列布局相對複雜些,咱們會按步驟一步一步實現,如:
① 聖盃佈局設計
<div class="container"> <div class="main">聖盃佈局</div> <div class="left">left</div> <div class="right">right</div> </div>
所謂聖盃佈局,就是根據左右兩側元素的寬度,給父容器元素設置一個左右內邊距,爲了方便記憶,咱們能夠理解成一開始父容器內是方形填滿的,給父容器添加左右內邊距,咱們能夠想象成將聖盃壓縮成形的過程。code
<style> .container { background: yellow; height: 100px; padding: 0px 100px 0px 150px; /*父元素添加內邊距將聖盃壓縮成形*/ } .main { background: green; width: 100%; height: 100px; } .left { background: red; width: 150px; height: 100px; } .right { background: blue; width: 100px; height: 100px; } </style>
由於目前左右兩部分都在內容的垂直排列,因此接下來須要給左中右三部分都添加一個左浮動,讓三個元素水平排在一塊兒,須要注意的是三個元素進行左浮動以後,左右兩個元素仍然在中間元素的下面,由於中間元素設置的寬度是100%,因此中間元素會佔滿父元素,因爲寬度沒法容下左右兩塊元素,因此左右兩塊元素會換行排列在一塊兒,如:
<style> .main { float: left; /*讓三個元素水平排列在一塊兒*/ } .left { float: left; /*讓三個元素水平排列在一塊兒*/ } .right { float: left; /*讓三個元素水平排列在一塊兒*/ } </style>
此時左中右三個元素能夠看作是水平排列在一塊兒的,咱們能夠經過給左右兩塊元素設置一個負的margin-left便可讓左右兩塊元素向左邊移動。左側元素須要到最左邊去,故其margin-left值爲-100%,即中間元素的寬度,右側元素須要到最右邊去,故其margin-left值爲負的右側元素自身寬度。
<style> .left { margin-left: -100%; /*將左側元素移動中間元素的寬度,到最左邊去*/ } .right { margin-left: -100px; /*將右側元素移動負的自身寬度,到最右邊去*/ } </style>
此時已經能夠看到左中右三個元素水平排列在一塊兒,而且左側元素在最左邊,右側元素在最右邊,可是左側元素其實應該是要在左側黃色區域中,右側元素應該在右側黃色區域中才對,因此咱們須要給左右兩個元素一個相對定位。左側元素再向左移動自身寬度的距離,故其left值爲負的左側元素自身寬度,右側元素須要右側移動自身寬度的距離,故其right值爲負的右側元素自身寬度。
<style> .left { position: relative; /*設置一個相對定位*/ left: -150px; /*相對於當前位置向左移動負的自身寬度*/ } .right { position: relative; /*設置一個相對定位*/ right: -100px; /*相對於當前位置向右移動負的自身寬度*/ } </style>
接下來咱們調整瀏覽器的寬度,發現元素髮生了佈局錯亂,由於當瀏覽器寬度特別小的時候,容器元素也會跟着變小,而左側元素因爲是浮動的,左側元素要想上來,必須向左移動一個負的自身寬度,因爲左側元素的margin-left值爲-100%,即移動了容器的可用內容寬度,當容器的可用內容寬度小於左側元素的寬度的時候(容器的100%值 < 左側元素的自身寬度),左側元素將沒法浮上來,只能換行顯示。
而要想解決這個問題,咱們就須要給容器設置一個最小寬度,這個最小寬度值怎麼定呢?左側元素要想不換行顯示,那麼容器的寬度必須可以容納左側元素的大小,因此容器內容區的最小值爲左側元素的寬度。
.container { min-width: 150px; /*給容器設置一個最小寬度,值爲左側元素的寬度,防止換行顯示*/ }
完整樣式爲:
<style> .container { background: yellow; height: 100px; padding: 0px 100px 0px 150px; /*父元素添加內邊距將聖盃壓縮成形*/ min-width: 150px; /*給容器設置一個最小寬度,值爲左側元素的寬度,防止換行顯示*/ } .main { background: green; width: 100%; height: 100px; float: left; /*讓三個元素水平排列在一塊兒*/ } .left { background: red; width: 150px; height: 100px; float: left; /*讓三個元素水平排列在一塊兒*/ margin-left: -100%; /*將左側元素移動中間元素的寬度,到最左邊去*/ position: relative; /*設置一個相對定位*/ left: -150px; /*相對於當前位置向左移動負的自身寬度*/ } .right { background: blue; width: 100px; height: 100px; float: left; /*讓三個元素水平排列在一塊兒*/ margin-left: -100px; /*將右側元素移動負的自身寬度,到最右邊去*/ position: relative; /*設置一個相對定位*/ right: -100px; /*相對於當前位置向右移動負的自身寬度*/ } </style>
② 雙飛翼佈局
<div class="container"> <div class="main"> <div class="content">雙飛翼佈局</div> </div> <div class="left">left</div> <div class="right">right</div> </div>
所謂雙飛翼佈局,就是給中間元素包裹一層div盒子,而後根據左右兩側元素的寬度,給中間內容元素設置一個左右外邊距,爲了方便記憶,咱們能夠理解成,給中間添加左右外邊距,就像給中間元素加裝了一雙翅膀,從而造成雙飛翼佈局。
<style> .container { background: yellow; height: 100px; } .main { width: 100%; } .content { background: green; height: 100px; margin-left: 150px; /*給中間元素添加一個左外邊距(翅膀)*/ margin-right: 100px; /*給中間元素添加一個右外邊距(翅膀)**/ } .left { background: red; width: 150px; height: 100px; } .right { background: blue; width: 100px; height: 100px; } </style>
一樣的,須要給左中右三部分都添加一個左浮動,讓三個元素水平排在一塊兒,如:
<style> .main { float: left; /*讓三個元素水平排列在一塊兒*/ } .left { float: left; /*讓三個元素水平排列在一塊兒*/ } .right { float: left; /*讓三個元素水平排列在一塊兒*/ } </style>
一樣的,須要給左側添加一個負的margin-left,值爲-100%,給右側添加一個負的margin-left,值爲負的右側元素自身寬度大小。
因爲以前中間元素已經設置好了左右外邊距給左右兩個元素留出了位置,因此添加margin-left以後就已經實現了。
<style> .left { margin-left: -100%; /*將左側元素移動中間元素的寬度,到最左邊去*/ } .right { margin-left: -100px; /*將右側元素移動負的自身寬度,到最右邊去*/ } </style>
一樣的爲了防止容器寬度過小致使左右兩個元素換行顯示,須要設置一個最小寬度。
.container { min-width: 400px; /*給容器設置一個最小寬度,值爲左側元素的寬度,防止換行顯示*/ }
完整樣式以下:
<style> .container { background: yellow; height: 100px; min-width: 400px; /*給容器設置一個最小寬度,值爲左側元素的寬度,防止換行顯示*/ } .main { float: left; width: 100%; } .content { background: green; height: 100px; margin-left: 150px; /*給中間元素添加一個左外邊距(翅膀)*/ margin-right: 100px; /*給中間元素添加一個右外邊距(翅膀)**/ } .left { background: red; width: 150px; height: 100px; float: left; margin-left: -100%; /*將左側元素移動中間元素的寬度,到最左邊去*/ } .right { background: blue; width: 100px; height: 100px; float: left; margin-left: -100px; /*將右側元素移動負的自身寬度,到最右邊去*/ } </style>
③ Flex實現三列布局
Flex實現三列布局相對簡單些,就是將父容器設置爲flex容器,中間元素設置flex值爲1,讓其自適應剩餘寬度,將左右元素設置爲禁止縮小,即flex-shrink值設置爲0.
<div class="container"> <div class="left">left</div> <div class="main">flex三列布局</div> <div class="right">right</div> </div>
<style> .container { background: yellow; height: 100px; display: flex; /*將父容器設置爲flex佈局*/ } .main { background: green; height: 100px; flex: 1; /*自適應剩餘寬度*/ min-width: 150px; /*給中間元素設置一個最小寬度防止過分縮放致使佈局錯亂*/ } .left { background: red; width: 150px; height: 100px; flex-shrink: 0; /*禁止縮小*/ } .right { background: blue; width: 100px; height: 100px; flex-shrink: 0; /*禁止縮小*/ } </style>
所謂粘連佈局,就是將頁面分紅上、中、下三個部分,上、下部分都爲固定高度,中間部分高度不定(但有一個最小高度爲瀏覽器高度),當頁面高度小於瀏覽器高度時,下部分應固定在屏幕底部,當頁面高度超出瀏覽器高度時,下部分應該隨中間部分被撐開,顯示在頁面最底部。
① margin-top + padding-bottom實現
首先佈局上將footer部分放到container容器下面,header和main放到container容器的中。
<div class="container"> <div class="header">header</div> <div class="main"> <h1>Sticky Footer粘連佈局</h1> <button id="add">添加內容</button> </div> </div> <div class="footer">footer</div> <script> const addButton = document.getElementById("add"); const main = document.querySelector(".main"); addButton.onclick = function() { const p = document.createElement("p"); p.innerText = "粘連佈局內容"; main.appendChild(p); } </script>
<style> * { padding: 0; margin: 0; } html, body { height: 100%; } .container { min-height: 100%; /*整個容器撐滿整個瀏覽器的高度*/ } .header { background: red; height: 100px; } .main { background: green; } .footer { background: blue; height: 100px; } </style>
目前因爲container容器設置了min-height爲100%,因此footer部分會被擠壓到瀏覽器底部的下面。接下來咱們就須要讓footer部分上移到瀏覽器的底部,能夠經過給footer設置一個margin-top,值爲負的footer自身高度。
.footer { margin-top: -100px; /*讓footer上移到瀏覽器的底部*/ }
此時點擊添加內容按鈕,添加一些內容,能夠看到添加的內容會覆蓋footer區域,如:
之因此出現這種狀況,是由於footer經過margin-top上移後只是覆蓋在了container上面,因此須要給container容器設置一個padding-bottom,將container容器的內容區上移。
* { box-sizing: border-box; /*將全部元素都定義成border-box邊框盒模型,很是重要*/ } .container { padding-bottom: 100px; /*將container的內容區向上移動footer高度的距離*/ }
須要注意的是,咱們給container容器添加padding-bottom以後,爲不影響整個container容器的高度,須要將container容器設置成邊框盒模型。
完整樣式代碼以下:
<style> * { padding: 0; margin: 0; box-sizing: border-box; /*將全部元素都定義成border-box邊框盒模型,很是重要*/ } html, body { height: 100%; } .container { min-height: 100%; /*整個容器撐滿整個瀏覽器的高度*/ padding-bottom: 100px; /*將container的內容區向上移動footer高度的距離*/ } .header { background: red; height: 100px; } .main { background: green; } .footer { background: blue; height: 100px; margin-top: -100px; /*讓footer上移到瀏覽器的底部*/ } </style>
② 經過flex佈局實現
佈局上有所不一樣,會將header、main和footer都放到container容器的中,並將container容器設置爲flex佈局,給container容器設置一個最小高度爲瀏覽器高度即100%,而後給中間部分設置flex值爲1,自適應將footer撐開到瀏覽器底部,等中間內容過多的時候就會將footer往下推。
<div class="container"> <div class="header">header</div> <div class="main"> <h1>Sticky Footer粘連佈局</h1> <button id="add">添加內容</button> </div> <div class="footer">footer</div> </div> <script> const addButton = document.getElementById("add"); const main = document.querySelector(".main"); addButton.onclick = function() { const p = document.createElement("p"); p.innerText = "粘連佈局內容"; main.appendChild(p); } </script>
<style> * { margin: 0; } html, body { height: 100%; } .container { min-height: 100%; /*給容器設置一個最小高度爲100%,以便將footer撐到底部*/ display: flex; /*將container容器設置成flex佈局*/ flex-direction: column; /*flex佈局的方向設置爲列*/ } .header { background: red; height: 100px; } .main { background: green; flex: 1; /*讓中間部分自適應,以便將footer撐到底部*/ } .footer { background: blue; height: 100px; } </style>