inline-block、BFC、邊距合并

1. 在什么場景下會出現外邊距合并?如何合并?如何不讓相鄰元素外邊距合并?給個父子外邊距合并的范例

外邊距合并
外邊距合并指的是,當兩個垂直外邊距相遇時,它們將形成一個外邊距。合并后的外邊距的高度等于兩個發生合并的外邊距的高度中的較大者。
當一個元素出現在另一個元素上面時,第一個元素的下外邊距與第二個元素的上外邊距會發生合并。請看下圖:

外邊距合并

大體就是這樣,具體如下:

  • 前提
  1. 相鄰兄弟元素:
    相鄰兄弟元素的外邊距會合并(當靠后的元素 清除浮動時除外)。
  1. 父元素與第一個或最后一個子元素:
    如果塊元素的margin-top與它的第一個子元素的margin-top 之間沒有 border、padding、inline content、 clearance 來分隔,或者塊元素的 margin-bottom 與它的最后一個子元素的margin-bottom 之間沒有 border、padding、inline content、height、min-height、 max-height 分隔,那么外邊距會合并。
    空塊元素:
    如果塊元素的 margin-top 與 margin-bottom 之間沒有 border、padding、inline content、height、min-height 來分隔,那么它的上下外邊距將會合并。
  • 外邊距合并場景
  1. 同一父元素下垂直相鄰的兄弟元素;
  2. 父元素和子元素(下外邊距需要考慮相鄰);
  3. 兄弟元素和他們的子元素;
  4. 高度為0并且最小高度也為0,不包含常規文檔流的元素;

eg:
第一種情況:兄弟元素:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title></title>
    <style type="text/css" media="screen">
      .container {
        border: 1px solid;
        width: 300px;
        height: 300px;        /* 盒子高300px */
      }
      .div1 {
        width: 100px;
        height: 100px;
        background: rgba(0, 255, 255, 0.5);
        margin-bottom: 100px;    /* 下外邊距100px */
      }
      .div2 {
        width: 100px;
        height: 100px;
        background: rgba(255, 0, 255, 0.5);
        margin-top: 100px;      /* 上外邊距100px */
      }
    </style>
  </head>
  <body>
    <div class="container">
      <div class="div1">1</div>
      <div class="div2">2</div>
    </div>
  </body>
</html>

效果圖:

兄弟元素下邊距和上邊距合并

如圖,兩個子元素盒子高度為100px,container高300px,所以中間只有100px,即外邊距合并后的100px。

第二種情況,父元素與子元素的合并:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title></title>
    <style type="text/css" media="screen">
      * {
      margin: 0;
      padding: 0;
      }
      .container {
        /*border: 1px solid;*/       /* 將元素邊框去除,其他樣式不變 */
        width: 300px;
        height: 300px;
        margin-top: 100px;         /* 給div1的父元素加上外邊距100px */
      }
      .div1 {
        width: 100px;
        height: 100px;
        background: rgba(0, 255, 255, 0.5);
        margin-bottom: 100px;
        margin-top: 100px;         /*給div1加上外邊距100px */
      }
      .div2 {
        width: 100px;
        height: 100px;
        background: rgba(255, 0, 255, 0.5);
        margin-top: 100px;
      }
    </style>
  </head>
  <body>
    <div class="container">
      <div class="div1">1</div>
      <div class="div2">2</div>
    </div>
  </body>
</html>

效果圖:

父元素子元素合并

如圖所示,在其他樣式不變的情況下,父元素的上外邊距100px和div1的上外邊距100px發生了合并,最終為100px。

