包围盒和BFC


盒模型

概念

所有的HTML元素都被一个看不见的盒子包围着,这个盒子被称为盒模型(Box Model)。

如图所示,是Chrome浏览器所绘制的某个元素的盒模型示意图,由内容区(content)、内边距(padding)、边框(border)、外边距(margin)。

内容区

指盒子的主要内容区域,用来显示和存储元素的“真实”内容,通常可由 widthmin-widthmax-widthheightmin-height 和 max-height分别设置内容区的宽度最小宽度最大宽度高度最小高度最大高度

内边距

内容区边框之间的距离,可使用padding属性设置或者padding-toppadding-bottompadding-leftpadding-right分别可设置上、下、左、右四个方向上的距离。内边距不支持设置负值,可以设置百分比,且按照宽度计算

边框

内边距外边距间的距离,可使用boder属性设置或者使用border-widthborder-styleborder-color分别设置边框的宽度样式颜色等属性

外边距

指元素边框周围一定距离的空间,与内边距类似,可使用padding属性设置或者margin-topmargin-bottommargin-leftmargin-right分别设置上、下、左、右四个方向上的距离。但外边距可设置负值,相邻元素之间的外边距大小遵循规则“正正按大,正负相加,负负最小”

分类

实际上,CSS的盒模型有两种,分别是标准盒模型怪异盒模型,它们的区别主要体现在元素的width属性是否只包含内容区的宽度。

标准盒模型

在标准盒模型中,widht属性只包含内容区content的宽度。因此标准盒模型的宽度为:width+padding+border+magin

元素可通过设置box-sizing: content-box使用标准盒模型,这也是默认的属性。

怪异盒模型(IE盒模型)

在怪异盒模型中,width属性不仅包含内容区content宽度,还包括边框和内边距的宽度。因此标准盒模型的宽度为:width+magin

元素可通过设置box-sizing: border-box使用怪异盒模型。

BFC

概念

块级盒子(Block-level Box)和行内盒子(Inline Box)

块级元素和行内元素会生成上述盒模型所表达的块级盒子和行内盒子,这两种盒子类型是CSS中用来描述HTML元素的基本显示类型,可通过display属性的值来定义元素的显示类型。块级盒子的display属性值通常为"block",行内盒子的display属性值通为"inline"(并不绝对)。

BFC的定义

MDN的定义为:区块格式化上下文(Block Formatting Context,BFC)是 Web 页面的可视 CSS 渲染的一部分,是块级盒子(Block-level Box)布局过程发生的区域,也是浮动元素与其他元素交互的区域。

通俗来说,BFC是一个独立的渲染区域,他规定了内部块级盒子的布局方式,此区域的布局不会受到BFC外部元素布局的影响。

注:实际开发中,BFC中是允许存在行内元素的,但是上述定义却说BFC是块级盒子的布局过程发生的区域,这是因为行内元素所存在的内联盒子在布局时会形成一个匿名块级盒子,该匿名块级盒子的布局行为与普通块级盒子类似。因此,内联盒子在BFC中的布局行为可以看作是一种特殊的块级盒子布局。

BFC的产生条件

  • 文档的根元素(<html>)。
  • 浮动元素( float 值不为 none 的元素)。
  • 绝对定位元素(position值为 absolute 或 fixed 的元素)。
  • display值为 inline-blocktableinline-tabletable-celltable-captiontable-rowtable-row-grouptable-header-grouptable-footer-groupflow-root
  • overflow值不为 visible 或 clip 的块级元素。
  • contain 值为 layoutcontent 或 paint 的元素。
  • 弹性元素(display 值为 flex 或 inline-flex 元素的直接子元素),如果它们本身既不是弹性、网格也不是表格容器。
  • 网格元素(display值为 grid 或 inline-grid 元素的直接子元素),如果它们本身既不是弹性、网格也不是表格容器。
  • 多列容器(column-count 或 column-width值不为 auto,且含有 column-count: 1 的元素)。
  • column-span 值为 all 的元素始终会创建一个新的格式化上下文,即使该元素没有包裹在一个多列容器中。

BFC的布局规则

  • 内部的Box会在垂直方向,一个接一个地放置。
  • Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Boxmargin会发生重叠。
  • 每个盒子(块盒与行盒)的margin box的左边,与包含块border box的左边相接触(对于从左往右的格式化,否则相反),即使存在浮动也是如此。
  • BFC的区域不会与float box重叠。
  • BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,反之亦然。
  • 计算BFC的高度时,浮动元素也参与计算。

BFC在开发中的作用

解决外边距重叠问题

假如页面中有两个div元素,他们的样式设置如下:

    #div1, #div2{
        width: 100px;
        height: 100px;
    }
    #div1 {
        background-color: yellow;
        margin: 20px;
    }
    #div2 {
        background-color: aliceblue;
        margin: 30px;
    }

只看代码可能会理所当然的认为两个div之间的边距应该是50px,但通过调试工具发现实际上只有30px

这是因为当两个div同时设置margin的时候,它们接触地方的外边距会发生重叠,即实际边距为两者中最大的一个。其原因就是BFC的布局规则第二条所讲的属于同一个BFC的两个相邻Boxmargin会发生重叠。既然规则中说的是同属于一个BFC下的两个DIV会发生这种情况,那么只需将其放在不同的BFC下,就可以解决这个问题。

如以下代码所示,在div2上新包裹一个div标签,并设置属性overflow: hidden创建一个BFC区域,从而解决外边距重叠的问题。

    #div1, #div2{
        width: 100px;
        height: 100px;
    }
    #div1 {
        background-color: yellow;
        margin: 20px;
    }
    #div2 {
        background-color: aliceblue;
        margin: 30px;
    }
    #div3 {
        overflow: hidden;
    }

包含内部浮动元素

假设div1作为父元素,有div2div3两个子元素,并且设置以下样式:

    #div2, #div3{
        width: 100px;
        height: 100px;
    }
    #div1 {
        border: 1px solid;
        margin: 20px;
    }
    #div2 {
        background-color: aliceblue;
    }
    #div3 {
        background-color: grey;
        float: left;
    }

由上图可知,父元素div1并没有包含浮动子元素div3的高度,这便是经典的高度塌陷问题。

根据BFC布局规则的第六条,计算BFC的高度时,浮动元素也参与计算,因此可通过为div1设置样式overflow: hidden,使其创建一个BFC的方式,消除因子元素浮动引起的高度塌陷。

排除外部浮动元素

假设有div1div2两个元素,设置以下样式:

    #div1 {
        background-color: yellowgreen;
        float: left;
    }
    #div2 {
        background-color: lightblue;
    }

如上图所示,当div1设置浮动后,div2中的文本会环绕在div1周围。

根据BFC布局规则的第四条,BFC的区域不会与float box重叠,可以给div2设置 overflow: hidder属性从而创建一个独立的BFC后,从而形成一种两栏布局,如下图所示:

声明:Hello World|版权所有,违者必究|如未注明,均为原创|本网站采用BY-NC-SA协议进行授权

转载:转载请注明原文链接 - 包围盒和BFC


Carpe Diem and Do what I like