任务十一~inline-block、BFC、边距合并

一、在什么场景下会出现外边距合并?如何合并?如何不让相邻元素外边距合并?给个父子外边距合并的范例

  • 在CSS当中,相邻的两个盒子(可能是兄弟关系也可能是祖先关系)的外边距可以结合成一个单独的外边距,相邻的两个盒子包括:
  • 相邻兄弟元素之间的合并
  • 父子元素之间的合并
  • 父子元素同时与其后元素的合并
  • 高度为0无内容的元素自身的合并
  • 合并的方式为:
  • 当两个外边距都是正数时,取两者中较大者
  • 当两个外边距一个为正数,一个为负数时,取两者之和
  • 当两个外边距都是负数时,取两者绝对值较大者
  • 针对以上各种情况,分别列举如何合并,如何不让相邻元素外边距合并
  • 两个相邻兄弟之间的外边距,比如如下情况
<!doctype html>
<html>
  <head>
      <meta charset="utf-8"/>
      <title>练习</title>
      <style>
          *{
              margin: 0;
              padding: 0;
          }
          body{
              background: #ccc;
          }
          .ct{
              width: 500px;
              margin: 0 auto;
              background: pink;
              border: 1px solid black;
          }
          .ct .box1{
              width: 100px;
              height: 100px;
              margin: 20px;
              border: 1px solid red;
          }
          .ct .box2{
              width: 100px;
              height: 100px;
              margin: 50px;
              border: 1px solid blue;
          }
      </style>
  </head>
  <body>
      <div class="ct">
          <div class="box1">1</div>
          <div class="box2">2</div>
      </div>
  </body>
</html>

此时效果图如下

相邻兄弟元素之间外边距的合并

如何不让相邻元素合并:(1)通过创造BFC环境可以消除兄弟相邻元素之间的外边距,如下所示代码

<!doctype html>
<html>
    <head>
        <meta charset="utf-8"/>
        <title>练习</title>
        <style>
            *{
                margin: 0;
                padding: 0;
            }
            body{
                background: #ccc;
            }
            .ct{
                width: 500px;
                margin: 0 auto;
                background: pink;
            }
            .ct .box1{
                display: inline-block;
                width: 100px;
                height: 100px;
                margin: 20px;
                border: 1px solid red;
            }
            .ct .box2{
                display: inline-block;
                width: 100px;
                height: 100px;
                margin: 50px;
                border: 1px solid blue;
            }
        </style>
    </head>
    <body>
        <div class="ct">
            <div class="box1">1</div>
            <div class="box2">2</div>
        </div>
    </body>
</html>

效果图如下图


创造BFC来消除兄弟元素之间外边距的合并

(2)当兄弟元素之间存在“界限”时也可以消除其之间的外边距的合并,如下所示代码

<!doctype html>
<html>
    <head>
        <meta charset="utf-8"/>
        <title>练习</title>
        <style>
            *{
                margin: 0;
                padding: 0;
            }
            body{
                background: #ccc;
            }
            .ct{
                width: 500px;
                margin: 0 auto;
                background: pink;
            }
            .ct>div{
                overflow: auto;
            }
            .ct .box1{
                width: 100px;
                height: 100px;
                margin: 20px;
                border: 1px solid red;
            }
            .ct .box2{
                width: 100px;
                height: 100px;
                margin: 50px;
                border: 1px solid blue;
            }
        </style>
    </head>
    <body>
        <div class="ct">
            <div>
                <div class="box1">1</div>
            </div>
            <div>
                <div class="box2">2</div>
            </div>
        </div>
    </body>
</html>

在相邻元素的外层在嵌套一层,在box1和box2之间形成一层界限,阻止了兄弟元素之间外边距的合并,效果图如下


相邻元素外边距
  • 父子元素之间的外边距合并,合并情况如下图所示情况
    父子元素之间外边距的合并

    如何不让相邻元素合并:(1)通过在div1的父元素上加上border或者padding即可消除父子元素之间外边距的合并,如下所示代码
