[TOC]css
沒錯,題目就是模仿《那些年,咱們一塊兒清除過的浮動》而來的。html
相信不少人和我在學習前端差很少的時候就據說過了聖盃佈局與雙飛翼佈局。關於取名無非是以爲長得像聖盃,或者是長得像小鳥。至於其中的區別也只有一小點,其中主要的思想可謂是基本一致!前端
這兩個佈局要實現的樣式都是下面的這種形式:git
也就是中間的那一部分,長得像聖盃或者是飛翔的小鳥,left 和 right 寬度已知,中間自適應填充。通常狀況下,若是這樣寫代碼,顯然是很好實現佈局的。github
<div class="head">head</div> <div class="content"> <div class="left">left</div> <div class="main">main</div> <div class="right">right</div> </div> <div class="foot">foot</div>
可是相應的按照 DOM 的加載順序,content 部分依次會加載 left、main、right。這對於有潔癖的人多是沒法忍受的,甚至是以爲不符合常理。工具
正常狀況下,咱們但願先加載的是主要部分,而後再開始加載 left 和 right 兩個相對來講不是很重要的東西。因此 HTML 代碼應該這樣寫:佈局
<div class="head">head</div> <div class="content"> <div class="main">main</div> <div class="left">left</div> <div class="right">right</div> </div> <div class="foot">foot</div>
另一方面來講,咱們倡導語義化的 HTML,也就是說在編寫 HTML 的時候不該該受制於 CSS 的干擾,因此這樣的寫法來達到上面的佈局也應該是必要的。學習
那麼若是這樣寫應該如何去寫 CSS 樣式呢?spa
首先咱們的想法多是先搭建起 head content 和 foot,content 裏面的東西所有用左浮動解決,對 content 要清除浮動讓他撐起高度。代碼以下:3d
* { margin: 0; padding: 0; } .cleanfix { clear: both; } .cleanfix:after { content: '.'; clear: both; display: block; visibility: hidden; height: 0; zoom: 1; } .head, .foot { width: 100%; height: 80px; } .head { background-color: #4eb5f7; } .foot { background-color: #999999; } .left, .right, .main { float: left; } .left { width: 40px; height: 60px; background-color: #B9E078; } .right { width: 60px; height: 80px; background-color: #FF9900; } .main { background-color: crimson; }
這樣的話就能實現下面的佈局:
咱們要的目的是 main 佈局自適應,這樣的話咱們給 main 100% 的寬度:
.main { 100%; }
這樣的話佈局就會變成這樣:
接下來,咱們想要 left 跑上去,這個時候就可使用奇妙的負邊距了。
main, left, right 咱們均可以看作是在一個浮動流中,依次的順序也是 main left right。目前是由於 main 佔了100% 從而致使 left 與 right 不能和 main 浮在同一行了,這個時候咱們能夠利用負邊距來讓 left 向前移動 (即 margin-left 爲正的時候就是和左邊的盒子的外邊距,那麼爲負的時候就是像前移動了)。加上下面的特技
.left { margin-left: 100%; }
那麼移動多少呢?爲了讓 left 跑到最左邊,那麼就像上面的同樣移動到 -100% ,也就是向左移動的最大值了。這樣,會獲得下面的佈局:
咱們看到 left 移動到最左邊了,那 right 是否是也能夠模仿 left 一塊兒移動呢?移動多少?right 只須要向前移動right的寬度個距離,即 60px
.right { margin-left: -60px; }
獲得下面的結果
和咱們想象中的同樣, right 也移動上去了,而且跑到了咱們想要的位置。
可是稍微細心點就能發現上面的結果仍是存在問題的,紅色中間部分的 main 跑到哪裏去了?
打開開發者工具審查元素就能看見好像是 left 和 right 覆蓋到上面去了。
那麼如何去使得 main 部分往裏面收收呢?這也就是聖馬布局與雙飛翼佈局根本區別了
聖盃佈局的思想就是給包裹着三個元素的 content 加一個 padding, 讓 padding-left 和 padding-right 的數值是 left 和 right 的寬度,而後利用相對定位把他們再移動在兩旁。
首先,給 content padding
.content { padding: 0 60px 0 40px; }
而後利用相對定位移動 left 和 right
.left { position: relative; left: -40px; } .right { position: relative; right: -60px; }
這樣也就完美的解決了問題:
最後 CSS 的全部樣式是這樣的:
* { margin: 0; padding: 0; } .cleanfix { clear: both; } .cleanfix:after { content: '.'; clear: both; display: block; visibility: hidden; height: 0; zoom: 1; } .head, .foot { width: 100%; height: 80px; } .head { background-color: #4eb5f7; } .foot { background-color: #999999; } .left, .right, .main { float: left; } .left { width: 40px; height: 60px; background-color: #B9E078; margin-left: -100%; } .right { width: 60px; height: 80px; background-color: #FF9900; margin-left: -60px; } .main { background-color: crimson; width: 100%; } .content { padding: 0 60px 0 40px; } .left { position: relative; left: -40px; } .right { position: relative; right: -60px; }
HTML 是這樣的:
<div class="head">head</div> <div class="content cleanfix"> <div class="main">main</div> <div class="left">left</div> <div class="right">right</div> </div> <div class="foot">foot</div>
延續到上面的狀況,聖馬布局是這樣作的
聖馬布局的思想就是給包裹着三個元素的 content 加一個 padding, 讓 padding-left 和 padding-right 的數值是 left 和 right 的寬度,而後利用相對定位把他們再移動在兩旁。
而雙飛翼佈局是在 main 裏面再添加一個 div, 而後對這個 div 進行 margin-left 和 margin-right. 即
<div class="head">head</div> <div class="content cleanfix"> <div class="main"> <div class="wrap">main</div> </div> <div class="left">left</div> <div class="right">right</div> </div> <div class="foot">foot</div>
CSS 部分對 wrap 進行處理:
.wrap { background-color: darkmagenta; margin-left: 40px; margin-right: 60px; }
最後咱們的CSS代碼是這樣的:
* { margin: 0; padding: 0; } .cleanfix { clear: both; } .cleanfix:after { content: '.'; clear: both; display: block; visibility: hidden; height: 0; zoom: 1; } .head, .foot { width: 100%; height: 80px; } .head { background-color: #4eb5f7; } .foot { background-color: #999999; } .left, .right, .main { float: left; } .left { width: 40px; height: 60px; background-color: #B9E078; margin-left: -100%; } .right { width: 60px; height: 80px; background-color: #FF9900; margin-left: -60px; } .main { background-color: crimson; width: 100%; } .wrap { background-color: darkmagenta; margin-left: 40px; margin-right: 60px; }
總結一下,聖馬布局和雙飛翼的流程大致上是這樣的
搭建 head content foot, content 內部的三個元素所有左浮動,而後清除浮動防止影響 foot
給 main 100% 的寬度讓他佔滿一行
給 left -100% 的margin-left 讓他移動到最左邊,給 right 和他寬度同樣的負 margin 讓他移動到最右邊
針對移動後 main 的兩邊會被 left 和 right 重合覆蓋掉作出不一樣的改變,這兒也就是兩個佈局的本質區別
聖盃佈局會給 content 內邊距,左右分別爲 left 和 right的寬度,而後再利用相對定位移動 left 和 right
雙飛翼佈局會在 main 裏面再加一層 wrap ,而後把內容都寫在 wrap 裏面,正對 wrap 設置他的 margin, 左右外邊距和 left 與 right 同樣
相信在上面的聖馬布局與雙飛翼佈局中已經見識到了負邊距的奇妙之處了,這就是他的第一奇妙之處
整個浮動能夠看是有一個浮動流的存在,利用負邊距可讓他在這個流中移動,而且會疊加到相應元素的上面
普通元素的位置是相對於文檔流而發生變化的。負邊距也會使元素在文檔流中發生位移。不一樣於相對定位的是,這些元素移動以後不會佔據原來的空間。他往前移動以後,文檔流也會跟着移動
負邊距能夠增長元素的寬度,對於沒有 width 的元素,負邊距能夠加寬他們。
這樣就可以很好的利用負邊距實現 一寸照片排列 的那種難題了。對於這種問題,比較麻煩的辦法是浮動以後 margin-right, 而後對每一行的最後一個元素設置 margin-right: 0。這樣就存在一個如何給最後一個元素設定這個margin-right的問題了。
利用負邊距,咱們能夠加大子元素的margin, 而後浮動裏面全部的元素,等他們都浮動起來的時候利用 overflow: hidden消除最右邊的邊距。
絕對定位就是相對於父親系元素的最近的一個定位元素的邊界來決定的,這個邊界也就是margin。
若是是負邊距的話就能機智的實現元素垂直水平居中了
.con { width: 100px; height: 100px; position: absolute; top: 50%; left: 50% margin-left: -50px; margin-top: -50px; }
https://github.com/rccoder/blog/issues/6
歡迎 start 與 watch