第三種情況,兄弟元素以及他們的子元素:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title></title>
    <style type="text/css" media="screen">
      * {
      margin: 0;
      padding: 0;
      }
      .ct1 {
        width: 300px;
        height: 300px;         
        margin-bottom: 95px;        /* ct1下外邊距95px */
      }
      .div1 {
        width: 100px;
        height: 100px;
        background: rgba(0, 255, 255, 0.5);
        margin-bottom: 100px;
      }
      .div2 {
        width: 100px;
        height: 100px;
        background: rgba(255, 0, 255, 0.5);
        margin-top: 100px;
        margin-bottom: 150px;      /* div2下外邊距150px */
      }
      .ct2 {
        width: 300px;
        height: 300px;
        margin-top: 90px;              /* ct2上外邊距90px */
        background: rgba(255, 255, 0, 0.5);
      }
    </style>
  </head>
  <body>
    <div class="ct1">
      <div class="div1">1</div>
      <div class="div2">2</div>
    </div>
    <div class="ct2"></div>
  </body>
</html>

效果圖:

父子元素未合并

如圖所示,出現了問題,雖然沒有border和padding的限制,但最終的外邊距是95px,而不是150px,為此在W3上找到了原因

bottom margin of a last in-flow child and bottom margin of its parent if the parent has 'auto' computed height

意思就是對于margin-bottom來說,父元素高度需為auto才能和子元素合并。不過經過摸索,發現除了auto還有min-height可以實現效果,不過min-height需要小于等于auto的高度,否則合并完會多出一部分多余的min-height值,所以解決方法就是:ct1的height需要改為min-height

      .ct1 {
        width: 300px;
        min-height: 300px;          /* height改為min-height */
        margin-bottom: 95px;        /* ct1下外邊距95px */
      }
正確示范

如圖所示,ct1和ct2之間的外邊距是150px,說明3個外邊距發生了合并,取了最大值150px。

第四種情況,高度為0并且最小高度也為0,不包含常規文檔流的元素:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title></title>
  </head>
  <style type="text/css" media="screen">
    div {
      text-align: center;
      line-height: 50px;
    }
    .div1 {
      background: rgba(0, 175, 255, 0.5);
      border: 1px solid;
    }
    .div2 {
      width: 100px;
      height: 50px;
      background: rgba(255, 213, 0,0.7);
    }
    .div3 {
      margin: 100px 0 -50px;
      height: 0;
      min-height: 0;
    }
  </style>
  <body>
    <div class="div1">
      <div class="div2">2</div>
      <div class="div3"></div>
    </div>
  </body>
</html>
空元素上下合并

如圖可以看出,空元素上下進行了合并,與div2的height數值相同為50px。

考慮多邊合并

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title></title>
  </head>
  <style type="text/css" media="screen">
    div {
      text-align: center;
      line-height: 50px;
    }
    .div1 {
      background: rgba(0, 175, 255, 0.5);
      border: 1px solid;
    }
    .div2,.div4 {
      width: 100px;
      height: 50px;
      background: rgba(255, 213, 0,0.7);
    }
    .div3 {
      margin: 100px 0 -50px;          /* 將height和min-height刪除,假設auto同樣可行 */
    }
    .div4 {
      margin-top: 100px;                  /* div4上外邊距為100px */
    }
  </style>
  <body>
    <div class="div1">
      <div class="div2">2</div>
      <div class="div3"></div>
      <div class="div4">4</div>          /* 增加div4 */
    </div>
  </body>
</html>

多邊距合并

發現了問題,當上下邊距合并后為50px,與div4合并的時候,100px大于50px,應該為100px外邊距,但是現在外邊距是50px,為什么?因為合并規律是:

在負外邊距的情況下,合并后的外邊距為最大正外邊距與最小負外邊距之和。

所以并不是根據嵌套合并,而是根據正負來合并,所以-50px和100px合并才得到50px的外邊距。


  • 如何合并
  1. 兩個相鄰的外邊距都是正數時,合并取兩者之間較大的值:
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title></title>
    <style type="text/css" media="screen">
      * {
      margin: 0;
      padding: 0;
      }
      .ct1 {
        width: 300px;
        min-height: 300px;
        margin-bottom: 95px;
        border: 1px solid;
      }
      .div1 {
        width: 100px;
        height: 100px;
        background: rgba(0, 255, 255, 0.5);
        margin-bottom: 100px;                        /* div1外邊距100px */
      }
      .div2 {
        width: 100px;
        height: 100px;
        background: rgba(255, 0, 255, 0.5);
        margin-top: 50px;                            /* div2外邊距50px */
      }
    </style>
  </head>
  <body>
    <div class="ct1">
      <div class="div1">1</div>
      <div class="div2">2</div>
    </div>
  </body>
