讲解
padding(内边距)和 margin(外边距)都支持 1~4 个值的简写:一个值四边相同;两个值是「上下、左右」;三个值是「上、左右、下」;四个值按顺时针「上右下左」。也都有单边写法 margin-top、padding-left 等。选择标准一句话:padding 是盒子「内部」的留白(背景色会延伸进去、点击区域会变大),margin 是盒子「对外」的距离(透明、不属于自己)。按钮想做大点击热区用 padding,两个卡片之间留空用 margin。
margin 有一个著名特性叫「外边距折叠」(margin collapsing):垂直方向上,相邻两个块级元素的 margin 不会相加,而是取较大者——上面的盒子 margin-bottom: 20px、下面的盒子 margin-top: 30px,实际间距是 30px 不是 50px。折叠还发生在父子之间(父元素没有 border、padding、内容隔开时,子元素的 margin-top 会「穿透」到父元素外面)和空盒子自身。注意折叠只发生在常规流的垂直方向,Flexbox 和 Grid 里的元素不折叠。
margin 还有两个实用招数:定宽块级元素写 margin: 0 auto 实现水平居中(auto 会平分剩余空间,但必须有确定宽度才有效);margin 允许负值,可以把元素拉出父容器或让相邻元素重叠,做头像堆叠效果时常用。padding 则不允许负值。另外切记:padding 和 margin 的百分比值(包括 padding-top)都相对「包含块宽度」计算,有人用 padding-top: 56.25% 做 16:9 的宽高比占位盒——现在更推荐直接用 aspect-ratio: 16 / 9。
示例
/* 简写:上 8、左右 16、下 24 */
.box {
margin: 8px 16px 24px;
padding: 12px 24px; /* 上下、左右 */
}
/* 定宽水平居中 */
.container {
width: 960px;
margin: 0 auto;
}
/* 外边距折叠:实际间距是 32px(取大者),不是 48px */
.paragraph {
margin-bottom: 16px;
}
.next-paragraph {
margin-top: 32px;
}
/* 负 margin:头像堆叠 */
.avatar-stack img {
width: 40px;
border-radius: 50%;
margin-left: -12px; /* 每个头像压住前一个 */
border: 2px solid #fff;
}
/* 16:9 视频占位(现代写法) */
.video-wrapper {
aspect-ratio: 16 / 9;
background: #000;
}
常见坑
- 被外边距折叠吓一跳:子元素的 margin-top 把父元素整个推下去了,像 margin 写错了对象。对策:父元素加 padding-top: 1px、border 或 overflow: hidden(创建块级格式化上下文)切断折叠,或者干脆改用 padding。
- 指望 margin 相加:垂直间距总是「取大不取和」,算出来的间距比预期小,先怀疑折叠。Flex/Grid 布局里没有折叠,行为反而更符合直觉。
- margin: 0 auto 不居中:元素没有确定宽度时 auto 没有可分的剩余空间,先确认 width/max-width 生效了;行内元素更是完全无效。
- 用 padding 做元素间间距:padding 属于元素自己,会撑大背景、边框和点击区域;元素之间的距离请用 margin 或父容器的 gap。
- padding-top 百分比猜错参照:50% 是父容器「宽度」的一半,不是高度的一半,想做正方形正好可以利用这一点(现在用 aspect-ratio 更直观)。
小结
padding 管内部、margin 管外部;简写按顺时针记;垂直 margin 会折叠取大者;margin: 0 auto 居中定宽块、负 margin 做叠层。下一章给盒子加上可见的边界:边框与圆角。