×

inline-block、BFC、边距合并

96
婷楼沐熙
2016.07.18 15:10* 字数 2292

收拾心情,重新出发。
加油。


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

  • 外边距合并指的是,两个在普通文档流中的“相邻”元素外边距相遇的时候发生合并的情况。这个所谓的“相邻”可以是父子关系相邻,兄弟关系相邻,甚至如果一个元素内部没有东西,自身的上下边距相遇时都会发生外边距合并。

  • 合并的结果为: 当两个外边距都是正数时,取两者之中的较大者;当两个外边距都是负数时,取两者之间绝对值较大者;当两个外边距一正一负时,取的是两者的和。

  • 下面对一些外边距合并的具体情况做一下说明。

  • 父子关系的合并
    假如说,父元素和子元素在正常的文档流当中。而且父元素没有边框或者padding,那么父子之间就会发生外边距合并。看下面的例子。


    父子关系的外边距合并

    按道理来说边框和字体上面都应该会有背景色,但是实际的效果并没有。这其实就是父子外边距合并带来的结果,因为它们的外边距融合了。
    要解决有以下几种方案:

    • 给父元素加边框
      给父元素加了边框之后,它们的margin就被边界线隔离开来,就不会发生外边距合并。它们就会各归各位,父元素有父元素的外边距,子元素有子元素的外边距。


      父元素加边框之后外边距不合并
    • 或者设置父元素的padding
      给父元素设置了padding之后,也能够阻止父子的外边距相融合,所以也可以防止父子元素的外边距合并。


      父元素设置上padding之后外边距不合并

      上图是设置了上padding,如果要其他方向不发生外边距合并,对相应的方向设置即可。

  • 兄弟关系的合并
    如果两个兄弟元素在正常的文档流当中,会产生外边距合并。

    兄弟元素外边距合并

  • 自身的合并
    一个元素如果里面没有东西,也没有边框和padding,那么它自身的外边距就会融合,也会发生外边距合并。这里的例子,其实child3元素,不仅自身的外边距合并了,还和上面child2的下margin合并了。合并的结果就是取了最大值50px。


    自身外边距的合并

    要防止自身合并,可以利用以下方法:

    • 给这个空的元素child3,加了边框之后,自身的上下外边距被隔离开,就不会发生外边距合并。


      加边框之后自身不合并
    • 给child3加上padding之后,自身也不会发生外边距合并。


      加padding之后自身不合并
    • 给child3设置overflow:hidden之后,自身上下外边距也不会发生合并。因为它内部形成了一个空间,自身的margin被这个空间隔离开。
      设置overflow:hidden之后不合并
  • 不产生外边距合并的情况

  • 浮动元素不与任何元素产生外边距合并。


    浮动元素发生外边距合并
  • 父子关系或者兄弟关系inline-block元素不合并。


    inline-block元素不合并
  • 创建BFC与子元素不合并
    设置overflow: hidden;也可以形成BFC,但是没有达到效果,外边距还是会合并。可能是两者的外边距没有真正隔离开来,外边距还是交融的。

    设置overflow属性元素合并

    给子元素加了div包裹之后,利用overflow:hidden外边距不合并,可见创建BFC与子元素不发生合并。在外层形成了BFC真正把两者的外边距隔离开来。
    加了div包裹之后不合并

  • 使用绝对定位的元素,不与任何元素发生外边距合并。


    绝对定位不发生外边距合并
  • 此外,还有根元素不合并、兄弟元素之间有间隙不合并等等。

总的来说,外边距合并不一定是两个相邻元素,不相邻的也可能会发生外边距合并。只要它们的外边距会融合到一起,没有分界线(可以是边框、padding,也可以是BFC形成的空间)隔开,就有可能发生外边距合并。

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

未去除间隙之前
  • html内标签不含空格


    标签没有空格
  • 标签可以换行,但是要保证标签相接的地方没有空格


    标签相接处没有空格
  • 利用负margin(一般-4px左右)
    负margin

    这里顺便对负margin做一个说明。margin-top和margin-left移动的是自己,margin-right和margin-bottom移动的是周围的元素。因为margin的意思是要让周围的元素有多少距离,比如说10px。根据文档流的顺序,当前的元素距离下一个元素要有10px的位置。因此,如果设置的是right和bottom,自然就是下一个元素移动。不然当前的元素和它前面的元素margin就会受到影响。
  • 利用浮动


    浮动
  • 利用父元素font-size


    font-size:0px

    这里需要注意的一点是在父元素里面设置了font-size之后,在容器里面的元素需要把字体大小重置回来。

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

当元素设置浮动时,父元素感知不到元素的存在,造成高度塌陷。在父容器使用overflow属性是形成一个BFC,使其内部元素不受外界的影响。关于BFC还可以参考深入理解BFC与合并
BFC有三个特性:

  • BFC会阻止垂直外边距(margin-top、margin-bottom)折叠
  • BFC不会重叠浮动元素
  • BFC可以包含浮动

根据第三条特性就可以知道,父容器的高度可以被撑开。

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

  • 浮动元素、绝对定位元素、非块级元素的块级容器(例如 inline-blocks, table-cells, 和 table-captions)以及overflow值不为“visiable”的块级盒子,都会为他们的内容创建新的块级格式化上下文。简单的来说,BFC就是一个独立的空间,内部的元素不受外部元素影响。
  • 以下情况都可以形成BFC:
  • float为 left|right
  • overflow为 hidden|auto|scroll
  • display为 table-cell|table-caption|inline-block
  • position为 absolute|fixed
  • BFC主要有以下一些用处:
  • 清除浮动
  • 防止外边距合并
  • 设计布局

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

  • 元素设置了浮动之后,父元素感知不到浮动元素的高度,使得元素会溢出父容器,造成父容器的高度没有被撑开。所以也可以说,浮动的元素失去了高度,导致父容器高度塌陷。
  • 解决父容器塌陷的方法就是要清除浮动。清除浮动的方法之前在我的另外一篇博客关于清除浮动的方法上面做过总结,这里就不再赘述。

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

.clearfix:after{   /* 在clearfix后面添加一个伪元素 */
    content: ' ';    /* 伪元素的内容为空白字符 */
    display: block;  /* 因为伪元素生成的默认为行内又元素,而clear对象一定是块级元素,所以这里设置一下display属性。 */
    clear: both;   /* 元素两边都不能有浮动对象 */
}
.clearfix{          
    *zoom: 1;  /* “*”号是IE6~8的一个bug,IE6~8看到以“*”开头的代码,会忽略星号,执行后面的代码。而zoom的原意是放大。它也会触发BFC,在IE里面其实不叫BFC,叫hasLayout 。*/
}
  • zoom是IE的特有属性,可以设置对象的缩放比例。后面可以接数字或者百分数,也就是表示缩放的比例。经常用zoom: 1;来触发IE的hasLayout、清除浮动以及解决外边距合并的问题。因为伪元素在IE8是部分支持,IE8以下不支持,所以上述的代码在IE中也能达到清除浮动的效果。
  • BFC是形成一个内部的独立小空间,不受外部元素影响。而上述方法只是让父元素感知到浮动元素的存在,把内容撑开,不会形成独立的空间。

七、代码

1、实现如下效果的导航条。

导航条

效果预览
2、利用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>

两栏布局

效果预览
代码github地址

前端学习知识点
Web note ad 1