</html>
正外邊距合并

2.兩個相鄰的外邊距都是負數時,合并取兩者絕對值的較大值:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title></title>
    <style type="text/css" media="screen">
      * {
      margin: 0;
      padding: 0;
      }
      .ct1 {
        width: 300px;
        min-height: 300px;
        margin-bottom: 95px;
        border: 1px solid;
      }
      .div1 {
        width: 100px;
        height: 100px;
        background: rgba(0, 255, 255, 0.5);
        margin-bottom: -50px;                  /* div1下外邊距為-50px */
      }
      .div2 {
        width: 100px;
        height: 100px;
        background: rgba(255, 0, 255, 0.5);
        margin-top: -1px;                /* div2下外邊距為-1px */
      }
    </style>
  </head>
  <body>
    <div class="ct1">
      <div class="div1">1</div>
      <div class="div2">2</div>
    </div>
  </body>
</html>
雙負外邊距合并

3.兩個外邊距一正一負時,合并為兩者的相加的和:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title></title>
    <style type="text/css" media="screen">
      * {
      margin: 0;
      padding: 0;
      }
      .ct1 {
        width: 300px;
        min-height: 300px;
        margin-bottom: 95px;
        border: 1px solid;
      }
      .div1 {
        width: 100px;
        height: 100px;
        background: rgba(0, 255, 255, 0.5);
        margin-bottom: 50px;             /* div1下外邊距為50px */
      }
      .div2 {
        width: 100px;
        height: 100px;
        background: rgba(255, 0, 255, 0.5);
        margin-top: -25px;                /* div2下外邊距為-25px */
      }
    </style>
  </head>
  <body>
    <div class="ct1">
      <div class="div1">1</div>
      <div class="div2">2</div>
    </div>
  </body>
</html>
一正一負外邊距

  • 防止相鄰元素外邊距合并
  1. 父子關系元素,給父元素加上padding或者border:
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title></title>
    <style type="text/css" media="screen">
      * {
      margin: 0;
      padding: 0;
      }
      .ct1 {
        width: 300px;
        min-height: 300px;
        border: 1px solid;
        margin-top: 100px;
      }
      .div1 {
        width: 100px;
        height: 100px;
        background: rgba(0, 255, 255, 0.5);
        margin-top: 50px;
      }
    </style>
  </head>
  <body>
    <div class="ct1">
      <div class="div1">1</div>
    </div>
  </body>
</html>
截斷外邊距合并

方法二:BFC:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title></title>
    <style type="text/css" media="screen">
      * {
      margin: 0;
      padding: 0;
      }
      .ct1 {
        width: 300px;
        min-height: 300px;
        margin-top: 100px;
        overflow: auto;       /* 創建BFC */
      }
      .div1 {
        width: 100px;
        height: 100px;
        background: rgba(0, 255, 255, 0.5);
        margin-top: 50px;
      }
    </style>
  </head>
  <body>
    <div class="ct1">
      <div class="div1">1</div>
    </div>
  </body>
</html>
BFC截斷父子元素外邊距合并
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title></title>
    <style type="text/css" media="screen">
      * {
      margin: 0;
      padding: 0;
      }
      .ct1 {
        width: 300px;
        min-height: 300px;
        margin-top: 100px;
        float: left;         /* BFC概念 */
      }
      .div1 {
        width: 100px;
        height: 100px;
        background: rgba(0, 255, 255, 0.5);
        margin-top: 50px;
      }
    </style>
  </head>
  <body>
    <div class="ct1">
      <div class="div1">1</div>
    </div>
  </body>