<!doctype html>
<html>
 <head>
     <meta charset="utf-8"/>
     <title>练习</title>
     <style>
         *{
             margin: 0;
             padding: 0;
         }
         body{
             background: #ccc;
         }
         .ct{
             width: 500px;
             margin: 0 auto;
             background: pink;
             border:1px solid black;
             /*或者通过设置padding值
             padding: 10px;*/
         }
         .ct .box1{
             width: 100px;
             height: 100px;
             margin: 20px;
             border: 1px solid red;
         }
         .ct .box2{
             width: 100px;
             height: 100px;
             margin: 50px;
             border: 1px solid blue;
         }
     </style>
 </head>
 <body>
     <div class="ct">
         <div class="box1">1</div>
         <div class="box2">2</div>
     </div>
 </body>
</html>

效果图如下图


消除父子元素之间外边距的合并

(2)通过创造BFC的环境来消除父子元素之间的外边距的合并,如下所示代码

<!doctype html>
<html>
    <head>
        <meta charset="utf-8"/>
        <title>练习</title>
        <style>
            *{
                margin: 0;
                padding: 0;
            }
            body{
                background: #ccc;
            }
            .ct{
                width: 500px;
                margin: 0 auto;
                background: pink;
                overflow: auto;
                /*或者还可以通过定位,浮动,
              设置display值为inline-block等来是.ct成为BFC环境*/
            }
            .ct .box1{
                width: 100px;
                height: 100px;
                margin: 20px;
                border: 1px solid red;
            }
            .ct .box2{
                width: 100px;
                height: 100px;
                margin: 50px;
                border: 1px solid blue;
            }
        </style>
    </head>
    <body>
        <div class="ct">
            <div class="box1">1</div>
            <div class="box2">2</div>
        </div>
    </body>
</html>

效果图如下图


通过形成BFC来消除父子元素之间的外边距合并
  • 父子元素同时与其后元素的外边距合并合并,比如如下情况
    父子元素同时与其后元素的外边距合并

    如何不让父子元素同时与其后元素的外边距合并:(1)可以在父元素上设置border、padding值,比如如下代码
<!doctype html>
<html>
    <head>
        <meta charset="utf-8"/>
        <title>练习</title>
        <style>
            *{
                margin: 0;
                padding: 0;
            }
            body{
                background: #ccc;
            }
            .ct{
                width: 500px;
                margin: 0 auto 60px auto;
                background: pink;
                padding: 10px;
            }
            .ct .box1{
                width: 100px;
                height: 100px;
                margin: 20px;
                border: 1px solid red;
            }
            .ct .box2{
                width: 100px;
                height: 100px;
                margin: 50px;
                border: 1px solid blue;
            }
            h1{
                width: 500px;
                margin: 35px auto;
                background: orange;
            }
        </style>
    </head>
    <body>
        <div class="ct">
            <div class="box1">1</div>
            <div class="box2">2</div>
        </div>
        <h1>jirengu</h1>
    </body>
</html>

此时就只有父元素.ct同h1的外边距进行合并,效果图如下图


外边距合并效果图

(2)也可以使父元素成为BFC,也可消除父子元素同时与其后元素外边距的合并,比如如下代码

<!doctype html>
<html>
    <head>
        <meta charset="utf-8"/>
        <title>练习</title>
        <style>
            *{
                margin: 0;
                padding: 0;
            }
            body{
                background: #ccc;
            }
            .ct{
                width: 500px;
                margin: 0 auto 60px auto;
                background: pink;
                overflow: auto;
            }
            .ct .box1{
                width: 100px;
                height: 100px;
                margin: 20px;
                border: 1px solid red;
            }
            .ct .box2{
                width: 100px;
                height: 100px;
                margin: 50px;
                border: 1px solid blue;
            }
            h1{
                width: 500px;
                margin: 35px auto;
                background: orange;
            }
        </style>
    </head>
    <body>
        <div class="ct">
            <div class="box1">1</div>
            <div class="box2">2</div>
        </div>
        <h1>jirengu</h1>
    </body>
</html>

效果图如下图所示


外边距合并效果图
  • 高度为0无内容的元素自身外边距的合并,比如如下情况,一个宽高为0的块级元素,设置了margin值后其margin值自身合并,如下图
    自身元素外边距的合并

    自身元素外边距的不合并的方法:(1)可以在元素上加上border、padding等值,如下代码
