六维教程

CSS 盒模型(上)

布局里的一切,都可以抽象成盒子。页面上的每个元素,不管看起来是文字、图片还是色块,浏览器都把它当做一个盒子来处理。盒模型就是描述这个盒子的结构,它是 CSS 最重要的模型,没有之一。

盒子的四层结构

从内到外,盒子分四层。最里面是内容区 content,装的是文字、图片这些实际内容。往外一层是内边距 padding,内容区和边框之间的空隙,相当于盒子里的缓冲垫。再往外是边框 border,盒子的边界线。最外面是外边距 margin,盒子和其他盒子之间的距离,相当于盒子间的安全距离。

.box {
  width: 200px;
  padding: 20px;
  border: 2px solid #3498db;
  margin: 10px;
}

四层各有各的样式属性。padding 和 margin 都支持四个方向的单独设置,padding-top、padding-right、padding-bottom、padding-left,也支持简写,一个值管四个方向,两个值管上下和左右,三个值管上、左右、下,四个值按顺时针上右下左。border 可以拆成宽度、样式、颜色三部分。

width 只控制内容区

默认情况下,width 和 height 设置的是内容区的尺寸,不含 padding 和 border。这带来一个经典问题,盒子总宽度会超出你的预期。

.box {
  width: 200px;
  padding: 20px;
  border: 2px solid #333;
}

看起来是 200 像素宽的盒子,实际占 200 加两个 20 再加两个 2,一共 244 像素。设计稿里量好的尺寸,填进代码总会莫名变宽,就是它捣的鬼。

box-sizing 的救赎

解决方法是换一个尺寸算法。box-sizing 有两个值,content-box 是默认的行为,border-box 让 width 直接包含 padding 和 border。

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

同样是 200 像素,这次是总宽 200,内容区自动被压缩到 156。写代码时心理负担小很多,说 200 就是 200。实际项目里,几乎所有人都会全局启用 border-box。

* {
  box-sizing: border-box;
}

一行代码,全站统一,再也不用纠结宽度算错。注意 margin 不在 box-sizing 管的范围里,它永远在外面。

块级和行内元素的差异

同样是盒子,块级元素和行内元素的盒模型表现不同。块级元素,比如 div、p,width 和 height 正常生效,上下 margin 也生效,默认占满整行。行内元素,比如 span、a,width 和 height 无效,左右 margin 和 padding 生效,上下 padding 和 margin 会影响视觉但不会挤开上下内容,容易和旁边的文字重叠。

行内元素想按盒子来控制尺寸,把 display 改成 inline-block 或者 block 就行,这块在讲文档流时会细说,现在先记住有这个差异。

看盒子的工具

浏览器开发者工具是学盒模型最好的老师。按 F12 打开,选中一个元素,样式面板下方会有一个盒模型图,中间是内容区,往外依次是 padding、border、margin,每个区域都有数值,还能直接点数值修改。更直观的是 Elements 面板里元素高亮区域,鼠标悬停就能看到内容区、padding、border 各自的范围,蓝的绿的黄的,一目了然。哪里不对劲,打开它看两眼,基本都能定位。

小结

盒模型四层,内容、内边距、边框、外边距。默认 width 只管内容区,全局启用 border-box 解决宽度焦虑,块级和行内元素的表现不同,调试靠开发者工具。下一篇处理盒模型的疑难杂症,边距合并。

上一篇
CSS 继承
下一篇
CSS 盒模型(下)