</html>

float阻止外邊距合并

諸如此類的,還有absolute定位inline-block,不再贅述。

2.相鄰元素:
情況一:inline-block,absolute截斷合并,具體情況如下:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title></title>
    <style type="text/css" media="screen">
    * {
      margin: 0;
      padding: 0;
    }
      .div1 {
        width: 150px;
        height: 150px;
        border: 1px solid;
        background: silver;
        margin-bottom: 100px;
        display: inline-block;         /* 用BFC,使渲染方式不同 */
      }
      .div2 {
        width: 150px;
        height: 150px;
        border: 1px solid;
        background: #efe0ce;
        margin-top: 100px;
      }
    </style>
  </head>
  <body>
    <div class="div1">1</div>
    <div class="div2">2</div>
  </body>
</html>

BFC阻止外邊距合并

情況二:一個常規文檔流元素的margin-bottom與它下一個常規文檔流的兄弟元素的margin-top會產生折疊,除非它們之間存在間隙:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title></title>
    <style type="text/css">
      .ct1 {
        border: 1px solid;
      }
      .div1 {
        height: 100px;
        width: 100px;
        background: pink;
        margin: 0 0 60px 0;
      }
      .div2 {
        float: left;
        height: 50px;
        width: 100px;
        background: rgba(0, 255, 255, 1);
        opacity: 0.4;
      }
      .div3 {
        height: 50px;
        width: 100px;
        background: rgba(255, 0, 255, 0.5);
        margin-top: 40px;
        clear: both;
      }
    </style>
  </head>
  <body>
    <div class="ct1">
    <div class="div1"></div>
    <div class="div2"></div>
    <div class="div3"></div>
  </div>
  </body>
</html>

Paste_Image.png

情況三
在之前介紹的邊距合并產生條件中,有介紹不能含有clearance,或者height,有相應演示,不再贅述。
情況四
空元素:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title></title>
    <style type="text/css">
      * {
        margin: 0;
        padding: 0;
      }
      .ct1 {
        width: 300px;
        height: 300px;
        background: rgba(255, 255, 0, 0.5);
        border: 1px solid;
      }
      .div1 {
        margin: 100px 0 50px 0;
        overflow: auto;              /* 用BFC */
      }
      .div2 {
        width: 100px;
        height: 100px;
        background: rgba(255, 0, 255, 0.5);
        margin-top: 50px;
      }
    </style>
  </head>
  <body>
    <div class="ct1">
      <div class="div1"></div>
      <div class="div2">

      </div>
    </div>
  </body>
</html>
空元素借助BFC阻止合并

如圖所示,可以借助BFC的概念讓height=0的元素上下不合并。


  • 父子外邊距合并樣例
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title></title>
    <style type="text/css" media="screen">
      * {
      margin: 0;
      padding: 0;
      }
      .ct1 {
        width: 300px;
        min-height: 300px;
        margin-top: 100px;
        background: rgba(255, 0, 0, 0.5);
      }
      .div1 {
        width: 100px;
        height: 100px;
        background: rgba(0, 255, 255, 0.5);
        margin-top: 50px;
      }
    </style>
  </head>
  <body>
    <div class="ct1">
      <div class="div1">1</div>
    </div>
  </body>
</html>
父子元素合并

補充
關于clearance

當浮動元素之后的元素設置clear以閉合相關方向的浮動時,根據w3c規范規定,閉合浮動的元素會在其margin-top以上產生一定的空隙(clearance,如下圖),該空隙會阻止元素margin-top的折疊,并作為間距存在于元素的margin-top的上方。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title></title>
    <style type="text/css">
      * {
        margin: 0;
        padding: 0;
      }
      .big-box {
        width: 100px;
        height: 100px;
        background: blue;
        margin: 20px 0;
      }
      .floatL {
        width: 80px;
        height: 80px;
        margin: 20px 0;
        background: rgba(0, 255, 0, 0.6);
        float: left;
      }
      .clear {
        width: 80px;
        height: 80px;
        margin: 40px 0;
        background: red;
        clear: both;
      }
    </style>
  </head>
  <body>
    <div class="wrapper overHid">
    <div class="big-box">non-float</div>
    <div class="middle-box green floatL">float left</div>
    <div class="middle-box red clear">clear</div>
