這多是史上最全的CSS自適應佈局總結教程

標題嚴格遵照了新廣告法,你再不爽,我也沒犯法呀!話很少說,直入正題。css

所謂佈局,其實包含兩個含義:尺寸與定位。也就是說,全部與尺寸和定位相關的屬性,均可以用來佈局。html

大致上,佈局中會用到的有:尺寸相關的盒子模型,普通流、浮動、絕對定位三種定位機制,CSS3中的transform、彈性盒子模塊、試驗中的grid模塊。逛園子的時候常常能夠看到浮動佈局,inline-block佈局,彈性盒佈局這幾個名詞。如今對佈局也算有一點了解,作個總結鞏固一下。若是你也看了不少資料,可是實際動手時對佈局仍是無從下手的話,但願本文能夠幫你理清思路。css3

嘮叨一句:看到一個效果圖的時候,千萬不要急着手賤去敲代碼!先思考清楚頁面的構造,理清各元素之間的關係,特別須要注意的是在不一樣的設備下須要有怎樣的展示,當你思路清晰找到最好的佈局方案時,coding其實真的不須要多少時間。瀏覽器

 

尺寸相關網絡


爲何要先說尺寸呢?由於尺寸在佈局中的做用很是核心,佈局方式定位這些只是改變了元素之間的關係,沒有尺寸就什麼也不是。好比咱們一般會用margin來控制跟其餘元素的距離,這就是佈局。ide

不少人都會以爲,什麼width、margin太簡單了,早就掌握了。這種心態我一開始學習CSS的時候也有,以爲很好理解很簡單,可是後面才發現本身原來不少東西都沒真正掌握。看看張鑫旭大神給咱們上的政治課:http://www.zhangxinxu.com/wordpress/2012/07/bottleneck-css-study/ wordpress

先說說百分比,百分比是相對父對象的,這裏特性很是好用,不少時候會用在自適應佈局上面。瀏覽器尺寸的改變,就是根節點html的長寬改變,咱們能夠用%來將瀏覽器尺寸和元素尺寸聯繫起來,作到自適應。函數

另一個比較有意思的是auto,auto是不少尺寸值的默認值,也就是由瀏覽器自動計算。首先是塊級元素水平方向的auto,塊級元素的margin、border、padding以及content寬度之和等於父元素width。使用auto屬性在父元素寬度變化的時候,該元素的寬度也會隨之變化。佈局

auto

可是當該元素被設爲浮動時,該元素的width就變成了內容的寬度了,由內容撐開,也就是所謂的有了包裹性。overflow | position:absolute | float:left/right均可以產生包裹性,替換元素也一樣具備包裹性。在具備包裹性的元素上想利用width : auto;來讓元素寬度自適應瀏覽器寬是不行的。學習

包裹性

高度方向:外邊距重疊,外邊距auto爲0,這兩點須要注意。書寫方向什麼的,接觸比較少就不扯了。

那爲何margin:auto對不能計算垂直方向的值呢?很簡單,垂直方向是被設計成能夠無限擴展的,內容越多瀏覽器便產生滾動條來擴展,因此垂直方向都找不到一個計算基準,以此返回一個false,便成了0。

用處:經過width、height控制大小,各個方向的margin值控制與邊界或者其餘元素的距離來定位。

 

浮動


目前PC網站大多使用float佈局,從成本上考慮大改的機率很小,因此不要說浮動無用,老是會有機會讓你維護的!表明網站:淘寶、騰訊、百度,好吧BAT都到齊了。

浮動聽得多了,博客園上關於用浮動佈局的介紹也很是的多。浮動本來用於文本環繞,但卻在佈局被髮揚光大,這就是命!個人理解:浮動佈局的核心就是讓元素脫離普通流,而後使用width/height,margin/padding將元素定位。脫離普通流的元素,就像脫離地心引力同樣,與普通流不在一個高度上。這個跟圖層的概念相似。高度不一樣因此能夠疊在其餘元素上面產生重疊或者使用負邊距跑到父元素外,理解了這一點浮動佈局就很好理解了。