<!doctype html>
<html>
    <head>
        <meta charset="utf-8"/>
        <title>练习</title>
        <style>
            *{
                margin: 0;
                padding: 0;
            }
            body{
                background: #ccc;
            }
            .ct{
                width: 500px;
                margin:10px;
                background: pink;
            }
            .ct .box1{
                width: 100px;
                height: 100px;
                margin: 20px;
                border: 1px solid red;
            }
            .ct .box2{
                width: 100px;
                height: 100px;
                margin: 40px;
                border: 1px solid blue;
            }
            .ct2{
                margin: 40px;
                padding: 1px;
            }
        </style>
    </head>
    <body>
        <div class="ct">
            <div class="box1">1</div>
            <div class="box2">2</div>
        </div>
        <div class="ct2"></div>
        <span>jirengu</span>
    </body>
</html>

效果图如下图所示,此时外边距的距离是80px


消除自身元素外边距合并的效果图

(2)可以使元素成为BFC,这样也可以阻止自身外边距的合并,如下代码

<!doctype html>
<html>
    <head>
        <meta charset="utf-8"/>
        <title>练习</title>
        <style>
            *{
                margin: 0;
                padding: 0;
            }
            body{
                background: #ccc;
            }
            .ct{
                width: 500px;
                margin:10px;
                background: pink;
            }
            .ct .box1{
                width: 100px;
                height: 100px;
                margin: 20px;
                border: 1px solid red;
            }
            .ct .box2{
                width: 100px;
                height: 100px;
                margin: 40px;
                border: 1px solid blue;
            }
            .ct2{
                margin: 40px;
                overflow: auto;
            }
        </style>
    </head>
    <body>
        <div class="ct">
            <div class="box1">1</div>
            <div class="box2">2</div>
        </div>
        <div class="ct2"></div>
        <span>jirengu</span>
    </body>
</html>

效果图如下图


使元素成为BFC从而阻止外边距的合并
  • 父子元素外边距合并例子如下
<!doctype html>
<html>
   <head>
       <meta charset="utf-8"/>
       <title>练习</title>
       <style>
           *{
               margin: 0;
               padding: 0;
           }
           body{
               background: #ccc;
           }
           header{
               background-color: pink;
           }
           h1{
               margin: 40px;
           }
       </style>
   </head>
   <body>
       <header>
           <h1>父子元素外边距合并</h1>
       </header>
   </body>
</html>

效果图如下


父子元素之间外边距的合并

解决办法已在第二点里详述,这里不再赘述


二、去除inline-block内缝隙有哪几种常见方法?

在把元素设置为inline-block时换行显示或空格分隔的时候会出现间距,比如


使用inline-block的间距

去除的方法如下:

  • 将html中的代码空格移除
<!doctype html>
<html>
   <head>
       <meta charset="utf-8"/>
       <title>练习</title>
       <style>
           *{
               margin: 0;
               padding: 0;
           }
           ul{
               list-style: none;
           }
           .ct{
               border:1px solid red;
               margin:200px auto 0 auto;
               width: 500px;
           }
           ul>li{
               display: inline-block;
               background: orange;
           }
       </style>
   </head>
   <body>
       <div class="ct">
           <ul>
               <li>111</li><li>222</li><li>333</li>
               <!--或者可以这样写
                <li>111</li
               ><li>222</li
               ><li>333</li> -->
           </ul>
       </div>
   </body>
</html>

效果图如下


移除代码空格去除inline-block内缝隙效果图
  • 使用负margin值
<!doctype html>
<html>
   <head>
       <meta charset="utf-8"/>
       <title>练习</title>
       <style>
           *{
               margin: 0;
               padding: 0;
           }
           ul{
               list-style: none;
           }
           .ct{
               border:1px solid red;
               margin:200px auto 0 auto;
               width: 500px;
           }
           ul>li{
               display: inline-block;
               background: orange;
               margin-left: -10px;
           }
           ul>li:first-child{
               margin: 0;
           }
       </style>
   </head>
   <body>
       <div class="ct">
           <ul>
               <li>111</li>
               <li>222</li>
               <li>333</li>
           </ul>
       </div>
   </body>
