幾個月前,帶着不甘和忐忑毅然決然的在亞馬遜離職了,當時不知道對我來講是好是壞,如今看來,當初的選擇仍是蠻不錯的。感受在亞馬遜的幾個月貌似接觸最多的就是wiki和tt了,懷着對技術熱忱離開,拒絕了騰訊,搜狐和鳳凰網,最後來到了經緯系下的一家創業公司,開啓了創業潮!我的在title和technology兩方面對比仍是更喜歡後者吧,反正還沒畢業,路還長着呢,好了言歸正傳!!!css
最近和boss直聘的前端leader吃飯,說到了佈局的問題,其實css佈局仍是挺容易讓人入坑的,由於不少頁面的html/css的佈局不合理就回致使整個頁面要用不少js來彌補你樣式的坑,而且極可能在不通設備下樣式直接亂掉。而通常前端工程師最經常使用的佈局是float佈局,聊到這裏,基本上咱們意見一致,那就是能用inline-block就儘可能少用float或position!!!緣由很簡單,就是float高度塌陷有的時候會致命!!!html
咱們來先寫這樣一段代碼前端
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <link rel="stylesheet" href="css/hjk.css"> <style> .inlineBlock{ display: inline-block; width: 200px; height: 200px; background: red; border:1px solid #666; } </style> </head> <body> <div class='inlineBlock'></div> <div class='inlineBlock'></div> </body> <script> </script> </html>
咱們來看一下效果:git
我勒個去,中間的哪一個間距是什麼鬼?chrome
咱們知道inline-block元素實際上是一個具備區塊元素,又具備內斂元素的一個元素!!bootstrap
好繞:其實inline-block就是不佔據一行的塊狀元素!前端工程師
那麼咱們怎麼去解決呢?其實解決的方法挺多,知道的空白的元素是inline-block默認的空格符,那麼咱們能夠這樣解決dom
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <link rel="stylesheet" href="css/hjk.css"> <style> .inlineBlock{ display: inline-block; width: 200px; height: 200px; background: red; border:1px solid #666; } </style> </head> <body> <div class='inlineBlock'></div><div class='inlineBlock'></div> </body> <script> </script> </html>
看一下樣式:佈局
好了這個問題就解決了,其實還有別的寫法好比說:學習
<div class='inlineBlock'></div><!-- --><div class='inlineBlock'></div>
或者說:
<div class='inlineBlock'> 我是內容</div><div class='inlineBlock'> 我是內容</div>
可是這種方法老是讓人看着頭疼,由於這個不符合正常html代碼的書寫,那麼咱們可能從css上面來決解這種問題麼?
首先咱們想到的確定是給第二個元素添加margin負,代碼以下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <link rel="stylesheet" href="css/hjk.css"> <style> .inlineBlock{ display: inline-block; width: 200px; height: 200px; background: red; border:1px solid #666; } .div2{ margin-left: -4px; } </style> </head> <body> <div class='inlineBlock div1'></div> <div class='inlineBlock div2'></div> </body> <script> </script> </html>
運行結果:
可是這種方法存在問題:
1.咱們佈局確定不少元素,不可能每一個都添加margin負這樣維護成本太大了
2.咱們線上代碼若是壓縮,那麼咱們就不存在哪一個4px的問題了,那麼咱們的margin負就回形成佈局混亂!
哪麼難道不能用css來解決這個問題麼?
還有一種方法仍是這種方法也有缺點
咱們給元素加一個container而後設置font-size爲0就能解決這個問題,而後根據咱們每一個佈局模塊想要的font-size在本身添加font-size
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <link rel="stylesheet" href="css/hjk.css"> <style> .container{ font-size: 0; } .inlineBlock{ display: inline-block; width: 200px; height: 200px; background: red; border:1px solid #666; font-size: 12px; } </style> </head> <body> <div class="container"> <div class='inlineBlock div1'></div> <div class='inlineBlock div2'></div> </div> </body> <script> </script> </html>
這樣子咱們也能獲得咱們想要的結果,可是其中利弊本身體會!
因此每一種方法都有優缺利弊,我的仍是喜歡註釋法,壓縮上線也不會有問題,也比較推薦這個!
好了咱們繼續,下面若是咱們給div內部加文字會怎麼樣呢?
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <link rel="stylesheet" href="css/hjk.css"> <style> .container{ font-size: 0; } .inlineBlock{ display: inline-block; width: 200px; height: 200px; background: red; border:1px solid #666; font-size: 12px; } </style> </head> <body> <div class="container"> <div class='inlineBlock div1'></div> <div class='inlineBlock div2'>我是內容</div> </div> </body> <script> </script> </html>
效果以下:
我勒個擦,我就加了個文字,這是什麼鬼——,怎麼莫名其表的還掉下來了?
其實這個問題主要的緣由是由於咱們默認的文字對齊是baseline,基線對齊,因此咱們的inline-block元素就會出現這樣的問題!
咱們改一下html代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <link rel="stylesheet" href="css/hjk.css"> <style> .inlineBlock{ display: inline-block; width: 200px; height: 200px; background: red; border:1px solid #666; font-size: 12px; } </style> </head> <body> <div> 我是container內容 <div class='inlineBlock div1'></div><!-- --><div class='inlineBlock div2'>我是div2內容</div> </div> </body> <script> </script> </html>
效果以下:
也就是說咱們如今全部inline內容都是跟container的基線對齊的由於div2內部加入了inline,因此整個元素都掉了下來基線對齊!可是爲何並非徹底的對齊呢?咱們如今來加入這樣一行代碼:
.inlineBlock{ line-height: 0; }
效果以下:
看到這裏你應該明白了吧,inline-block的元素,受line-height和vertical-align兩個元素的影響!(不明白vertical-align或二者的關係的同窗,建議先去學習一下)
那麼到這裏咱們的問題就好解決了
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <link rel="stylesheet" href="css/hjk.css"> <style> .inlineBlock{ display: inline-block; width: 200px; height: 200px; background: red; border:1px solid #666; font-size: 12px; vertical-align: top; } </style> </head> <body> <div> 我是container內容 <div class='inlineBlock div1'></div><!-- --><div class='inlineBlock div2'>我是div2內容</div> </div> </body> <script> </script> </html>
效果以下:
這樣咱們就實現了top線對齊,問題圓滿解決!
其實還有個容易的方法,只須要添加float,全部問題迎刃而解:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <link rel="stylesheet" href="css/hjk.css"> <style> .inlineBlock{ display: inline-block; width: 200px; height: 200px; background: red; border:1px solid #666; font-size: 12px; float: left; } </style> </head> <body> <div> <div class='inlineBlock div1'></div> <div class='inlineBlock div2'>我是div2內容</div> </div> </body> <script> </script> </html>
你看他倆靠的多近啊,尚未掉落的問題,可是由於float的高度塌陷問題又來了,刻刻~~~本身慢慢領悟!!
接下來咱們來看看float的問題,這裏咱們用到了盒模型,建議基礎很差的小夥伴學一學盒模型
其實float最開始出現就是爲了實現文字環繞效果,float以後高度塌陷,因此文字會環繞這你float的元素!注意是文字環繞,不是元素環繞!可是由於float元素的出現咱們大多數都比較喜歡用float佈局,float屬性就這樣子被濫用了,固然我也是其中的一員。雖然高度塌陷這個問題(不是bug)比較讓人頭疼,可是比起inline-block元素來講,我仍是更喜歡float的佈局方式!
首先咱們來講一下一種總體的warp佈局(這個和float無關),就拿咱們學校的官網舉例- -:
這種佈局(好比背景顏色想要#eee),首先的第一種想法確定是我先外層一個div,width爲100%,而後內部div設置class爲wrap,而後我給wrap一個固定的width,以後margin負居中,這種是人們最多見的,也是最經常使用的。可是這種方式我並不接受,第一外層div並無用出了設置了背景顏色,第二就是咱們margin負就必需要根據計算而來的margin負,若是改動width那麼margin負也要跟着改!
我我的比較推崇padding方式來實現這個佈局,既能減小沒必要要的dom元素,也能避免margin帶來的問題!
代碼以下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style> *{ padding: 0; margin: 0; } .container{ padding: 20px 40px 40px; height: 100px; background: #eee; } </style> </head> <body> <div class='container'> sdf </div> </body> </html>
效果以下:
咱們用padding來單體了以前的warp佈局,以後咱們給container內部添加一下浮動元素
css:
.fBox{ width: 25%; height: 200px; float: left; box-sizing: border-box; border:1px solid #000; }
dom:把container替換成
<div class='container'> <div class="fBox"></div> <div class="fBox"></div> <div class="fBox"></div> <div class="fBox"></div> <div class="fBoxc"></div> </div>
效果以下:
由於內部高度塌陷,因此float的元素並無撐開整個container,怎麼解決這個問題呢?咱們首先想到的確定是clear:both;清除浮動
代碼以下:
<div class='container'> <div class="fBox"></div> <div class="fBox"></div> <div class="fBox"></div> <div class="fBox"></div> <div class="fBoxc"></div> <div style='clear: both;'></div> </div>
效果以下:
這個問題雖然解決了,可是存在不少問題。
首先從html的原則來講咱們新增了一個空白div元素,這就違背了咱們堅守無用dom元素的原則了,其次咱們若是不少個浮動,那麼咱們須要給不少container內部最後一行清除浮動,這樣子整個頁面代碼會很混亂。
下面咱們來介紹第二種方法:
咱們去掉container的height高度添加overflow:hidden;
代碼以下:
.container{
padding: 20px 40px 40px;
background: #eee;
overflow: hidden;
}
html:
<div class='container'> <div class="fBox"></div> <div class="fBox"></div> <div class="fBox"></div> <div class="fBox"></div> <div class="fBoxc"></div> </div>
效果以下:
這個兼容性很是的好,並且確實可以撐起來整個container,可是存在很大的問題(本人就在這個屬性栽倒過)
1.不能使用position超出尺寸的會被隱藏
2.若是佈局已經內部float並不知道height有多大,千萬不要使用,由於若是height比你的設備的height還要大的時候,每次滑動頁面以前都會計算container的高度,因此也就是說滑動以前你須要點一下屏幕,他計算的事件雖然不少很短可是這個問題特別影響用戶體驗!
我曾經在學校給一家公司作活動需求,當時爲了方便用的這個屬性來兼容自動撐開container,當時也沒有本身的手機作一下測試,由於項目趕的比較急,而後在chrome上面測了一下沒問題就直接提交到git上了,結果當天晚上12點以前上線,公司測試並無測出咱們個overflow的問題,後來臨近12點的時候在線下忽然測出了這個問題,以後爲了兼容這個問題,我整個頁面的佈局所有大改,由於當時css比較渣,頁面混用了float和position,而後overflow自適應,再加上頁面比較複雜,因此我改頁面改到凌晨2點辦才修復這個bug,再加上當時ui那面也出了一點問題,因此整個活動延遲到次日中午12點上的線。沉痛的教訓!!!
下面我說一下我最推薦的一種方式,也是如今最主流的方式,京東淘寶都在用這個來決解浮動問題!就是經過委元素來清除浮動
代碼以下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style> *{ padding: 0; margin: 0; } .fBox{ width: 25%; height: 200px; float: left; box-sizing: border-box; border:1px solid #000; } .container{ padding: 20px 40px 40px; background: #eee; } .clearFix:after{ content:''; clear: both; display: table; } </style> </head> <body> <div class='clearFix container'> <div class="fBox"></div> <div class="fBox"></div> <div class="fBox"></div> <div class="fBox"></div> <div class="fBoxc"></div> </div> </body> </html>
效果以下:
這樣咱們就解決了浮動的問題,接下來咱們嘗試一下根據不一樣屏幕的尺寸來改變每一個li的width來實現移動端的自適應
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style> *{ padding: 0; margin: 0; } .fBox{ width: 50%; height: 200px; float: left; box-sizing: border-box; border:1px solid #000; } @media (min-width: 992px){ .fBox{ width: 25%; } } @media (max-width: 750px){ .fBox{ width: 100%; } } .container{ padding: 20px 40px 40px; background: #eee; } .clearFix:after{ content:''; clear: both; display: table; } </style> </head> <body> <div class='clearFix container'> <div class="fBox"></div> <div class="fBox"></div> <div class="fBox"></div> <div class="fBox"></div> <div class="fBoxc"></div> </div> <p>sdjfkjahskdfhjkhsdfhsdkfjhsdjkhf</p> </body> </html>
效果以下:
width:1200px
width:750px
width:600px
看到這個咱們可能給不一樣的media裏面添加不用的class設置不一樣的width百分比,這樣咱們只須要給一個元素添加這三個class就可以實現不用width尺寸的屏幕顯示不用的佈局!看到這裏你有沒有恍然大悟,沒錯bootstrap3的基本佈局原理與不一樣設備的class實現原理就是這樣子設計的!