圖層

下面用個聖盃佈局的例子說明一下,理解了這個以後其餘佈局更加簡單:

left,寬度固定,高度可固定也可由內容撐開
right,寬度固定,高度可固定也可由內容撐開
center,能夠自適應瀏覽器寬度,高度可固定也可由內容撐開。

HTML & CSS:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>寬度自適應佈局</title>
        <style>
            .wrap {
                background-color: #D66464;
            }
            .clearfix:after {
                content: "";
                clear: both;
                display: block;
            }
            .left {
                float: left;
                width: 100px;
                background: #00f;
                height: 180px;
            }
            .right {
                float: right;
                width: 150px;
                background: #0f0;
                height: 200px;
            }
            .center {
                background: #FFFFFF;
                margin-left: 110px;
                margin-right: 160px;
                height: 150px;
            }
        </style>
    </head>
    <body>
        <div class="wrap clearfix">
            <div class="left">left,寬度固定,高度可固定也能夠由內容撐開。</div>
            <div class="right">right,寬度固定,高度可固定也能夠由內容撐開。</div>
            <div class="center">center,能夠自適應瀏覽器寬度,高度可固定也能夠由內容撐開。</div>
        </div>
    </body>
</html>
View Code

原理很是簡單,左右側邊欄定寬並浮動,中部內容區放最後不浮動、默認width:auto並設置相應外邊距,讓左右側邊欄浮動到上面。注意:子元素設置爲浮動以後,父對象的高度就坍塌了,須要設置父對象後的元素清除浮動,這樣父對象的高度才能被浮動子元素撐起來了。

固然,咱們也要問一下,爲啥父對象高度會坍塌呢?上面也說過了,浮動元素已經脫離了普通流,父對象所在的普通流比喻成地表,那浮動元素就已經上天了。可是父對象還在地表啊,從外太空看浮動元素在父對象裏面,可是其實並不在,又怎麼能撐開父對象呢?寬度若是咱們不設置的話,其實也是爲0的,由於父對象裏面空空如也,因此寬高爲0。

上天

要撐開的辦法就兩個,1是讓父對象也上天(。。。你咋不上天呢),2是把浮動元素的邊框邊界拉下來。

父對象也上天(即浮動)的話,那就不能實現寬度自適應了。由於float元素的width:auto是包裹內容的,參考前面說的!

辦法2就是在後面的元素里加一個clear語句。說到這個問題就要扯到clear與BFC了,我就不獻醜了。傳送門:https://developer.mozilla.org/zh-CN/docs/Web/CSS/clear

這個三列布局還有個雙飛(是雙飛翼!想啥呢)的變種,就是在HTML中center部分也就是內容區提到最前面,也就是內容先行渲染。在網絡很差的時候,左右雙翼能不能出來沒關係,先讓主體內容出來!這種想法,明顯的優秀工程師思惟,但,尼瑪的雙翼都是廣告啊。廣告不出來,哪能賺錢養大家這羣工程師?因此提出雙飛的玉伯才離開了淘寶???(純屬意淫,如真屬實,當我扯淡,哈哈哈!)

哈哈哈

先上碼:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>寬度自適應佈局</title>
        <style>
            .wrap {
                background-color: #FBD570;
                margin-left: 100px;
                margin-right: 150px;
            }
            .clearfix:after {
                content: "";
                clear: both;
                display: block;
            }
            .left {
                float: left;
                width: 100px;
                background: #00f;
                height: 180px;
                margin-left: calc(-100% - 100px); 
            }
            .right {
                float: right;
                width: 150px;
                background: #0f0;
                height: 200px;
                margin-right: -150px;
            }
            .center {
                background: #B373DA;
                height: 150px;
                float: left;
                width: 100%;
            }
        </style>
    </head>
    <body>
        <div class="wrap clearfix">
            <div class="center">center,能夠自適應瀏覽器寬度,高度可固定也能夠由內容撐開。</div>
            <div class="left">left,寬度固定,高度可固定也能夠由內容撐開</div>
            <div class="right">right,寬度固定,高度可固定也能夠由內容撐開</div>
        </div>
    </body>
