跳到主要内容

[Easy] 🏷️ Box Model

Default

Box ModelCSS 当中是被用来讨论如何设计布局的术语。他本身可以理解为一个包裹 HTML 元素的盒子,中间有四个主要的属性 :

  • content : 主要用于显示元素的内容,譬如文字。
  • padding : 元素的内容和元素边界的距离
  • margin : 元素对外其他元素的距离
  • border : 元素本身的边线

box-sizing

决定 Box Model 使用的类型,会通过 box-sizing 这个语法。

意思是指,当元素计算宽度和高度时,padding, border 这两个属性是采用对内填充还是对外扩充。

其预设值为 content-box,采用对外扩充,在这个条件下,除了元素自己的宽高外,额外的 padding, border 都要加入计算。如下 :

div {
width: 100px;
padding: 10px;
border: 1px solid #000;
}

这个 div 的宽度计算是 100px(width) + 20px(左右 padding) + 2px(左右 border) = 122px

border-box

显然上述这种方式并不可靠,会使前端开发时,被迫需要一直计算元素宽高,为了改善开发体验,自然得改采另一模式,即 border-box

如下例,在样式初始化时将全体元素 box-sizing 的值设为 border-box :

* {
box-sizing: border-box; // global style
}

如此一来,就会改采对内填充的形式,元素的宽高设计更为直觉,不必为了 paddingborder 去增减数字。

对比例题

假设有以下相同的样式设定:

.box {
width: 100px;
height: 100px;
padding: 10px;
border: 5px solid #000;
margin: 20px;
}

content-box(预设值)

  • 实际占用宽度 = 100px(width) + 20px(左右 padding) + 10px(左右 border) = 130px
  • 实际占用高度 = 100px(height) + 20px(上下 padding) + 10px(上下 border) = 130px
  • content 区域 = 100px × 100px
  • 注意margin 不计入元素宽度,但会影响与其他元素的距离

border-box

  • 实际占用宽度 = 100px(padding 和 border 向内挤压)
  • 实际占用高度 = 100px
  • content 区域 = 100px - 20px(左右 padding) - 10px(左右 border) = 70px × 70px
  • 注意margin 同样不计入元素宽度

视觉化对比

content-box:
┌─────────── margin (20px) ───────────┐
│ ┌──────── border (5px) ──────────┐ │
│ │ ┌──── padding (10px) ──────┐ │ │
│ │ │ │ │ │
│ │ │ content (100×100) │ │ │
│ │ │ │ │ │
│ │ └───────────────────────────┘ │ │
│ └─────────────────────────────────┘ │
└─────────────────────────────────────┘
总宽度:130px(不含 margin)

border-box:
┌─────────── margin (20px) ───────────┐
│ ┌──────── border (5px) ──────────┐ │
│ │ ┌──── padding (10px) ──────┐ │ │
│ │ │ │ │ │
│ │ │ content (70×70) │ │ │
│ │ │ │ │ │
│ │ └───────────────────────────┘ │ │
│ └─────────────────────────────────┘ │
└─────────────────────────────────────┘
总宽度:100px(不含 margin)

常见陷阱

1. margin 的处理

无论是 content-boxborder-boxmargin 都不会被计入元素的宽高,两种模式只影响 paddingborder 的计算方式。

.box {
box-sizing: border-box;
width: 100px;
padding: 10px;
border: 5px solid;
margin: 20px; /* 不计入 width */
}
/* 元素实际占用宽度仍是 100px,但与其他元素的距离会多 20px */

2. 百分比宽度

当使用百分比宽度时,计算方式也会受到 box-sizing 影响:

.parent {
width: 200px;
}

.child {
width: 50%; /* 继承父元素的 50% = 100px */
padding: 10px;
border: 5px solid;
}

/* content-box: 实际占用 130px(可能超出父元素) */
/* border-box: 实际占用 100px(刚好是父元素的 50%) */

3. inline 元素

box-sizinginline 元素不起作用,因为 inline 元素的 widthheight 设定本身就无效。

span {
display: inline;
width: 100px; /* 无效 */
box-sizing: border-box; /* 也无效 */
}

4. min-width / max-width

min-widthmax-width 同样受到 box-sizing 影响:

.box {
box-sizing: border-box;
min-width: 100px; /* 包含 padding 和 border */
padding: 10px;
border: 5px solid;
}
/* content 最小宽度 = 100 - 20 - 10 = 70px */

Reference