CSS 盒模型、解决方案、BFC 原理讲解

1,541 阅读3分钟

PS:内容比较基础,目的只是覆盖面试知识点,大佬可以 history.back(-1)

W3C 标准盒模型 & IE 怪异盒模型

页面上显示的每个元素(包括内联元素)都可以看作一个盒子,即盒模型( box model )

盒模型由 4 部分组成,从内到外分别是:content padding border margin

W3C 标准盒模型一个元素的宽度(高度以此类推)应该这样计算:


                                            
一个元素的宽度 =  content
盒子总宽度 = margin-left + border-left + padding-left + width + padding-right + border-right + margin-right

                                        

IE 怪异盒模型一个元素的宽度(高度以此类推)却是这样计算的:


                                            
一个元素的宽度 =  content + padding + border
盒子总宽度 = margin-left + width + margin-right

                                        

解决方案 box-sizing


                                            
// W3C 标准盒模型(浏览器默认)
box-sizing: content-box;
// IE 怪异盒模型
box-sizing: border-box;

                                        

当我们设置 box-sizing: border-box; 时,borderpadding 就被包含在了宽高之内,和 IE 盒模型是一样的。

所以,为了避免你同一份 css 在不同浏览器下表现不同,最好加上:


                                            
*, *:before, *:after {
  -moz-box-sizing: border-box;
  -webkit-box-sizing: border-box;
  box-sizing: border-box;
}

                                        

JS 如何获取盒模型对应的宽和高


                                            
<style>
  * {
    margin: 0;
    padding: 0;
  }
  #box {
    width: 100px;
    height: 100px;
    padding: 50px;
    border: 5px solid red;
    margin: 50px;
  }
</style>
<div id="box" style=""></div>
<script>
  let box = document.getElementById('box')
  // 只能取到内联样式的宽高
  console.log('style:' + box.style.width) // 100px
  // 内联样式和外联样式的宽高都能取到,但只有 IE 支持
  console.log('currentStyle:' + box.currentStyle.width) // 100px
  // 内联样式和外联样式的宽高都能取到,几乎所有主流浏览器都支持
  console.log('getComputedStyle:' + getComputedStyle(box).width) // 100px
  // 内联样式和外联样式的宽高都能取到,几乎所有主流浏览器都支持,取到的是盒子总宽度
  console.log('getBoundingClientRect:' + box.getBoundingClientRect().width) // 210
</script>

                                        

BFC

BFC:块级元素格式化上下文

IFC:内联元素格式化上下文(面试不常考)

BFC 原理

  1. 在 BFC 的垂直方向上,边距会发生重叠
  2. BFC 区域不会与 浮动区域重叠
  3. BFC 在页面上是一个独立的容器,与其他元素互不影响
  4. 计算 BFC 高度时,浮动元素也会参与计算

如何创建 BFC

  1. float 值不为 none,只要设置了浮动,当前元素就创建了一个 BFC
  2. position值不为static,只要设置了定位,当前元素就创建了一个 BFC
  3. display 值不为默认,只要设置了display,当前元素就创建了一个 BFC
  4. overflow 值不为 visible,只要设置了overflow,当前元素就创建了一个 BFC

                                            
overflow: hidden;

                                        

BFC 使用场景

解决边距重叠问题

当元素都设置了 margin 边距时,margin 将取最大值。为了不让边距重叠,可以给子元素加一个父元素,并设置该父元素为 BFC


                                            
<div class="box" id="box">
  <p>Lorem ipsum dolor sit.</p>
  <div style="overflow: hidden;">
    <p>Lorem ipsum dolor sit.</p>
  </div>
  <p>Lorem ipsum dolor sit.</p>
</div>

                                        

侵占浮动元素的位置

设置非浮动元素为 BFC 即可


                                            
<style>
  .one {
    float: left;
    width: 100px;
    height: 100px;
    background-color: pink;
  }
  .two {
    height: 200px;
    background-color: red;
    /* 设置 BFC */
    overflow: hidden;
  }
</style>
<div class="one"></div>
<div class="two"></div>

                                        

清除浮动

BFC 原理第 4 条:计算 BFC 高度时,浮动元素也会参与计算

当然,清除浮动还有其他最佳实践,这里只是分析场景。


                                            
<style>
.one {
  background-color: pink;
  /* 设置 BFC */
  overflow: hidden;
}
.two {
  float: left;
}
</style>
<div class="one">
  <div class="two">hello world</div>
</div>