</html>

效果图如下

设置负margin值去除inline-block内缝隙效果图

注意:margin负值的大小与上下文的字体和文字大小相关,而且,发现chrome和firefox设置的值也不一样,在firefox中当负margin值设置为-10px,比如下图更多不同
负margin在firefox中的显示

此时,需要将firefox的负margin值设置为-5px才可以,如下图
设置负margin值去除inline-block内缝隙效果图

  • 使用浮动float
<!doctype html>
<html>
   <head>
       <meta charset="utf-8"/>
       <title>练习</title>
       <style>
           *{
               margin: 0;
               padding: 0;
           }
           ul{
               list-style: none;
           }
           .ct{
               border:1px solid red;
               margin:200px auto 0 auto;
               width: 500px;
               overflow: auto;
           }
           ul>li{
               float: left;
               background: orange;
           }
       </style>
   </head>
   <body>
       <div class="ct">
           <ul>
               <li>111</li>
               <li>222</li>
               <li>333</li>
           </ul>
       </div>
   </body>
</html>

效果图


设置float去除inline-block内缝隙效果图
  • 利用font-size为0
<!doctype html>
<html>
   <head>
       <meta charset="utf-8"/>
       <title>练习</title>
       <style>
           *{
               margin: 0;
               padding: 0;
           }
           ul{
               list-style: none;
           }
           .ct{
               border:1px solid red;
               margin:200px auto 0 auto;
               width: 500px;
               font-size: 0;
           }
           ul>li{
               display: inline-block;
               background: orange;
               font-size: 20px;
           }
       </style>
   </head>
   <body>
       <div class="ct">
           <ul>
               <li>111</li>
               <li>222</li>
               <li>333</li>
           </ul>
       </div>
   </body>
</html>

效果图


利用font-size为0去除inline-block内缝隙效果图
  • 利用letter-spacing
<!doctype html>
<html>
   <head>
       <meta charset="utf-8"/>
       <title>练习</title>
       <style>
           *{
               margin: 0;
               padding: 0;
           }
           ul{
               list-style: none;
           }
           .ct{
               border:1px solid red;
               margin:200px auto 0 auto;
               width: 500px;
               letter-spacing: -10px;
           }
           ul>li{
               display: inline-block;
               background: orange;
               letter-spacing: 0;
           }
       </style>
   </head>
   <body>
       <div class="ct">
           <ul>
               <li>111</li>
               <li>222</li>
               <li>333</li>
           </ul>
       </div>
   </body>
</html>

效果图

利用letter-spacing去除inline-block内缝隙效果图

注意:letter-spacing在chrome和firefox中不一样,在firefox中要将.ct{letter-spacing:-5px;}才可以

  • 利用word-spacing
<!doctype html>
<html>
   <head>
       <meta charset="utf-8"/>
       <title>练习</title>
       <style>
           *{
               margin: 0;
               padding: 0;
           }
           ul{
               list-style: none;
           }
           .ct{
               border:1px solid red;
               margin:200px auto 0 auto;
               width: 500px;
               word-spacing: -10px;
           }
           ul>li{
               display: inline-block;
               background: orange;
               word-spacing: 0;
           }
       </style>
   </head>
   <body>
       <div class="ct">
           <ul>
               <li>111</li>
               <li>222</li>
               <li>333</li>
           </ul>
       </div>
   </body>
</html>

效果图


利用word-spacing去除inline-block内缝隙效果图

三、父容器使用overflow: auto| hidden撑开高度的原理是什么?

  • overflow定义溢出元素内容区的内容会如何处理,其语法为overflow:auto | hidden | scroll | visible| inherit,其中值分别表示
  • auto表示如果内容被修剪,则浏览器会显示滚动条以便查看其余的内容
  • visible默认值,内容不会被修剪,会呈现在元素框之外
  • hidden内容会被修剪,并且其余内容是不可见的
  • scroll内容会被修剪,但是浏览器会显示滚动条以便查看其余的内容
  • 可以看出overflow只是定义溢出内容如何处理的属性,其能撑开高度是因为overflow值不为“visiable”的块级盒子都会形成一个BFC,且这个BFC的环境不受外界的影响并会创造一个独立布局,所以在父元素中设置了overflow值不为“visiable”的值时,父元素成为BFC,可以包含浮动元素,故父容器的高度可以被撑开

