所有HTML元素可以看作盒子,在CSS中,box model这一术语是用来设计和布局时使用。
CSS盒模型本质上是一个盒子,封装周围的HTML元素,它包括:边距边框填充,和实际内容
盒模型允许我们在其它元素和周围元素边框之间的空间放置元素。
下面的图片说明了盒子模型(Box Model):

不同部分的说明:

  • Margin(外边距) - 清除边框外的区域,外边距是透明的。
  • Border(边框) - 围绕在内边距和内容外的边框。
  • Padding(内边距) - 清除内容周围的区域,内边距是透明的。
  • Content(内容) - 盒子的内容,显示文本和图像。
  • 注意:我们用盒子的宽高来衡量盒子的大小,可以看做总元素的宽度和高度,和元素本身设置的宽度和高度(width,height)不是同一个概念。

    标准盒模型

  • 元素的 width、height 只包含内容 content,不包含 border 和 padding 值;
  • 盒子的大小由元素的宽高、边框和内边距决定。
  • 盒子的宽/高 = width/height + border + padding + margin
    模型如下图:

    IE盒模型

  • 元素的 width、height 不仅包括 content,还包括 border 和 padding;
  • 盒子的大小取决于 width、height,修改 border 和 padding 值不能改变盒子的大小
  • 盒子宽/高=width/height + margin = 内容区宽度/高度 + padding + border + margin
    盒型如下图:

兼容

  • 标准盒模型和IE盒模型就在内容content的区别,标准盒模型的content只包括width/height,而IE盒模型的content包括width/height+border+padding。
  • 标准盒模型下元素的 box-sizing 属性(IE8+)默认值为 content-box,将它设置成 border-box 可转换为 IE 盒模型。在实际应用场景中,若想控制元素总宽高保持固定,这个设置很有用。
  • 元素的宽(width)、高(height)、边框(border)、内边距(padding)、外边距(margin)都是盒子模型的重要组成部分,但是盒子模型的大小只与元素的宽高、边框、内间距有关,外边距只影响盒子所占外围空间的大小。

    边距重叠解决方案(BFC)

    首先要明确BFC是什么意思,其全英文拼写为 Block Formatting Context 直译为块级格式化上下文。它是一个独立的渲染区域,只有Block-level box参与, 它规定了内部的Block-level Box如何布局,并且与这个区域外部毫不相干。
  • Block-level box:display 属性为 block, list-item, table 的元素。
  • inline-level box:display 属性为 inline, inline-block, inline-table的元素。

    BFC布局规则

  • 内部的box会在垂直方向,一个接一个的放置
  • 每个元素的margin box的左边,与包含块border box的左边相接触(对于从做往右的格式化,否则相反)
  • box垂直方向的距离由margin决定,属于同一个BFC的两个相邻box的margin会发生重叠
  • BFC的区域不会与浮动区域的box重叠
  • BFC是一个页面上的独立的容器,外面的元素不会影响BFC里的元素,反过来,里面的也不会影响外面的
  • 计算BFC高度的时候,浮动元素也会参与计算

    如何创建BFC

  • float属性不为none(脱离文档流)
  • position为absolute或fixed
  • display为inline-block,table-cell,table-caption,flex,inline-flex
  • overflow不为visible
  • 根元素, 即HTML元素

    BFC的作用

  1. 利用BFC避免margin重叠
  2. 自适应两栏布局
  3. 清除内部浮动
    例子如下:
    避免margin重叠
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <style>
    .pOne{
    margin: 10px 0;
    }
    .pTwo{
    margin: 30px 0;
    }
    </style>
    <body>
    <p class="pOne">文本1</p>
    <p class="pTwo">文本2</p>
    </body>
    在上面的例子中,margin会重叠,会以最大的margin为准。也就是两个p元素的外边距为30px。
    当我们利用BFC时
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    <style>
    .pOne{
    margin: 10px 0;
    }
    .pTwo{
    margin: 30px 0;
    }
    div{
    overflow: hidden;
    }
    </style>
    <body>
    <p class="pOne">文本1</p>
    <div >
    <p class="pTwo">文本2</p>
    </div>
    </body>
    利用BFC消除了margin重叠问题,这样的话两个p元素的外边距为30+10=40px。
    自适应两栏布局
    根据BFC的布局规则:每个元素的margin box的左边,与包含块border box的左边相接触(对于从做往右的格式化,否则相反)。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    <style>
    .left{
    height: 300px;
    width: 200px;
    background-color: #00FFFF;
    float: left;
    }
    .right{
    height: 500px;
    background-color: #F5F5DC;
    }
    </style>
    <body>
    <div class="left">LEFT</div>
    <div class="right">RIGHT</div>
    </body>
    效果如下图:
    根据BFC的布局规则:BFC的区域不会与浮动区域的box重叠。所以我们要创建一个BFC,避免left和right重叠。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    <style>
    .left{
    height: 300px;
    width: 200px;
    background-color: #00FFFF;
    float: left;
    }
    .right{
    height: 500px;
    overflow: hidden; /*right变为BFC*/
    background-color: #F5F5DC;
    }
    </style>
    <body>
    <div class="left">LEFT</div>
    <div class="right">RIGHT</div>
    </body>
    清除内部浮动
    当我们不给父节点设置高度,子节点设置浮动的时候,会发生高度塌陷,这个时候我们就要清除浮动。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    <style>
    .parent{
    width: 300px;
    border: 5px solid darkgoldenrod;
    }
    .child{
    height: 100px;
    width: 100px;
    float: left;
    border: 5px solid #00FFFF;
    }
    </style>
    <body>
    <div class="parent">
    <div class="child"></div>
    <div class="child"></div>
    </div>
    </body>
    效果如下,父节点高度塌陷:
    根据BFC布局规则:计算BFC高度的时候,浮动元素也会参与计算。因此我们把父节点设置为BFC就可以解决高度塌陷。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    <style>
    .parent{
    width: 300px;
    border: 5px solid darkgoldenrod;
    overflow: hidden; /*BFC*/
    }
    .child{
    height: 100px;
    width: 100px;
    float: left;
    border: 5px solid #00FFFF;
    }
    </style>
    <body>
    <div class="parent">
    <div class="child"></div>
    <div class="child"></div>
    </div>
    </body>

关于解决父节点高度塌陷问题

给父元素末尾添加一个空元素,并设置成清除浮动

1
<div style="clear:both;"></div>

缺点:添加了无意义标签,不易于后期维护,违背了结构和表现分离的标准

给父元素添加 overflow:auto;

让父元素也浮动

缺点:影响整体页面布局,若父元素也有父元素呢?总不能一直浮动到body吧?

使用after伪元素

给父元素添加一个类,来添加一个看不见的块元素,以实现清除浮动。

1
2
3
4
5
6
7
8
.clearfix:after
{
content: '';
height: 0;
display: block;
visibility: hidden;
clear: both;
}

BFC

也就是BFC的布局规则:计算BFC高度的时候,浮动元素也会参与计算。上面的方法也用到了这条规则。下面这个方法是一个不错的方法。

1
2
3
4
5
6
7
8
9
10
.clearfix:after,
.clearfix:before
{
content: " ";
display:table;
}
.clearfix:after
{
clear:both;
}