绝对定位 + margin: auto 实现水平垂直居中

2017/04/17 | 2分钟阅读 | 更新于 2017/04/17

话说,面试官都喜欢问一个问题,“怎么让一个元素(比如图片)水平垂直居中(😏)”,我感觉这个题目可以考察到很多不同的CSS属性的以及相互作用,于是我就把这道题出给了刚接触前端的学弟们,要求是方法越多越好,然后来源不限,但是要自己理解。然后今天我就收到了一个意外的答案:

.img-center {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  margin: auto;
}

说意外是我完全没试过,于是写个Demo试试,完美实现,于是去找了找,看到张鑫旭大大的文章 ,顺便也研究了下原理。

说起来,看到这个写法,我想到了两个东西,一个是用position: absolute;position: fixed;搭配lefttoprightbottom去实现一些一边稀奇古怪的布局,比如一栏顶宽,一栏自适应什么的。然后另一个就是一个常用的水平居中写法:

.center {
  display: block;
  width: 480px;
  margin: 0 auto;
}

这个的原理目测是来自这一条⬇

10.3.3 Block-level, non-replaced elements in normal flow

If both ‘margin-left’ and ‘margin-right’ are ‘auto’, their used values are equal. This horizontally centers the element with respect to the edges of the containing block.

https://www.w3.org/TR/CSS21/visudet.html#blockwidth

如果 margin-leftmargin-top 都是auto,那么它们取相等的值…


然后刚刚提到的水平垂直居中的部分在这里⬇

10.3.7 Absolutely positioned, non-replaced elements

If none of the three is ‘auto’: If both ‘margin-left’ and ‘margin-right’ are ‘auto’, solve the equation under the extra constraint that the two margins get equal values, unless this would make them negative …

https://www.w3.org/TR/CSS21/visudet.html#abs-non-replaced-width

就是说,如果left,right,width,都不是auto,并且margin-left和margin-right都是auto,那么margin取相等的值,除非这会导致它们取到负值。 然后如果没有left和right的话,在仅有width的情况下,left会取0(ltr),元素就居左了。 同时如果left和right为有值,margin平分的是减掉width和left以及right的值(其实还有padding和border)。

10.6.4 Absolutely positioned, non-replaced elements

If none of the three are ‘auto’: If both ‘margin-top’ and ‘margin-bottom’ are ‘auto’, solve the equation under the extra constraint that the two margins get equal values.

https://www.w3.org/TR/CSS21/visudet.html#abs-non-replaced-width

这一段跟前一段差不多,不过是margin-top和margin-bottom。

然后审查元素看看:

【✔】确实是通过margin居中的。

最后,放一个复杂版本,来看下在有各种复杂属性的情况下的计算结果,注意left值:


🔮

© 2026 香蕉引擎故障报告

🌱 Powered by Hugo with theme Dream.

关于

要怎么介绍自己呢,🤔。

很早以前是作为 Web 前端在学习的,但是工作第一年就成为了全干工程师。喜欢尝试各种东西,什么都会一点。

一直很喜欢 Ebiten 游戏引擎 ,特别简洁,用它做过一些小东西,可以查看这个分类 。另外特别推荐这个木鱼 ,是一个相对完整的小玩意儿,包含手搓的一个简单的 UI 框架;支持鼠标和键盘操作;有多语言和主题切换功能;同时支持 Web 端和客户端。它的源代码在 bin16/wooden-fish

主题

网站基于 Hugo,当前使用的是 hugo-theme-dream 主题的修改版 ,根据我的需要,做了一些对 PaperMod 的兼容。

我自己也写过主题 ,但是没有别人写的好看。

正在从我的笔记中往外搬运内容

等待更新:

  • 从《锈湖》中学了些什么东西
  • 我拿 React 写解谜游戏的经过
  • 基于 Pocketbase 的 Pocket Memos
  • 数独!