</html>
View Code

思路:

1)既然HTML裏面要讓center放前面,爲了讓left跑到center前面,那center也必須浮動了,不然由於都是塊元素他們會分兩行。

2)浮動以後還要讓center寬度自適應,那明顯width只能100%,而後在父元素中設width:auto,還有兩側margin,其實也就是父對象寬度自適應,center只是繼承content的寬度。

3)對left使用負的margin讓他們浮動到上方去。

代碼裏面我用到了一個calc(),這個CSS3帶來的計算函數簡直酷斃了!本例裏若是不使用calc函數,那麼就須要wrap左邊距爲0,left左邊距-100%,而後center多加一層子塊DIV設置margin-left:100px,能夠達到一樣的效果!calc函數與百分比配合就足以實現自適應的要求!目前全部的自適應佈局都在利用瀏覽器來爲咱們計算尺寸,可是有了calc以後咱們就能夠本身制定規則!單是想一想都高潮了吧?

總結:使用浮動來進行佈局,一個比較大的問題是清除浮動。這個可使用一個after僞類來清除。更大的問題是浮動性像水同樣向上流動,難以把握。在元素較多並且元素高度尺寸不一的狀況下,單純使用浮動只能實現上端對齊,這對於適應多種設備的佈局就顯得力不從心了。目前的作法是犧牲一部份內容,將元素作成等高排列,從美觀上看也固然也是極好的,比良莠不齊的排列要美觀。

 

普通流佈局


普通流佈局:display : inline-block!這是一個傳說中取代float佈局的存在。看了一些網站,PC端浮動爲主,移動端的也用的很少啊,已經有些使用flex的了,說好的inline-block一統江湖呢?

使用inline-block以前先處理點小障礙:inline-block元素會有4px左右的空隙,這個是由於咱們寫代碼時候的換行符所致。

4px間隙

解決辦法很簡單:在inline-block的父元素中設置樣式font-size:0;letter-spacing: -4px; 而後設置inline-block的全部兄弟元素 font-size:值;letter-spacing: 值px;  恢復正常的顯示。

消除4px間隙

另外還有一點須要注意的是inline-block默認是基線對齊的,而inline-block的基線又跟文本基線一致,因此在內容不一樣的時候並不能水平對齊。只須要用vertical-align顯式聲明一下top/bottom/middle對齊便可。這裏補充一下基線的內容,沒你想的那麼簡單哦。分有文字和無文字兩種狀況:

1)無文字:容器的margin-bottom下邊緣。與容器內部的元素沒一毛錢關係。

2)有文字:最後一行文字的下邊緣,跟文字塊(p,h等)的margin、padding不要緊!注意是最後一行,不管文字在什麼子對象容器內在什麼位置都不要緊,瀏覽器會找到最後一行文字對齊底部。

大家感覺一下:

baseline-01    baseline-02    baseline-03

警示:inline-block的基線是最後一行文字的底部,flex裏面的基線是第一行文字的底部(請看下文阮老師的文章)

baseline-04

滿滿的都是淚啊。。。既然都叫baseline,何須呢?

ohmygod

使用inline-block進行聖盃佈局:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>寬度自適應佈局</title>
        <style>
            .wrap {
                background-color: #FBD570;
                font-size: 0;
                letter-spacing: -4px;  /*用於兼容safari,根據不一樣字體字號或許須要作必定的調整*/
                margin-left: 100px;
                margin-right: 150px;
            }
            .wrap * {
                font-size: 1rem;
                letter-spacing: normal;
            }
            .left {
                display: inline-block;
                vertical-align: top;
                width: 100px;
                background: #00f;
                height: 180px;
                margin-left: -100px;
            }
            .right {
                display: inline-block;
                vertical-align: top;
                   width: 150px;
                background: #0f0;
                height: 200px;
                margin-right: -150px;
            }
            .center {
                display: inline-block;
                vertical-align: top;
                background: #B373DA;
                height: 150px;
                min-width: 150px;
                width: 100%;
            }
        </style>
    </head>
    <body>
        <div class="wrap">
            <div class="left">left,寬度高度固定</div>
            <div class="center">center,能夠自適應瀏覽器寬度,高度固定。</div>
            <div class="right">right,寬度高度固定</div>
        </div>
    </body>
