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

一、问题

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

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

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://upload-images.jianshu.io/upload_images/2166980-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、方法三-----左右均浮动-适合固定宽度

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,390评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,821评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,632评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,170评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,033评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,098评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,511评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,204评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,479评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,572评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,341评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,893评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,171评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,486评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,676评论 2 335

推荐阅读更多精彩内容

  • 问答题47 /72 常见浏览器兼容性问题与解决方案? 参考答案 (1)浏览器兼容问题一:不同浏览器的标签默认的外补...
    _Yfling阅读 13,703评论 1 92
  • 一、在什么场景下会出现外边距合并?如何合并?如何不让相邻元素外边距合并?给个父子外边距合并的范例 在CSS当中,相...
    dengpan阅读 551评论 0 0
  • 一、在什么场景下会出现外边距合并?如何合并?如何不让相邻元素外边距合并?给个父子外边距合并的范例 1、外边距和并的...
    鸿鹄飞天阅读 580评论 0 0
  • 收拾心情,重新出发。加油。 一、在什么场景下会出现外边距合并?如何合并?如何不让相邻元素外边距合并?给个父子外边距...
    婷楼沐熙阅读 1,296评论 0 1
  • 1.在什么场景下会出现外边距合并?如何合并?如何不让相邻元素外边距合并?给个父子外边距合并的范例 概念:在CSS当...
    饥人谷_任磊阅读 636评论 0 3