在块级元素设定 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 中的 auto 对于不同的元素类型有不同的取值。但是在任何情况下,都为以下两种取值之一:
父元素剩余空间(available space)的值
- 普通块级元素(static / relative) 设定 width 值时的 margin-left 和 margin-right
0 px
- 行内元素(inline), float 以及 position 值为 absolute 或 fixed
- 元素的 margin-top 和 margin-bottom
- 普通块级元素未设定 width 值时的 margin-left 和 margin-right
块级元素 width 的默认值为 auto.
事实上,对于不同的元素类型,width: auto 有不同的含义:
.parent {
position: relative;
background: grey;
width: 200px;
height: 100px;
}
.child {
background: blue;
}
<div class="parent">
<div class="child">
这是一段文本
div>
div>
child 是一个普通的 div 元素,没有设置 width,即 width 为默认值 auto,效果如下:
fit-content 也称为 shrink-to-fit,自行体会。
如果将 child 的 display: inline-block 或者 width: fit-content,效果如下:
内部元素中宽度值最大元素的宽度为最终容器的宽度
如果将 child width: min-content,效果如下:
如果将 child width设置为 max-content,同时换一段较长的文本,效果如下:
因此我们可以知道,对于 div 元素的 width 默认值 auto 代表 fill-available,即撑满可用空间,那么自然 margin-left / margin-right 的 auto 值只能为 0 了。
事实上,只要元素 width 不设置为 fill-available 或 100%,就可以达到水平居中的效果。比如我们将 width 设置为 min-content, max-content, fit-content.
.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
这种现象和 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-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 可以使元素居中的原理。(主要是标准规定)