</html>
View Code

這裏也沒什麼好說的,用到的也是width:auto和width:100%這兩點,簡單知識點的簡單用法。

雙飛的話,代碼跟聖盃的基本相同,注意在html的順序變爲center>right>left,只改左欄移動的margin-left: calc(-100% - 100px)到預約位置便可。不能用calc的話能夠在center裏面再加一層,跟浮動同樣的處理方式。更簡單的方法是使用CSS3帶給咱們的box-sizing屬性。請看代碼:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>寬度自適應佈局</title>
        <style>
            .wrap {
                background-color: #FBD570;
                font-size: 0;
                letter-spacing: -4px;  /*用於兼容safari,根據不一樣字體字號或許須要作必定的調整*/
                margin-right: 150px;
            }
            .wrap * {
                font-size: 1rem;
                letter-spacing: normal;
            }
            .left {
                display: inline-block;
                vertical-align: top;
                width: 100px;
                background: #00f;
                height: 180px;
                margin-left: -100%;
            }
            .right {
                display: inline-block;
                vertical-align: top;
                   width: 150px;
                background: #0f0;
                height: 200px;
                margin-right: -150px;
            }
            .center {
                display: inline-block;
                vertical-align: top;
                background: #B373DA;
                height: 150px;
                min-width: 150px;
                width: 100%;
                box-sizing: border-box;
                padding-left: 100px;
                background-origin: content-box;
                background-clip: content-box;
            }
        </style>
    </head>
    <body>
        <div class="wrap">
            <div class="center">
                center,能夠自適應瀏覽器寬度,高度固定。
            </div>
            <div class="right">right,寬度高度固定</div>
            <div class="left">left,寬度高度固定</div>
        </div>
    </body>
</html>
View Code

總結:相比浮動inline-block更加容易理解,也更符合咱們的認知,結合盒子模型的幾個控制屬性就能夠進行佈局了。對於元素高度不一樣的狀況,目前浮動佈局的作法都是將元素作成等高元素進行展示,這從美學上看也符合整齊的要求,不過犧牲了一部份內容。但inline-block有vertical-align屬性,能夠很好地解決元素高度不一樣而帶來的佈局問題。用過以後,你也會喜歡上inline-block的。。。至少我會!

 

絕對定位


前面的浮動和普通流中其實定位都是靠盒子模型控制的,與咱們常說的定位仍是有差異的。而絕對定位就是咱們日常所說的定位,給定參考座標系+座標肯定位置。關於絕對定位的資料太多,我就不說了。提一點就是absolute定位的基準是最近的非static定位父對象,而fixed是相對html根節點的定位。兩種定位都會脫離普通流,跟以前說的浮動同樣,上天了。

上天

固然,他們跟浮動在空間中的位置仍是有差異的,項目中有遇到這個問題的請參考張大嬸的文章: http://www.zhangxinxu.com/wordpress/2016/01/understand-css-stacking-context-order-z-index/  仍是要結合項目來看,不然看過也只是看過而已,並不會存到你的腦子裏,畢竟仍是至關抽象至關理論性的東西。借用張大神的一個總結圖:

2016-01-07_223349

