CSS 盒模型

标准盒模型与 IE 盒模型的区别,以及 box-sizing 的使用

问题

CSS 盒模型有哪些类型?它们的区别是什么?如何通过 box-sizing 切换?

解答

盒模型组成

每个元素都是一个矩形盒子,由四部分组成:

+------------------------------------------+
|               margin                     |
|  +------------------------------------+  |
|  |            h38kz                  |  |
|  |  +------------------------------+  |  |
|  |  |          padding             |  |  |
|  |  |  +------------------------+  |  |  |
|  |  |  |        content         |  |  |  |
|  |  |  +------------------------+  |  |  |
|  |  +------------------------------+  |  |
|  +------------------------------------+  |
+------------------------------------------+

标准盒模型(content-box)

widthheight 只包含 content 区域。

.standard-box {
  box-sizing: content-box; /* 默认值 */
  width: 200px;
  padding: 20px;
  border: 5px solid #333;
}

/* 
 * 实际占用宽度 = 200 + 20*2 + 5*2 = 250px
 * width 只是 content 的宽度
 */

IE 盒模型(border-box)

widthheight 包含 content + padding + border。

.ie-box {
  box-sizing: border-box;
  width: 200px;
  padding: 20px;
  border: 5px solid #333;
}

/* 
 * 实际占用宽度 = 200px
 * content 宽度 = 200 - 20*2 - 5*2 = 150px
 */

对比示例

<!DOCTYPE html>
<html>
<head>
  <style>
    .box {
      width: 200px;
      height: 100px;
      padding: 20px;
      border: 5px solid #333;
      margin: 10px;
      background: #f0f0f0;
    }
    
    .content-box {
      box-sizing: content-box;
    }
    
    .border-box {
      box-sizing: border-box;
    }
  </style>
</head>
<body>
  <!-- 实际宽度: 200 + 40 + 10 = 250px -->
  <div class="box content-box">content-box</div>
  
  <!-- 实际宽度: 200px -->
  <div class="box border-box">border-box</div>
</body>
</html>

实际项目中的最佳实践

/* 全局重置,让所有元素使用 border-box */
*,
*::before,
*::after {
  box-sizing: border-box;
}

/* 这样设置宽度更直观 */
.container {
  width: 100%;
  padding: 16px; /* 不会撑破容器 */
}

获取元素尺寸

const el = document.querySelector('.box');

// 获取 content 尺寸
el.clientWidth;  // content + padding
el.clientHeight;

// 获取完整尺寸(包含边框)
el.offsetWidth;  // content + padding + border
el.offsetHeight;

// 获取计算后的样式
const style = getComputedStyle(el);
style.width;     // 返回 width 的计算值
style.boxSizing; // 返回 "content-box" 或 "border-box"

关键点

  • 标准盒模型width = content,实际宽度需要加上 padding 和 border
  • IE 盒模型width = content + padding + border,设置多少就占多少
  • box-sizingcontent-box(默认)和 border-box 切换两种模式
  • 推荐做法:全局设置 box-sizing: border-box,布局计算更直观
  • margin 不计入:两种盒模型的 width 都不包含 margin