css-inline-block和float的佈局兩者擇其一?

幾個月前,帶着不甘和忐忑毅然決然的在亞馬遜離職了,當時不知道對我來講是好是壞,如今看來,當初的選擇仍是蠻不錯的。感受在亞馬遜的幾個月貌似接觸最多的就是wiki和tt了,懷着對技術熱忱離開,拒絕了騰訊,搜狐和鳳凰網,最後來到了經緯系下的一家創業公司,開啓了創業潮!我的在title和technology兩方面對比仍是更喜歡後者吧,反正還沒畢業,路還長着呢,好了言歸正傳!!!css

inline-block屬性:

最近和boss直聘的前端leader吃飯,說到了佈局的問題,其實css佈局仍是挺容易讓人入坑的,由於不少頁面的html/css的佈局不合理就回致使整個頁面要用不少js來彌補你樣式的坑,而且極可能在不通設備下樣式直接亂掉。而通常前端工程師最經常使用的佈局是float佈局,聊到這裏,基本上咱們意見一致,那就是能用inline-block就儘可能少用float或position!!!緣由很簡單,就是float高度塌陷有的時候會致命!!!html

下面咱們來講一下inline-block的那些坑:

咱們來先寫這樣一段代碼前端

<!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佈局,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實現原理就是這樣子設計的!

相關文章
相關標籤/搜索