四、BFC是什么?如何形成BFC,有什么作用?

  • BFC:浮动元素和绝对定位元素,非块级盒子的块级容器(例如 inline-blocks, table-cells, 和 table-captions),以及overflow值不为“visiable”的块级盒子,都会为他们的内容创建新的BFC(块级格式上下文)
  • 形成BFC的方法:
  • 设置了浮动float
  • 设置了绝对定位
  • 在非块级盒子的块级容器上display属性为inline-block,table-cells,table-captions等
  • overflow值不为"visiable"的块级盒子
  • 作用如下:
  • 清除由于文字受到浮动的影响,比如
    在未给文字所在的元素设置BFC时,效果如下
    未设置BFC时的效果图

    加入如下代码
<!doctype html>
<html>
   <head>
       <meta charset="utf-8"/>
       <title>练习</title>
       <style>
           *{
               margin: 0;
               padding: 0;
           }
           .ct{
               border:1px solid red;
               margin:100px auto 0 auto;
               width: 500px;
               height: 500px;
           }
           .ct img{
               float: left;
               width: 200px;
               height: 200px;
           }
           .ct p{
               background-color: pink;
               color: #fff;
               overflow: auto;
           }
       </style>
   </head>
   <body>
       <div class="ct">
           <img src="img/lufei.jpg" alt="路飞">
           <p>清除文字受浮动的影响清除文字受浮动的影响清除文字受浮动的影响清除文字受浮动的影响清除文字受浮动的影响清除文字受浮动的影响清除文字受浮动的影响清除文字受浮动的影响清除文字受浮动的影响清除文字受浮动的影响清除文字受浮动的影响清除文字受浮动的影响清除文字受浮动的影响清除文字受浮动的影响清除文字受浮动的影响清除文字受浮动的影响清除文字受浮动的影响清除文字受浮动的影响清除文字受浮动的影响清除文字受浮动的影响清除文字受浮动的影响清除文字受浮动的影响清除文字受浮动的影响</p>
       </div>
   </body>
</html>

效果图如下


BFC效果图
  • 形成一个独立空间,可以撑开父元素高度,比如
    在未成为BFC之前,父元素高度塌陷,如下图
    父元素高度塌陷

    加入如下代码
<!doctype html>
<html>
   <head>
       <meta charset="utf-8"/>
       <title>练习</title>
       <style>
           *{
               margin: 0;
               padding: 0;
           }
           .ct{
               border:1px solid red;
               margin:100px auto 0 auto;
               width: 500px;
               overflow: auto;
               /*以下几种方法也可以,各有各的好处与带来的影响
               overflow: hidden;
               display: inline-block;
               float: left;*/
           }
           .ct .box{
               float: left;
               width: 100px;
               height: 100px;
               margin: 20px;
               background-color: pink;
               color: #fff;
           }
       </style>
   </head>
   <body>
       <div class="ct">
           <div class="box">1</div>
           <div class="box">2</div>
           <div class="box">3</div>
       </div>
   </body>
</html>

效果图如下图


运用父元素撑开了父元素的高度
  • 阻止外边距的合并,比如
    外边距合并

    加入如下代码
<!doctype html>
<html>
   <head>
       <meta charset="utf-8"/>
       <title>练习</title>
       <style>
           *{
               margin: 0;
               padding: 0;
           }
           body{
               background: #ccc;
           }
           .ct{
               width: 500px;
               margin: 0 auto;
               background: pink;
           }
           .ct .box1{
               display: inline-block;
               width: 100px;
               height: 100px;
               margin: 20px;
               border: 1px solid red;
           }
           .ct .box2{
               display: inline-block;
               width: 100px;
               height: 100px;
               margin: 50px;
               border: 1px solid blue;
           }
       </style>
   </head>
   <body>
       <div class="ct">
           <div class="box1">1</div>
           <div class="box2">2</div>
       </div>
   </body>