</div>
  </body>
</html>
clearance

clearance原理

上面的圖中我們可以看到,我們為紅色塊盒設置的40px的margin-top(這里我們通過相同高度的陰影來將其可視化)好像并沒有對紫色塊盒起作用,而且無論我們怎么修改這個margin-top值都不會影響紅色塊盒的位置,而只由綠色塊盒的margin-bottom所決定。
通過w3c的官方規范可知,閉合浮動的塊盒在margin-top上所產生的間距(clearance)的值與該塊盒的margin-top之和應該足夠讓該塊盒垂直的跨越浮動元素的margin-bottom,使閉合浮動的塊盒的border-top恰好與浮動元素的塊盒的margin-bottom相鄰接。
可以得出這樣一個式子:r-margin-top + r-clearance = g-margin-top + g-height + g-margin-bottom

經判斷,這個例子是正確的,并且可以理解為,兩個元素中間含有clearance,那么將不會產生外邊距合并,且clearance不是個定值,是自然產生的。以此類推,min-height和height也是類似于這樣的原理使外邊距無法合并。


由于知識點比較零散,作如下整理

外邊距合并mindmanager

注意圖中防止合并里,創建BFC和直接利用浮動、絕對定位、inline-block不同,前者利用BFC獨立環境特性,后者利用各自屬性特性,區別在此,所以區分著寫;至于BFC,后面內容會有BFC的概念,此導圖內不再贅述。
附件:鏈接: http://pan.baidu.com/s/1dEEm8vR 密碼: qn91

參考
W3 Box model
MDN|CSS 外邊距合并
w3cschool 外邊距合并
深入理解BFC和Margin Collapse


2. 去除inline-block內縫隙有哪幾種常見方法?

原理:瀏覽器bug將inline-block元素標簽之間的縫隙視作文本。
** 去除方法**:
1.inline-block內縫隙是html中white-spacing屬性處理得到,所以可以刪除html中多余的空格來去除縫隙:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title></title>
    <style type="text/css">
      * {
        margin: 0;
        padding: 0;
      }
      #header {
        height: 50px;
        border-bottom: 1px solid #ccc;
      }
      .nav > li {
        display: inline-block;
        background: rgba(255, 0, 255, 0.5);
        line-height: 50px;
      }
    </style>
  </head>
  <body>
    <div id="header">
        <ul class="nav">
          <li>tag1</li>
          <li>tag2</li><li>tag3</li>       <!--產生原因,由于-->
          <li>tag4</li>
        </ul>
    </div>
  </body>
</html>
inline-block縫隙

或者還可以這樣寫:

  <body>
    <div id="header">
        <ul class="nav">
          <li>tag1</li
            ><li>tag2</li          
              ><li>tag3</li
                ><li>tag4</li>             <!--分隔開,不留間隙-->
        </ul>
    </div>
  </body>

2.或者用負外邊距實現去除效果,不過第一個元素會溢出元素框,需要單獨設置:

      .nav > li {
        display: inline-block;
        background: rgba(255, 0, 255, 0.5);
        line-height: 50px;
        margin-left: -8px;          /* 負外邊距 */
      }

負margin消除inline-block縫隙

3.可以用浮動屬性來去除縫隙,不過要記得用BFC將父元素撐開:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title></title>
    <style type="text/css">
      * {
        margin: 0;
        padding: 0;
      }
      #header {
        height: 50px;
        border-bottom: 1px solid #ccc;
      }
      .nav > li {
        display: inline-block;
        background: rgba(255, 0, 255, 0.5);
        line-height: 50px;
        float: left;
      }
      .nav {
        overflow: auto;                 /* 用BFC清除父元素浮動 */
        background: rgba(255, 255, 0, 0.7);
      }
    </style>
  </head>
  <body>
    <div id="header">
        <ul class="nav">
          <li>tag1</li>
          <li>tag2</li>
          <li>tag3</li>
          <li>tag4</li>
        </ul>
    </div>
  </body>