使用絕對定位(特指absolute)作自適應佈局跟前面兩種方式沒太大差異,寬度自適應仍是在auto和100%上作文章,而位置則由top/bottom/left/right等控制。仍是以聖盃佈局來舉例:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>寬度自適應佈局</title>
        <style>
            .wrap {
                position: relative;
                background-color: #FBD570;
                margin-left: 100px;
                margin-right: 150px;
                height: 250px;
            }
            .left {
                position: absolute;
                top: 0;
                left: -100px;
                width: 100px;
                background: #00f;
                height: 180px;
            }
            .right {
                position: absolute;
                top: 0;
                right: 0;
                   width: 150px;
                background: #0f0;
                height: 200px;
                margin-right: -150px;
            }
            .center {
                position: absolute;
                top: 0;
                left: 0;
                background: #B373DA;
                height: 150px;
                min-width: 150px;
                width: 100%;
            }
        </style>
    </head>
    <body>
        <div class="wrap">
            <div class="center">
                center,能夠自適應瀏覽器寬度,高度固定。
            </div>
            <div class="left">left,寬度高度固定</div>
            <div class="right">right,寬度高度固定</div>
        </div>
    </body>
</html>
View Code

父元素爲relative,子元素爲absolute,這樣的話,又會出現跟浮動同樣的問題:父對象高度坍塌,子元素不能撐起父對象。緣由也跟浮動同樣,解決辦法的話目前我知道的只有給父對象指定一個肯定height值,你們若是有更好的辦法,請聯繫我!

總結:單純使用絕對定位進行自適應佈局的狀況不多,通常絕對定位都用在尺寸固定的元素定位上。並且fixed定位的渲染效率很低,由於它會頻繁觸發瀏覽器的重排。另外提一點:CSS3的transform會對絕對定位產生影響哦~好比說讓fixed定位再也不固定在瀏覽器視窗的黑魔法:http://www.zhangxinxu.com/wordpress/2015/05/css3-transform-affect/ 

 

彈性盒子


CSS3中對佈局影響最大的莫過於彈性盒子模塊了,這是一套區別於以往盒子模型佈局的全新方案。上面幾種方法你能夠看到,爲了實現自適應咱們用的都是width:auto和100%的嵌套以及各類邊距的移動定位,這套規則並不符合咱們的認知。爲何不能開拓出一塊區域,橫豎排列均可以,內部全部元素的尺寸能夠按照一個規則和這個區域的大小聯繫起來?終於CSS3作出了改變,引入了flex彈性佈局方案,彈性盒佈局有以下優點:
       1.獨立的高度控制與對齊。
       2.獨立的元素順序。
       3.指定元素之間的關係。
       4.靈活的尺寸與對齊方式。

在MDN上有很是簡單易懂的基礎教程https://developer.mozilla.org/zh-CN/docs/Web/CSS/CSS_Flexible_Box_Layout/Using_CSS_flexible_boxes

flexbox

上面也已經給出了聖盃佈局的自適應佈局方案,因此代碼就不貼了不過這個例子實現的是3欄成比例縮放,左右欄若是須要固定值的話能夠寫成  flex: 0 0 150px; 的樣式。

可是上面的教程沒有給出各個屬性的詳細解釋,建議看看阮一峯的博文,詳細易懂並且配圖超漂亮的有木有:http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html

總結:彈性盒子在移動端的應用會愈來愈廣泛,這套模型值得去好好研究。語法規則都是很是貼近人性,很是靈活,瀏覽器兼容性也很是好,固然國內百花齊放的移動瀏覽器會有哪些大坑呢?咱們拭目以待~

 

其餘


其餘包括position:relative和CSS3中的transform均可以實現定位,可是因爲他們在原來的普通流中還佔着一個坑,因此不多用來佈局啥的。transform是個很酷炫的東西,能夠用平面的素材作出不少3D的效果,並且不須要js就能夠作,很是好玩。此文已經很長,就很少說了,之後會寫一篇文章來專門說說她的故事。

 

總結以上!文字太多,放個圖片來調和下~~~以爲不錯的同窗,請點贊!以爲錯了的同窗,請聯繫我!

照片 1556_副本

(圖片出處:著名攝影師 小楊同窗,轉載請註明)

 原創文章,轉載請註明出處!本文連接:http://www.cnblogs.com/qieguo/p/5421252.html 

相關文章
相關標籤/搜索