前端面试题 - 80. 说说css盒模型(彻底理解Box模型、BFC、清除浮动)

397 阅读6分钟

CSS 盒模型

W3C中有两种盒模型 content-boxborder-box 是 CSS 盒子模型中的两种不同的盒子模型。两者主要的区别在于计算盒子尺寸时的方式不同。

  • content-box 盒子模型是默认的盒子模型,它将元素的边框之外的部分作为盒子的内容区域。在 content-box 中,盒子的宽度和高度只包括内容的宽度和高度(不包括边框和内边距)。例如:
box-sizing: content-box;
width: 100px;
padding: 10px;
border: 1px solid black;

上述样式设置下,元素的实际宽度为 100 + 2*10 + 2*1 = 122 像素,其中 100 像素为内容宽度,10 像素为左右内边距,1 像素为左右边框。

image.png

  • border-box 盒子模型将元素的边框包含在内,也就是说,盒子的宽度和高度指的是整个元素框的尺寸,包括边框和内边距。在 border-box 中,盒子的宽度和高度指的是内容区域加上内边距和边框的总宽度。例如:
box-sizing: border-box;
width: 100px;
padding: 10px;
border: 1px solid black;

上述样式设置下,元素的实际宽度为 100 像素,其中包括了内容宽度、左右内边距和左右边框。

可以看出,border-box 盒子模型更加符合常规的设计理念,更容易控制盒子的大小和布局。因此,在实际开发中,一般会将盒子模型设置为 border-box。但需要注意的是,在使用 border-box 盒子模型时,必须考虑到边框和内边距对元素尺寸的影响。

content-box 也还是有用

虽然 border-box 盒子模型更加常用,但在某些情况下 content-box 也有一定的应用场景。例如:

  1. 希望在布局时精确控制元素的尺寸。

当使用 content-box 盒子模型时,通过对元素的宽度和高度进行设置,可以精确地控制元素的实际尺寸。这样就能够避免边框和内边距所带来的影响,从而方便地实现布局效果。

  1. 需要在不同浏览器之间保持一致的盒子模型。

由于 border-box 盒子模型在 IE6-7 中存在兼容性问题,因此在某些情况下可能需要使用 content-box 盒子模型来保证各个浏览器之间的一致性。

  1. 元素默认使用 content-box 盒子模型。

在某些情况下,如果没有对元素的盒子模型进行设置,那么元素就会默认使用 content-box 盒子模型。此时,如果需要修改盒子模型,就需要显式地对元素进行设置,否则会造成布局错误等问题。

综上所述,content-box 盒子模型虽然不如 border-box 盒子模型广泛使用,但在某些情况下仍然有其应用场景。

什么是BFC

BFC(Block Formatting Context)指的是块级格式化上下文,是一种 Web 页面中盒模型布局规则的解析器,它是 W3C CSS2.1 规范中的一个概念。

BFC 是 Web 页面中一个独立的渲染区域,具有一定的独立性和封闭性,主要有以下特点:

  1. 浮动元素:BFC在计算高度时,内部浮动元素的高度也要计算在内,也就是说技术BFC区域内哪怕只有浮动元素,BFC的高度也不会发生塌缩。
  2. margin重叠:BFC内部相邻的BOX设置margin会重叠,并且优先使用值最高的margin。
  3. 内外独立:BFC是一个独立的区域,其内部的元素不会影响到外部,外部的元素也不会影响到内部。
  • 触发条件:

    • 根元素
    • position: absolute/fixed
    • display: inline-block、table-cell、table-caption、flex、inline-flex、grid 或 inline-grid
    • float 属性值不为 none
    • ovevflow !== visible
  • 规则:

    • 属于同一个 BFC 的两个相邻 Box 垂直排列
    • 属于同一个 BFC 的两个相邻 Box 的 margin 会发生重叠
    • BFC 中子元素的 margin box 的左边, 与包含块 (BFC) border box的左边相接触 (子元素 absolute 除外)
    • BFC 的区域不会与 float 的元素区域重叠
    • 计算 BFC 的高度时,浮动子元素也参与计算
    • 文字层不会被浮动层覆盖,环绕于周围
  • 应用:

    • 阻止margin重叠
    • 可以包含浮动元素 —— 清除内部浮动(清除浮动的原理是两个div都位于同一个 BFC 区域之中)
    • 自适应两栏布局
    • 可以阻止元素被浮动元素覆盖

为什么要清除浮动

在 Web 页面中,浮动是一种常用的布局技术,可以使元素脱离文档流并沿着其他元素浮动

浮动元素在父级元素高度不确定时,会导致布局错乱和不可预测的结果:

  1. 父元素高度塌陷:当子元素设置了浮动属性后,子元素从文档流中脱离,不再占据空间。如果父级元素没有设置高度或者指定了固定高度,那么它将无法正确计算其自身高度,从而导致父元素高度塌陷的问题。
  2. 兄弟元素位置错乱:当一个浮动元素出现在文档流中时,它会影响到后续元素的位置和布局。如果多个浮动元素相互交错,则可能导致元素位置错乱的问题。
  3. 内容溢出:当浮动元素超出了其父级元素的范围时,可能会导致内容溢出和页面布局错乱的问题。

因此,为了避免这些问题,我们需要清除浮动。可以使用以下方法来清除浮动:

  1. BFC:父元素设置 overflow 属性值为 hidden、auto 或 scroll
  2. clear: 使用 clear 属性清除浮动(clear: both; 表示不允许浮动元素在两侧出现。)
  3. 伪元素:使用伪元素清除浮动

示例

  1. 父元素设置 overflow 属性值为 hidden、auto 或 scroll

通过给父元素设置 overflow 属性值为 hidden、auto 或 scroll,可以创建一个新的 BFC(块级格式化上下文),从而使浮动元素不会影响到其他元素的布局。例如:

<style>
    .parent {
        overflow: hidden;
    }
    .child {
        float: left;
        width: 100px;
        height: 100px;
        margin-right: 10px;
        background-color: red;
    }
</style>

<div class="parent">
    <div class="child"></div>
    <div class="child"></div>
    <div class="child"></div>
</div>

在这个例子中,将父元素的 overflow 属性值设置为 hidden,从而创建了一个新的 BFC 块级格式化上下文,避免了浮动元素对页面布局的影响。

  1. clear: both;

使用 clear 属性可以清除浮动,让包含元素正确地包含其内部的浮动元素,并且不会影响到其他的页面元素。例如:

<style>
    .parent::after {
        content: ".";
        display: block;
        height: 0;
        visibility: hidden;
        clear: both;
    }
    .child {
        float: left;
        width: 100px;
        height: 100px;
        margin-right: 10px;
        background-color: red;
    }
</style>

<div class="parent">
    <div class="child"></div>
    <div class="child"></div>
    <div class="child"></div>
</div>

什么是margin重叠

Margin 重叠指的是当两个相邻元素的 margin 值发生重叠时,其中一个或两个 margin 的合成值会变为单独 margin 的最大值。具体来说,当上下两个相邻元素的 margin 值都为正数时,它们之间的 margin 会发生重叠,重叠后的 margin 值将取二者中的较大值。

是一些常用的方法:

  1. padding/border:使用 padding 或 border 属性代替 margin,从而避免 margin 重叠的问题。
  2. BFC:创建新的 BFC 块级格式化上下文,从而避免 Margin 重叠的问题。