</html>

效果图如下

阻止外边距合并

参考自W3Cplus


五、浮动导致的父容器高度塌陷指什么?为什么会产生?有几种解决方法?

  • 浮动导致的父容器高度塌陷指:父容器的高度因为其子元素的浮动脱离文档流而导致父元素无法得到子元素的高度支撑从而显示为0的情况,比如下图所示


    父元素高度塌陷
  • 解决办法如下:

  • 在父容器中设置float,比如如下代码

 <!doctype html>
<html>
  <head>
      <meta charset="utf-8"/>
      <title>练习</title>
      <style>
          *{
              margin: 0;
              padding: 0;
          }
          .center{
              float: left;
              width: 500px;
              margin: 100px auto;
              border: 1px solid red;
          }
          .box1{
              float: left;
              width: 100px;
              height: 100px;
              background: pink;
          }
          .box2{
              float: right;
              width: 100px;
              height: 100px;
              background: orange;
          }
      </style>
  </head>
  <body>
      <div class="center">
          <div class="box1"></div>
          <div class="box2"></div>
      </div>
  </body>
</html>

效果图如下图所示


父元素高度撑开
  • 在父容器中设置overflow不为visible的值,比如如下代码
.center{
              overflow: auto;
              width: 500px;
              margin: 100px auto;
              border: 1px solid red;
          }

效果图如下图


父元素高度被撑开
  • 在父容器中设置display为inline-block等值,比如如下代码
.center{
              display: inline-block;
              width: 500px;
              margin: 100px auto;
              border: 1px solid red;
}

效果图


父元素高度被撑开
  • 在父容器中设置height值,比如如下代码
.center{
              height: 500px;
              width: 500px;
              margin: 100px auto;
              border: 1px solid red;
}

效果图


父元素高度被撑开
  • 在父元素中设置如下代码
.center:after{
  content: '';
  display: block;
  clear: both;
}
.center{
  *zoom:1;
}

效果图


父元素高度被撑开

六、以下代码每一行的作用是什么? 为什么会产生作用? 和BFC撑开空间有什么区别?

代码如下

.clearfix:after{
    content: '';
    display: block;
    clear: both;
}
.clearfix{
    *zoom: 1;
}
  • 总的作用清除浮动带来的影响,每一行的代码作用如下:
    • .clearfix:after~选择.clearfix类为其设置after伪类
    • content:"";表示内容为空
    • display:block;表示将.clearfix设置为块级元素
    • clear:both表示将元素两边的浮动清除
    • *zoom:1;IE67的属性,设置.clearfix的缩放比例
  • 原因如下
    • 通过在.clearfix后增加一个空的设置了清除两边浮动块级元素,父元素会感知到这个空元素并且把自身空间撑开,但其并没有形成独立的空间
    • BFC是一个独立的布局环境,BFC中的元素的布局是不受外界的影响

版权声明:本教程版权归邓攀和饥人谷所有,转载须说明来源!!!!

推荐阅读更多精彩内容

  • 1.在什么场景下会出现外边距合并?如何合并?如何不让相邻元素外边距合并?给个父子外边距合并的范例 概念:在CSS当...
    饥人谷_任磊阅读 273评论 0 3
  • 1.在什么场景下会出现外边距合并?如何合并?如何不让相邻元素外边距合并?给个父子外边距合并的范例 答: 情况一(兄...
    呦泥酷阅读 85评论 0 0
  • 1. 在什么场景下会出现外边距合并?如何合并?如何不让相邻元素外边距合并?给个父子外边距合并的范例 外边距合并:外...
    进击的阿群阅读 374评论 1 2
  • 1.在什么场景下会出现外边距合并?如何合并?如何不让相邻元素外边距合并?给个父子外边距合并的范例。 当block元...
    王康_Wang阅读 59评论 0 0
  • 夜色沉寂,明月当空远去的路坎坷难平我拴好马的缰绳,徘徊树下一边扬着流沙一边想起江湖归隐 跨过石头山,到了王家沟那里...
    小畴阅读 95评论 0 1