</html>
浮動清除縫隙

4.在父元素寫上font-size:0;消除空格占位符的大小以去除縫隙:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title></title>
    <style type="text/css">
      * {
        margin: 0;
        padding: 0;
      }
      #header {
        height: 50px;
        border-bottom: 1px solid #ccc;
      }
      .nav {
        background: rgba(255, 255, 0, 0.7);
        font-size: 0;                   /* 父元素消除縫隙空白占位符 */
      }
      .nav > li {
        display: inline-block;
        background: rgba(255, 0, 255, 0.5);
        line-height: 50px;
        font-size: 16px;
      }
    </style>
  </head>
  <body>
    <div id="header">
        <ul class="nav">
          <li>tag1</li>
          <li>tag2</li>
          <li>tag3</li>
          <li>tag4</li>
        </ul>
    </div>
  </body>
</html>
font-size:0消除縫隙

3. 父容器使用overflow: auto| hidden撐開高度的原理是什么?

  1. 首先看下overflow的相關內容:
    overflow屬性規定當內容溢出元素框時發生的事情。
    其屬性值為:
屬性值 描述
visible 默認值。內容不會被修剪,會呈現在元素框之外
hidden 內容會被修剪,修建部分是不可見的
scroll 內容會被修剪,但是瀏覽器會顯示滾動條以便查看其余的內容,且總是顯示滾動條
auto 如果內容溢出,則修剪,并顯示滾動條,不溢出不修剪不顯示滾動條
inherit 規定應該從父元素繼承 overflow 屬性的值,任何的版本的 Internet Explorer (包括 IE8)都不支持屬性值 "inherit"。
  1. 再來看看BFC的概念:

浮動元素和絕對定位元素,非塊級盒子的塊級容器(例如 inline-blocks, table-cells, 和 table-captions),以及overflow值不為“visiable”的塊級盒子,都會為他們的內容創建新的BFC(塊級格式上下文)。
在BFC中,盒子從頂端開始垂直地一個接一個地排列,兩個盒子之間的垂直的間隙是由他們的margin 值所決定的。在一個BFC中,兩個相鄰的塊級盒子的垂直外邊距會產生折疊。
首先BFC是一個名詞,是一個獨立的布局環境,我們可以理解為一個箱子(實際上是看不見摸不著的),箱子里面物品的擺放是不受外界的影響的。轉換為BFC的理解則是:BFC中的元素的布局是不受外界的影響(我們往往利用這個特性來消除浮動元素對其非浮動的兄弟元素和其子元素帶來的影響。)

可以看出,overflow本身并沒有什么特別之處,而是會產生BFC,創造獨立布局環境,使元素不受浮動元素的影響。
所以針對撐開父元素的情況,是由于父元素創建了BFC,使父元素形成獨立環境,從而浮動元素被包含在內,自然撐開。


4. BFC是什么?如何形成BFC,有什么作用?

在前一個問題里,將BFC的概念簡單說了下,以及它其中的一個作用——清除浮動的影響,撐開父元素。下面具體說說BFC的具體情況:

  1. 形成BFC:
  • 用float屬性(none值除外);
  • 用絕對定位absolute;
  • overflow(visible值除外);
  • display屬性為table-cell, table-caption, inline-block, flex, 或者inline-flex
  1. 作用:
  • 撐開父元素(見問題3);
  • 阻止外邊距合并(見問題1);
  • 清除浮動的文字環繞影響或位置影響

總結:BFC用法靈活,可以解決很棘手的問題,不過不是萬能的,具體問題具體分析(見題1)


5. 浮動導致的父容器高度塌陷指什么?為什么會產生?有幾種解決方法

