margin: 0 auto 水平居中原理

前言

块级元素设定 width 值 的情况下,设置其 margin: 0 auto 可以在父级元素中达到水平居中

在 CSS 居中布局界,这可以说是一个烂梗了。但如果继续追问其原理,很多人就语焉不详了。网络中很多文章有两个问题:描述不全面或者延伸太广,难以聚焦,时间一长容易遗忘

所以写这篇文章的目的是在收敛知识扩展面的同时又能抓住要点,就算时间久了也可以从要点出发把整个原理。

居中示例

 .parent {
     background: grey;
     width: 200px;
     height: 40px;
 }
.child {
    background: blue;
    width: 100px;
    margin: 0 auto
}
 <div class="parent">
     <div class="child">
        水平居中
     div>
 div>

效果如下:margin-left 和 margin-right 的计算值为 (200 - 100) / 2 = 50 px
margin: 0 auto 水平居中原理_第1张图片

要点分析

  1. margin 值为 auto 代表什么?
  2. 块级元素 width 为什么一定要设值?

margin 值为 auto 代表什么?

margin 中的 auto 对于不同的元素类型有不同的取值。但是在任何情况下,都为以下两种取值之一

  1. 父元素剩余空间(available space)的值
         - 普通块级元素(static / relative) 设定 width 值时的 margin-left 和 margin-right

  2. 0 px
         - 行内元素(inline), float 以及 position 值为 absolute 或 fixed
         - 元素的 margin-top 和 margin-bottom
         - 普通块级元素未设定 width 值时的 margin-left 和 margin-right

块级元素 width 为什么一定要设值

块级元素 width 的默认值为 auto.

事实上,对于不同的元素类型,width: auto 有不同的含义:

 .parent {
 	 position: relative;
     background: grey;
     width: 200px;
     height: 100px;
 }
.child {
    background: blue;
}
 <div class="parent">
     <div class="child">
        这是一段文本
     div>
 div>

div 元素:fill-available 撑满可用空间

child 是一个普通的 div 元素,没有设置 width,即 width 为默认值 auto,效果如下:
margin: 0 auto 水平居中原理_第2张图片

inline-block 元素: fit-content

fit-content 也称为 shrink-to-fit,自行体会。

如果将 child 的 display: inline-block 或者 width: fit-content,效果如下:
margin: 0 auto 水平居中原理_第3张图片

min-content 固有的最小宽度

内部元素中宽度值最大元素的宽度为最终容器的宽度

如果将 child width: min-content,效果如下:
margin: 0 auto 水平居中原理_第4张图片

max-content

如果将 child width设置为 max-content,同时换一段较长的文本,效果如下:
margin: 0 auto 水平居中原理_第5张图片
因此我们可以知道,对于 div 元素的 width 默认值 auto 代表 fill-available,即撑满可用空间,那么自然 margin-left / margin-right 的 auto 值只能为 0 了。

事实上,只要元素 width 不设置为 fill-available 或 100%,就可以达到水平居中的效果。比如我们将 width 设置为 min-content, max-content, fit-content.

特殊情况: absolute 元素 margin: auto 水平垂直居中

 .parent {
 	 position: relative;
     background: grey;
     width: 200px;
     height: 200px;
 }
.child {
	position: absolute;
    background: blue;
    width: 100px;
    height: 100px;
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;
    margin: auto;
}
 <div class="parent">
     <div class="child">
        水平垂直居中
     div>
 div>

效果如下:margin-left 和 margin-right 计算值为 (200 - 100) / 2 = 50 px
margin-top 和 margin-bottom 计算值为 (200 - 100) / 2 = 50 px
margin: 0 auto 水平居中原理_第6张图片
这种现象和 W3C 文档中的一段话有关:

关于 margin-left 和 margin-right 的:

"If all three of “left”, “width”, and “right” are “auto”: First set any “auto” values for “margin-left” and “margin-right” to 0… "

如果 left, width 和 right 都没有设置(即取默认值 auto),在这种情况下 margin-left 和 margin-right 的 auto 值为 0

“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”

如果 left, width 和 right 的值都设定了,此时如果 margin-left 和 margin-right 都为 auto, 即 (parent_width - width - left - right) / 2

为了验证上述的规定,我们将栗子中的 left 设为 50px. 由于 left 的作用,元素不再居中,但 margin-left 和 margin-right 均分剩余的空间,值为 (200 - 100 - 50 - 0) / 2 = 25 px

margin: 0 auto 水平居中原理_第7张图片
关于 margin-top 和 margin-bottom 的:

W3 文档描述与 margin-left / margin-right 相似:

“If all three of “top”, “height”, and “bottom” are auto, set “top” to the static position…”

如果 top, height 和 bottom 都没有设置(即取默认值 auto),在这种情况下 margin-top 和 margin-bottom 的 auto 值为 0

“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…”

如果 left, height 和 right 的值都设定了,此时如果 margin-top 和 margin-bottom 都为 auto, 即 (parent_height - height - top - bottom) / 2

这就是元素绝对定位时 margin: auto 可以使元素居中的原理。(主要是标准规定)

你可能感兴趣的:(CSS)