为什么 margin:auto 可以水平居中

  1. 前提知识
  2. 决定水平位置的等式
  3. 等式左边大于右边
  4. 等式右边大于左边
  5. margin:auto

前提知识

这个涉及到盒子的水平布局。
在盒子模型概念里,位于一个盒子元素内的盒子元素,只能使用其外部盒子的 内容 区域,即除去外部的 border,padding

(此图片搬运菜鸟教程)
当盒子的宽度小于外部盒子的宽度时,盒子在水平方向的位置是怎样的?

决定水平位置的等式

当盒子的宽度小于外部盒子的宽度时,盒子在水平方向的位置由其自身的 7 个 CSS 属性的值决定:

margin-left 默认值 0
border-left
padding-left
width 默认值 auto
padding-right
border-right 
margin-right 默认值 0

规定这些属性的值必须满足下面的等式:

7 个属性的值的和 = 外部盒子的 width 值

等式不成立,称为 过渡约束。当浏览器加载 CSS 时,有的会被自动调整。
padding,border 一般不会被浏览器修改。浏览器优先修改 width,margin-left,largin-right 中被明确设置为 auto 的属性的值使等式成立(注意 width 默认值就是 auto)。
调整的情况为:

  1. 当 7 个属性都不存在值为 auto 的情况,浏览器会调整 margin-right 以使等式满足(因为默认是从左向右排列的,当从右向左排列时,会调整 margin-left 以满足等式)
    1. 当等式左边大于右边时,有些值会被强制改为负值以使等式成立。
    2. 当等式左边小于右边时,有些值会增加以使等式成立。
  2. margin-left,margin-right,width 这三个属性中存在 auto 情况时:
    1. 三个属性中只有一个为 auto,则浏览器会调整此属性使等式成立。
    2. 两个属性为 auto,再看情况:
      1. 若其中 width 为 auto,则另一个为 automargin 属性值的 auto 就被浏览器改为 0。
      2. 两个 margin 为 autowidth 为固定值,则这两个 margin 值相等,即平分外部盒子剩余空间
    3. 这三个都为 auto,则宽度变为最大

不要把 auto 简单地看作 0

总结:当 7 个属性的值小于外部盒子的 width,则由浏览器根据规则选择其中的属性进行操作以满足等式。

等式左边大于右边

.outer {
    height: 200px;
    width: 800px;
    border: 5px solid;
}

.inner {
    height: 200px;
    background-color: goldenrod;
}
</style>

200 + 0 + 0 + 1000 + 0 + 0 > 800,浏览器修改了 margin-right 为 - 400px

验证,满足上述规则 2.1

等式右边大于左边

.inner {
    height: 200px;
    background-color: goldenrod;

    width: 200px;
    margin-right: 200px;
}

0 + 0 + 0 + 200 + 0 + 0 + 200 < 800,浏览器修改 margin-right 为 600px

当显示写出 margin-left:100px,使得等式右边仍然大于左边时,浏览器仍然选择去修改 margin-right

当显示写出 margin-left:auto 时,浏览器终于肯修改 margin-left 了!

margin:auto

由于 margin 分四个方向,这里的 auto 其实应该写作 margin:0 auto,即上下为 0,左右为 auto。


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论。
我的空间