高度塌陷是指,在父元素的height為0時,對其內部元素應用浮動屬性,浮動屬性使元素脫離文檔流,而父元素沒有元素可以支撐,從而高度塌陷,變為0。

首先不用浮動,導航欄效果如圖:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title></title>
    <style type="text/css">
      #header {
        border-bottom: 1px solid #ccc;
      }
      .nav {
        background: rgba(255, 255, 0, 0.7);
        border: 1px solid blue;
      }
      .nav > li {
        display: inline-block;
        background: rgba(255, 0, 255, 0.5);
        /*float: left;*/
      }
    </style>
  </head>
  <body>
    <div id="header">
        <ul class="nav">
          <li>tag1</li>
          <li>tag2</li>
          <li>tag3</li>
          <li>tag4</li>
        </ul>
    </div>
  </body>
</html>

導航欄

當我為了將inline-block屬性的縫隙去除時,采用浮動,效果如下:

      .nav > li {
        display: inline-block;
        background: rgba(255, 0, 255, 0.5);
        float: left;                   /* 子元素應用浮動 */
      }
浮動對父元素高度影響

可以看出父元素的藍色邊框變為了一條線,這是因為浮動之后子元素脫離文檔流,從而父元素高度塌陷。

解決方法
1.利用空元素清除浮動:

  • 第一種:在html中添加空元素:
 <!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title></title>
    <style type="text/css">
      #header {
        border-bottom: 1px solid #ccc;
      }
      .nav {
        background: rgba(255, 255, 0, 0.7);
        border: 1px solid blue;
      }
      .nav > li {
        display: inline-block;
        background: rgba(255, 0, 255, 0.5);
        float: left;
      }
      .clear {
        clear: both;
      }
    </style>
  </head>
  <body>
    <div id="header">
        <ul class="nav">
          <li>tag1</li>
          <li>tag2</li>
          <li>tag3</li>
          <li>tag4</li>
          <div class="clear"></div>
        </ul>
    </div>
  </body>
</html>
Paste_Image.png
  • 第二種,在CSS中創建空元素:
.nav:after {
        content: '';
        display: block;
        clear: both;
      }
偽類效果圖

2.使用BFC,使父元素按照BFC渲染,包含住浮動元素:

      .nav {
        background: rgba(255, 255, 0, 0.7);
        border: 1px solid blue;
        overflow: hidden;
      }
BFC清除浮動影響

如圖,父元素高度恢復正常,如果用其他BFC屬性也可以,不過有一定的副作用,下面來依次說明:

方法 說明
overflow 副作用最小,不過可能會不需要overflow的特性
absolute 收縮元素寬度,不易解決
float 收縮元素寬度,影響布局,可借助clear解決
inline-block 收縮元素寬度,不易解決

6. 以下代碼每一行的作用是什么? 為什么會產生作用? 和BFC撐開空間有什么區別?

.clearfix:after {
            content: '';
            display: block;
            clear: both;
        }
        .clearfix {
            *zoom: 1;
        }
未加代碼

加上代碼

如圖所示:
應用這個屬性,可以將父元素高度撐開,避免子元素浮動之后,父元素高度塌陷。

代碼 說明
.clearfix:after clearfix的after偽類選擇器,在元素最后應用屬性
content: ''; 內容為空
display: block; 表現為塊級元素,如果不表現,行內元素不會撐開父元素
clear: both; 清除兩邊浮動
*zoom: 1; IE專有屬性,縮放比例,也可用于檢查BUG,參數設為1的話,多用于清除浮動

關于zoom
這個屬性是IE專有屬性,其他瀏覽器沒有,它可以設置或檢索對象的縮放比,它還有其他一些小作用,比如觸發ie的hasLayout屬性,清除浮動、清除margin的重疊等。現在已經基本不用這個屬性,所以僅在考慮兼容的清除浮動會用到。


本文版權歸本人及饑人谷所有,轉載請注明來源。謝謝!

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容