CSS 盒模型
盒模型是 CSS 布局的地基。页面上的每一个元素都是一个矩形盒子,从内到外由四层组成。理解了盒子怎么算尺寸、怎么相互影响,你才能精准控制元素的占地大小和间距。这一篇是后面所有布局章节的前置知识。
1. 盒子的四层结构
从里到外,每个盒子由这四层组成(像套娃一样):
- content(内容区):元素的实际内容,文字、图片所在的位置。
width和height默认就是设这里。 - padding(内边距):内容到边框之间的留白。让文字不贴边框,视觉上更舒服。
- border(边框):盒子四周的边线,可以有粗细、样式、颜色。
- margin(外边距):边框到相邻元素的距离。控制元素之间的空隙。
.box {
width: 200px; /* 内容区宽度 */
height: 100px; /* 内容区高度 */
padding: 20px; /* 内边距:内容到边框的距离 */
border: 2px solid #333;/* 边框 */
margin: 16px; /* 外边距:边框到相邻元素的距离 */
box-sizing: border-box;/* 让 width 包含 padding 和 border */
}记住一个类比:padding 是"盒子里的填充物"(在内部),margin 是"两个盒子之间的空隙"(在外部)。新手最容易搞反这俩——记住"padding 在内、margin 在外"。
2. box-sizing:最关键的属性
这是盒模型里最重要的概念,也是新手最容易踩的坑。默认情况下,你设的 width 只算内容区——加上 padding 和 border 后,盒子实际占的宽度会比设的大。
/* 默认 content-box:width 只算内容区 */
/* 实际占用宽度 = 200 + 20*2 + 2*2 = 244px */
.box-a {
width: 200px;
padding: 20px;
border: 2px solid #333;
box-sizing: content-box; /* 浏览器默认值 */
}
/* border-box:width 包含 padding 和 border */
/* 实际占用宽度 = 200px(内容区自动缩到 156px) */
.box-b {
width: 200px;
padding: 20px;
border: 2px solid #333;
box-sizing: border-box;
}
/* 全局推荐:所有元素都改用 border-box */
* {
box-sizing: border-box;
}看例子:同一个 width: 200px,content-box 下实际占 244px,而 border-box 下实际就 200px。后者把 padding 和 border 算进了 width,算尺寸直观得多。
实际项目几乎都会全局开 border-box,写在 reset 里:
这是前端工程的"默认规矩",几乎所有现代框架(Bootstrap、Tailwind)都这么做。从今天起,你的每个项目都应该开头加这一行。
3. padding 简写
padding 和 margin 的简写规则完全一样,掌握一个就会另一个。规则是从 12 点方向开始顺时针:上、右、下、左。
.box {
/* 四个方向各设 */
padding-top: 10px;
padding-right: 20px;
padding-bottom: 10px;
padding-left: 20px;
/* 简写:上 右 下 左(从 12 点方向顺时针) */
padding: 10px 20px 10px 20px;
/* 两个值:上下 左右 */
padding: 10px 20px;
/* 一个值:四个方向全相同 */
padding: 10px;
}简写省略规则:写一个值=四个方向都一样;写两个值=上下、左右;写三个值=上、左右、下;写四个值=上、右、下、左。这和时钟方向一致,记住了就再也不会写反。
4. margin 简写与水平居中
margin 简写和 padding 完全一致,但有一个 padding 做不到的常用技巧:水平居中。
.box {
/* 简写规则和 padding 完全一致 */
margin: 10px 20px; /* 上下 10,左右 20 */
/* 居中一个有固定宽度的块级元素 */
width: 600px;
margin: 0 auto; /* 上下 0,左右 auto = 自动平分 = 水平居中 */
/* 负 margin:让元素超出父级或重叠(慎用) */
margin-top: -10px;
}margin: 0 auto 是把左右都设成 auto,浏览器会自动平分剩余空间,从而让块级元素在父容器里水平居中。前提是元素必须有明确的 width(没有宽度,auto 就没剩余空间可分了)。
注意:margin 可以是负值,让元素超出父级或与相邻元素重叠。padding 不能是负值。
5. margin 合并(塌陷)— 必踩的坑
这是新手最常遇到的"诡异现象":两个上下相邻的块级元素,它们的上下 margin不会相加,而是取较大者。比如 A 的下边距是 30px,B 的上边距是 20px,实际间距只有 30px,不是 50px。
<!-- 上下相邻块级元素的 margin 会"合并"取较大值 -->
<style>
.a { margin-bottom: 30px; }
.b { margin-top: 20px; }
/* 两个段落之间的实际间距是 30px,不是 50px */
</style>
<p class="a">第一段</p>
<p class="b">第二段</p>
<!-- 解决方法 1:改成 padding -->
<!-- 解决方法 2:给父元素加 overflow: hidden 或 padding -->
<!-- 解决方法 3:用 Flex/Grid(它们不会发生 margin 合并) -->这只发生在块级元素的上下方向(左右不合并,父子的上下也会合并)。解决办法有几个:
- 改用
padding代替 margin。 - 给父元素加
overflow: hidden、padding-top或border-top。 - 最推荐:用 Flex 或 Grid 布局,它们根本不会发生 margin 合并。这也是为什么现代开发很少再遇到这个问题。
6. display 类型
每个元素都有一个 display 属性,决定它怎么"摆"在页面上。常见取值:
/* block:独占一行,可设宽高 */
div, p, h1, ul, li { display: block; }
/* inline:不换行,宽高无效(只占内容那么大) */
span, a, strong, em { display: inline; }
/* inline-block:不换行,但可以设宽高(最佳折中) */
.btn { display: inline-block; padding: 8px 16px; }
/* none:完全隐藏,不占空间 */
.modal { display: none; }
/* flex / grid:把元素变成弹性/网格容器 */
.toolbar { display: flex; }
.gallery { display: grid; }- block(块级):独占一行,可以设宽高。典型:div、p、h1、ul。
- inline(行内):不换行,设宽高无效。典型:span、a、strong。
- inline-block(行内块):不换行,但可以设宽高。常用于按钮、标签。
- none:完全隐藏,不占空间(区别于
visibility: hidden,后者还占位置)。 - flex / grid:把元素变成布局容器(后续章节专讲)。
注意:行内元素(inline)设宽高、上下 margin/padding 都无效或表现异常——想给 <a> 或 <span> 设尺寸,把它改成 inline-block 或 flex 即可。
小结
盒模型是布局的原子:content 是内容、padding 是内部留白、border 是边框、margin 是外部空隙;全局开 box-sizing: border-box 让尺寸直观;上下 margin 会合并,改用 padding 或 Flex 解决;display 决定元素怎么摆。下一篇讲文本与字体——让文字真正好看起来的那些属性。
← 上一篇 CSS 选择器
下一篇 CSS 文本与字体 →