美文网首页css+css3饥人谷技术博客Web前端之路
inline-block、BFC、边距合并基础知识问答

inline-block、BFC、边距合并基础知识问答

作者: 该帐号已被查封_才怪 | 来源:发表于2016-07-18 23:27 被阅读257次

    一、问题

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

    在正常文档流中以下场景中的块级框会出现外边距合并的情况有如下几种:

    1、两个或以上垂直外边距相碰时,会发生外边距合并的情况;

    1.1 当这两个外边距均为正值时,合并后的边距大小外为他们的最大者;(即使该两个元素有边框及内边距也会这样)
    如下面的例子:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
        <style>
        *{
            margin: 0;
            padding: 0;
    
        }
        div{
            height: 200px;
            width: 200px;   
    
        }
        .top-div{
            background-color: red;
            margin: 10px;
            padding: 5px;
            border: 10px solid #000;
    
        }
        .down-div{
            background-color: blue;
            margin: 20px;
            padding: 10px;
            border: 20px solid green;
        }
    
    
        </style>
    </head>
    <body>
        <div class="top-div">上div</div>
        <div class="down-div">下div</div>
        
    </body>
    </html>
    
    垂直外边距合并例子.png

    运行后,这两个div间的外边距为20px,即最大者down-div的外边距;

    1.2 不全是正值时,则取绝对值,然后用正值减去最大值;

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
        <style>
        *{
            margin: 0px;
            padding: 0px;
        }
        div.up{
            width: 100px;
            height: 100px;
            margin: -20px;
            padding: 15px;
            border: 20px solid blue;
        }
        div.down{
            width: 100px;
            height: 100px;        
            margin: 10px;
            padding: 15px;
            border: 20px solid red;
        }
    
    
        </style>
    
    
    </head>
    <body>
    
    <div class="up">我是上div</div>
    <div class="down">我是下div</div>
    
    
    </body>
    </html>
    

    运行后,外边距为-10px;

    一个负边距.png

    1.3 全是负值时,则均取绝对值,然后用0减去最大值;

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
        <style>
        *{
            margin: 0px;
            padding: 0px;
        }
        div.up{
            margin: -20px;
            padding: 15px;
            border: 5px solid blue;
        }
        div.down{
            margin: -10px;
            padding: 15px;
            border: 5px solid red;
        }
    
    
        </style>
    
    
    </head>
    <body>
    <div class="up">我是上div</div>
    <div class="down">我是下div</div>
    </body>
    </html>
    

    运行后,外边距为-20px;

    均为负值.png

    注:当元素为inline-block时不会发生外边距合并的情况;例如:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
        <style>
        *{
            margin: 0px;
            padding: 0px;
            font-size: 0px;
        }
    /*    body{
            position: absolute;
            float: none;
        }*/
    
        a{
            border: 2px solid red;
            margin: 10px;
            padding: 5px;
    
            font-size: 20px;
        }
    /*    img{
            border: 2px solid red;
            margin: 30px;
            padding: 15px;
        }*/
    
        </style>
    
    
    </head>
    <body>
        <a href="www.w3school.com.cn" class="">我是下联元素a标签</a>
        <a href="www.w3school.com.cn" class="">我是下联元素a标签</a>
    
    
    
    
    </body>
    </html>
    
    inline-block外边距不会合并.png

    很明显,last-buttom并没有与上面的两个div发生外边距合并的情况。

    2、当两个块框有嵌套关系,且无内边距或边框或内容区里的文字将他们分开时,也会发生合并现象,合并后也是取他们中的最大者。

    例如以下代码:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>包含有边框及内边距</title>
        <style>
        *{
            margin: 0;
            padding: 0;
    
        }
    
        .in-div{
            background-color: red;
            margin: 50px;
    /*      padding: 5px;
            border: 10px solid #000;*/
            height: 200px;
            width: 200px;
        }
        .out-div{
            background-color: blue;
            margin: 20px;
    /*      padding: 10px;*/
    /*      border: 20px solid green;*/
            height: 400px;
            width: 400px;
        }
    
    
        </style>
    </head>
    <body>
        <div class="out-div">
        <div class="in-div"></div>
        </div>
        
    </body>
    </html>
    
    父子内边距合并.png

    父元素out-div虽然外边距为20px,但其实合并后,它距离上页面为50px,即为in-div的边距。
    对于这一点我深有体会。。。。做上个任务时10-1我用自己的思路写了页面后,发现left-aside及main均距离header有10px,我当时没有设他们margin-top:10px 只是main-content我设置了margin-top:10px,当时想不通后来在群里问才知道父子外边距合并了。。。。感兴趣的可以看看我的这个代码。。。

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title>10-1自己</title>
      <style>
      *{
          margin: 0px;
          padding: 0px;
          box-sizing:border-box;    
    
      }
      .container{
        margin: 0 auto;
        width: 900px;
      }
      #header{
        height: 50px;
        background-color: #333;
    
      }
      #header:after{
        content: "";
        display:table;
        clear: both;
    
      }
      ul,li{
        display: inline-block;
        list-style: none;
        vertical-align: middle;    
      }
    
    
    
      .nav-content>a{
    
        text-decoration: none;
        color: #fff;
        font-size: 20px;
        margin-left: 10px;
        margin-right: 10px;
        width: 50px;
        height: 50px;
        display: inline-block;
        line-height: 50px;
        text-align: center;
        vertical-align: middle;
    
        
      }
      .nav-content>a:hover{
        background-color: #fff;
        color: #333;
      }
    
    
      .jirengu-logo{
        height: 50px;
        float: left;
        margin-right: 350px;
    
    
      }
      #main:after{
        content: "";
        display: table;
        clear: both;
      }
    
    
      #left-sidebar{
        background-color: #eee;
        width: 200px;
        min-height: 500px;
        float: left;
    
    
      }
      #main-content{
        background-color: #eee;
        width: 690px;
        min-height: 150px;
        margin-left:210px;
        margin-top: 10px; 
        
    
    
      }
      #footer{
        background-color: #333;
        clear: left;
    
    
    
      }
      .footer-li>a{
    
        text-decoration: none;
        color: #fff;
        height: 40px;
        line-height: 40px;
        font-weight: bold;
        padding-left: 20px;
    
    
      }
      #main-content>h1,p{
        padding: 12px;
      }
    
    
      </style>
    </head>
    <body>
        <div id="header">
          <div class="container">      
            <a href="http://jirengu.com">![jirengu logo](http:https://img.haomeiwen.com/i2166980/4e5aaee185d91fb1.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
            </a>
            <ul class="nav-ul">
            <li class="nav-content"><a href="#">技能</a></li>
            <li class="nav-content"><a href="#">经历</a></li>
            <li class="nav-content"><a href="#">作品</a></li>
            <li class="nav-content"><a href="#">关于</a></li>
          </ul>
          </div>        
        </div>
        <div id="main">
          <div class="container">
            <div id="left-sidebar">            
            </div>
            <div id="main-content">            
                <h1>我的作品</h1>
                <p>生活很美好</p>
                <p>心情不错</p> 
                <p>代码写的很漂亮</p>
            </div>
          </div>
        </div>
    
        <div id="footer">
          <div class="container">
            <ul>
              <li class="footer-li"><a href="http://jirengu.com">饥人谷</a></li>
              <li class="footer-li"><a href="http://jscode.me">JSCODE</a></li>
              <li class="footer-li"><a href="http://js.jirengu.com">JSBIN</a></li>
            </ul>  
               
          </div>
        </div>
    
    </body>
    </html>
    
    提问截图.png

    言归正传,在该种情况下:
    a、如果在父元素下面再增加一个具有外边距的div同级元素,则新增的div上边距还会与父元素的下边距合并。(但该div不会与父元素中的子元素发生合并。)
    b、在该种情况下当父元素和子元素间被父元素内容区的文字、父元素的内边距、父元素的边框中的任意一个隔开,则该种外边距合并的情况就不存在;

    3、一个空元素它没有边框或填充时,它的上边距和下边距也会发生合并;

    例如如下代码

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
        <style>
        *{
            margin: 0;
            padding: 0;
        }
        div.kong{
            margin: 10px 20px 30px 40px;
        }
        .down{
            height: 20px;
            width: 220px;
            background-color: red;
            margin: 10px;
            border: 5px solid green;
        }
    
        </style>
    </head>
    <body>
        <div class="kong"></div>
        <div class="down"></div>
    </body>
    </html>
    
    空元素合并.png

    审查元素可以看出kong的上边距为10px,下边距为30px,上下边距合并后则为30px,down距离页面上面的距离为30px,而它自身margin为10px,它与上面的空元素发生了合并;

    以上所说的合并是指块框的合并,而行内框(可见本人写的这篇文章)、浮动及绝对定位元素均不会发生外边距合并的情况!!!!

    不让两相邻元素发生合并现象,可以

    1、让这两相邻元素中的一个或两个设置为inline-block或浮动或绝对定位或overflow: hidden(overflow: hidden只能用于父子情况的父元素上)
    2、在他们间加入任意内容(不能空的元素,padding不为0或border宽度不为0且style不为none)
    3、对于兄弟元素,可在外层均包裹一个div,然后样式设置为overflow:hidden;

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

    有五种常见的方法:
    1、可先设置font-size为0px;在将font-size设回来;
    2、将标签并排写,如下面的例子

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
        <style>
        *{
            margin: 0;
            padding: 0;
    
        }
        ul,li{
            display: inline-block;
            background-color: red;
            color: #fff;
    /*      font-size: 0px;*/
        }
        .fix{
            font-size: 20px;
        }
        </style>
    </head>
    <body>
     <ul>
        <li class="fix">1</li><li class="fix">2</li><li class="fix">3</li>
     </ul>  
    </body>
    </html>
    

    3、将标签拆分写,如下面的例子

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
        <style>
        *{
            margin: 0;
            padding: 0;
    
        }
        ul,li{
            display: inline-block;
            background-color: red;
            color: #fff;
    /*      font-size: 0px;*/
        }
        .fix{
            font-size: 20px;
        }
    
        </style>
    </head>
    <body>
     <ul>
        <li class="fix"
        >1</li><li class="fix"
        >2</li><li class="fix"
        >3</li>
     </ul>  
    </body>
    </html>
    

    4、在子元素中使用浮动,然后在父元素overflow:hidden/auto;
    5、使用负边距;

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
        <style>
        *{
            margin: 0;
            padding: 0;
    
        }
    
        ul,li{
            display: inline-block;
            background-color: red;
            list-style: none;
            color: #fff;
    
            
            /*float: left;*/
    /*      font-size: 0px;*/
        }
        ul{
            border: 5px solid blue;
        }
        .fix{
            margin-left: -4px;  
    
        }
    
        </style>
    </head>
    <body>
     <ul>
        <li class="fix-first">1</li>
        <li class="fix">2</li>
        <li class="fix">3</li>
     </ul>  
    </body>
    </html>
    

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

    撑起的原理是借用了BFC,可以这样理解:当里面使用了浮动元素,使用overflow:auto| hidden 的作用是超出部分会裁剪或隐藏掉,浮动元素虽然脱离了文档流,但overflow还是会把它的高度和宽度给算进来的,从而把高度给撑开了。

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

    BFC全称为block formatting context,翻译过来就是块级格式化上下文,是页面 CSS 视觉渲染的一部分。它是用于决定块盒子的布局及浮动相互影响的一个区域。(简单理解就是它是一个独立封闭的盒子,它对外面的元素不产生影响,但里面的元素还是会相互影响的,除非在这里面又产生了一个BFC)

    下列情况将创建一个块格式化上下文:
    1、根元素或其它包含它的元素
    2、浮动 (元素的 float 不为 none)
    3、绝对定位元素 (元素的 position 为 absolute 或 fixed)
    4、行内块 inline-blocks (元素的 display: inline-block)
    5、表格单元格 (元素的 display: table-cell,HTML表格单元格默认属性)
    6、表格标题 (元素的 display: table-caption, HTML表格标题默认属性)
    7、overflow 的值不为 visible的元素

    8、弹性盒子 flex boxes (元素的 display: flex 或 inline-flex)

    其实最常见的就是:overflow:hidden/auto; position:absolute/fixed;float:left/right;display:inline-block;

    BFC的作用是1、可以避免与外面的元素发生外边距合并的情况;2、包含浮动;3、可避免文字环绕(如使用overflow:auto 虽然使用负边距也能做到,但使用负边距相当于写死了。。。)

    块格式化上下文对定位 (参见 float
    ) 与清除浮动 (参见 clear
    ) 很重要。定位和清除浮动的样式规则只适用于处于同一块格式化上下文内的元素。浮动不会影响其它块格式化上下文中元素的布局,并且清除浮动只清除同一块格式化上下文中 在它前面的元素的浮动。

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

    是指父容器撑不开空间(让浮动元素包含在里面),原因为浮动元素是脱离文档流的,此时父容器里面相当于没有元素一样,从而导致高度塌陷;

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
        <style>
        *{
            margin: 0;
            padding: 0;
    
        }
        .ct{
            border: 2px solid #000;
            
        }
    
        .ct>div{
            width: 100px;
            height: 100px;
            float:left;
        }
        .float1{
            background-color: red;
        }
        .float2{
            background-color: blue;
        }
    
        </style>
    </head>
    <body>
    <div class="ct">
        <div class="float1"></div>
        <div class="float2"></div>
    </div>
    </body>
    </html>
    

    例如上面的代码父容器ct就没有被撑开;
    解决方法有:
    1、在父容器中加入overflow: hidden/auto;
    2、使父容器 float或display:inline-block;
    3、在父容器中添加高度;
    4、在父容器中的最后面子元素后面增加一个div,并设该div 清除浮动clear:both;
    5、在样式中加入如下代码

        .ct:after{
            content: "";
            display: table;
            clear: both;
        }
        .ct{
            *zoom:1;/* for ie 6,7*/
        }
    

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

    .clearfix:after{ /*在clearfix后面增加元素*/
        content: ''; /*该元素内容为空*/
        display: block; /*该元素类型为块级元素*/
        clear: both; /*在该元素上清除浮动*/
    }
    .clearfix{ /*选择clearfix*/
        *zoom: 1;  /*只针对IE8以下,触发IE浏览器的haslayout ,解决ie下的浮动,margin重叠等问题。 */
    }
    

    产生作用的原因是其在.clearfix后面增加了一个空的块级元素,该块级元素是清除浮动的,而.clearfix中还有浮动元素,从而导致.clearfix被撑开了同时下面的元素不会上来,但它并没有形成独立的空间;
    BFC撑开空间是形成一个封闭独立的空间,它不影响周围的元素;
    因此两者有本质区别;

    二、代码

    (一)、实现如下效果的导航条

    自己写的代码详见此处

    (二)、利用BFC的原理实现下图所示两栏布局

    <div id="header">header</div>
    <div id="content">
        <div class="aside">aside</div>
        <div class="main">
            我是main 
            我是main 我是main 我是main 我是main 我是main 我是main 我是main 我是main 我是main 我是main 我是main... 
        </div>
    </div>
    <div id="footer"></div>
    

    自己写的代码详见如下:
    1、 BFC原理 方法一 -----左浮动右overflow:hidden
    2、严格意义上的非BFC原理 方法二---左浮动右margin-left
    3、方法三-----左右均浮动-适合固定宽度

    **本文版权归本人即简书笔名:该账户已被查封 所有,如需转载请注明出处。谢谢! *

    相关文章

      网友评论

      • 婷楼沐熙:写的很详细哦。老乡赞。
        婷楼沐熙:@该帐号已被查封 嗯嗯。说得好。总要慢慢摸索的。
        该帐号已被查封_才怪:@婷楼沐熙 哈哈 写的详细没用,要写的正确、写的全面、写的通俗易懂才是王道

      本文标题:inline-block、BFC、边距合并基础知识问答

      本文链接:https://www.haomeiwen.com/subject/vcupjttx.html