Menu

CSS margin 外边距:简写、margin auto 与外边距折叠

margin 是元素边框外侧的透明空间,用来把其他元素推开。本文讲解 margin 简写、用 margin: 0 auto 居中、负外边距、flexbox 中的 margin auto,以及垂直外边距为什么会折叠。

本页包含可运行的编辑器。编辑、运行,立即查看输出。

margin 是什么

margin(外边距)是元素边框外侧的空间。它始终是透明的,作用是把其他元素推开。在下面的示例中,灰色容器透过蓝色盒子周围的外边距显露出来:

灰色的那一圈不属于盒子:盒子自身的背景到边框就停止了。如果想要带有元素背景的空间,请使用 padding。

margin 简写

margin 接受一到四个值,顺序和 padding 一样,按顺时针排列:

声明上右下左
margin: 10px;10101010
margin: 10px 20px;10201020
margin: 10px 20px 30px;10203020
margin: 10px 20px 30px 40px;10203040

每一边也有自己的属性(margin-top、margin-right、margin-bottom、margin-left),还有跟随文字方向的逻辑属性(margin-inline-start、margin-inline-end、margin-block、margin-inline)。

和 padding 不同,margin 可以取 auto 和负值:

值示例说明
长度16px、1.5rem最常用
百分比5%四条边都相对于包含块的宽度计算
automargin: 0 auto由浏览器填入剩余空间
负值margin-top: -10px把元素或相邻元素拉近,可能重叠

用 margin: 0 auto 居中

margin: 0 auto 是让块级元素水平居中的经典写法。两侧都设为 auto,就是告诉浏览器把剩余空间平均分配。元素的宽度必须小于容器,否则没有剩余空间可分:

在常规流中,auto 外边距不能垂直居中(垂直方向的 auto 外边距会变成 0),对行内元素也不起作用。想全面了解居中方法,请看如何让 div 居中。

外边距折叠

两个垂直外边距相接时,它们不会相加,浏览器只保留较大的那个。这里第一个盒子设置了 margin-bottom: 30px,第二个设置了 margin-top: 20px,它们之间的间距是 30px,而不是 50px:

折叠是有意设计的:它让段落和标题可以各自带上自己的间距,相遇时又不会翻倍。真正容易让人踩坑的是第二种情况:子元素的上外边距跑出了父元素:

在第一个父元素中,子元素 30px 的外边距穿过父元素的上边缘发生了折叠,所以它把整个父元素往下推,而不是在父元素内部留出灰色空间。下面任意一种做法都能阻止它:

  • 给父元素设置 display: flow-root(和 overflow: hidden 不同,它不会裁剪任何内容)。
  • 给父元素的上边缘加上内边距或边框。
  • 让父元素成为 flex 或 grid 容器:flex 和 grid 项目的外边距永远不会折叠。

水平外边距永远不会折叠,浮动元素和绝对定位元素的外边距也不会。

负外边距

负外边距朝相反方向拉。设在上方或起始一侧时,它移动的是元素本身;设在下方或结束一侧时,它把下一个元素拉近。盒子之间可能重叠:

flexbox 中的 margin auto

在 flex 容器中,auto 外边距会占据它那一侧的全部剩余空间。这是把某一项推到一行最末端的最简单方法,而且在 flexbox 中 auto 在垂直方向上同样有效:

margin-inline-start: auto 把剩余空间放在“Log in”之前,无论页面是从左到右还是从右到左,它都会出现在这一行的末端。

常见错误

  • 在没有宽度的元素上使用 margin: 0 auto。 块级元素本来就会占满容器;请设置 width 或 max-width。
  • 在行内元素上使用 margin: auto。 保持行内的 span、a 或 img 的 auto 外边距等于 0。把它改成 display: block。
  • 把两个垂直外边距相加,以为会得到它们的和。 它们会折叠成较大的那个;在 flex 或 grid 中使用 gap,或者始终只用一个方向的外边距。
  • 子元素的外边距把父元素推开。 这是父子外边距折叠;给父元素加上 display: flow-root。
  • 在需要背景的地方用 margin 留空。 margin 是透明的;请改用 padding。

常见问题

CSS 中的 margin 是什么?

margin(外边距)是元素边框外侧的空间。它是透明的,会把相邻的元素推开。可以用 margin 设置,也可以用单边属性 margin-top、margin-right、margin-bottom 和 margin-left 分别设置。

margin: 0 auto 有什么作用?

它把上下外边距设为 0,再把水平方向剩余的空间平均分给左右外边距,于是块级元素在水平方向上居中。元素的宽度必须小于容器,例如 max-width: 600px。

为什么 margin auto 没有让元素居中?

通常是因为元素没有设置宽度(块级元素会占满容器,没有剩余空间可分),或者它是行内元素(默认的 span、a、img),行内元素的 auto 外边距等于 0。给它设置宽度和 display: block,或者在父元素上用 flexbox 或 grid 来居中。

什么是外边距折叠?

两个垂直外边距相遇时,例如一个段落的下外边距和下一个段落的上外边距,浏览器只取较大的那个,而不是把两者相加。这只发生在常规流中块级盒子的垂直外边距上,flex 和 grid 布局中不会发生。

margin 可以是负值吗?

可以。负外边距会把元素往那一侧拉,或者把下一个元素拉到它上面,因此盒子之间可能重叠。它适合做细微的对齐调整,也可以让元素突破容器的内边距。

Coddy 编程语言插图

和 Coddy 一起学编程

开始