[TOC]
前言
本文介绍CSS中的水平居中。如果只想看结论,则可以直接跳到文末的总结即可。
让 inline 或 inline-xxx 元素在父元素内水平居中
如果是想让一个 inline 或 inline-xxx (inline-block, inline-table, inline-flex等)的元素在父元素中水平居中。例如:纯文本span/label,链接 a,input 等元素
- 前提: 父元素必须是 block 类型的元素,如果不是,则要为其设置
display: block
- 设置方式:为父元素设置
text-align: center
代码:
父元素{
text-align: center;
}
例:
<div class="parent">
I'm an horizontally-centered inline element (text).
</div>
<div class="parent">
<a href="#0" class="child">One</a>
<a href="#0" class="child">Two</a>
<a href="#0" class="child">Three</a>
<a href="#0" class="child">Four</a>
</div>
.parent{
text-align: center;
border: 1px solid black;
margin: 20px 0;
width: 500px;
/* height: 100px; */
}
.child {
text-decoration: none;
background: #333;
border-radius: 5px;
color: white;
padding: 3px 8px;
}
效果:
注意:
- 上述css中,我们没有为父元素
.parent
显式地设置高度,则从上图来看,它会紧紧包裹子元素。如果我们想要效果稍微美观点,可以给它添加一些 padding等。但是只要没有显式地为父元素设置高度,那么很容易被误解为,这种代码设置方式,不仅能让子元素水平居中,还能让子元素垂直居中。至于原因,请看下面2的探讨。 - 如果我们为父元素
.parent
显式地设置高度,效果如何呢?修改css中.parent
的代码,为其添加设置高度的代码,如下:
.parent{
...
height: 100px;
}
则效果图如下:
由上图可以发现,这里所介绍的代码设置方式,只能实现“让子元素水平居中”的效果,无法让子元素垂直居中。当然了,如果不显式地为父元素设置高度,那么从实际效果上看,确实能同时实现让子元素水平和垂直居中的效果,但你需要知道这其中的原因,避免突然有一天为父元素显式设置了高度以后,原先子元素垂直居中的效果没了,你还在困惑。
让 block 元素在父元素内水平居中
如果是想让一个 block 的元素在父元素中水平居中,例如:div,p等元素,则
- 前提:该子元素必须有一个固定的 width 数值(否则它默认会占满整个父元素的宽度,从而不存在水平居中的问题)
- 设置方式:为该子元素设置左右 margin 都为 auto
代码:子元素{ margin-left: auto; margin-right: auto; }
例:
<div class="parent">
<div class="child">
I'm a block level element and am horizontally centered.
</div>
</div>
.parent {
width: 400px;
/* height: 300px; */
background: white;
margin: 20px 0;
border: 1px solid black;
}
.child {
margin: 0 auto;
width: 200px;
background: black;
padding: 20px;
color: white;
}
效果:
和前边的例子同理,该例子中,我们也是没有显式地为父元素设置 padding和高度,导致呈现的效果看上去像“同时实现了让子元素水平和垂直居中”。但你也要意识到,一旦为父元素显式地设置了高度,那么子元素就不再垂直居中了。例如:我们为上述代码中的 .parent
添加代码 height: 300px;
, 则效果如下图:
由上图发现,一旦为父元素显式设置了高度,那么子元素就不再垂直居中了。
让 inline 或 inline-xxx 或 block 元素在父元素内水平居中,或者让 inline 元素在另一个 inline 元素内水平居中
- 前提:
- 如果是让inline 或 inline-xxx 或 block 元素在父元素内水平居中,则前提:
- 父元素可以是block元素,也可以是 inline-block 元素。
- 要居中的子元素必须有一个固定的 width 数值
- 如果是让inline 或 inline-xxx 元素在 inline父元素内水平居中,则似乎没有什么前提条件。如果父元素不设置宽度,则在为其设置了
display: flex
以后,其宽度默认是占满其父容器的宽度。
- 如果是让inline 或 inline-xxx 或 block 元素在父元素内水平居中,则前提:
- 设置方式: 为父元素使用 flex 布局
- 代码:
父元素 { display: flex; flex-direction: row; justify-content: center; }
例1:父元素是 block元素
<div class="parent">
<span class="child">span1</span>
<span class="child">span2</span>
<span class="child">span3</span>
</div>
<div class="parent">
<div class="child">div1</div>
<div class="child">div2</div>
<div class="child">div3</div>
</div>
.parent {
width: 500px;
/* height: 150px; */
margin-bottom: 10px;
background-color: orange;
display: flex;
flex-direction: row;
justify-content: center;
}
.child {
width: 50px;
height: 100px;
border: 1px solid black;
margin: 0 10px;
}
效果:
同理,上述代码也是没有显式地为父元素设置高度,如果显式设置了高度,例如设置 height: 150px
, 则效果如下:
也是无法让子元素垂直居中的。
例2:父元素是 inline-block元素
将上述例1中的css代码做简单修改,为 .parent
添加 display: inline-block;
即可
.parent {
...
display: inline-block;
...
}
效果:
从上图来看,每个父元素内部的子元素都水平居中。但因为父元素自己是行内元素,导致两个父元素排到一行内了,而不是分布在两行。
如果为父元素添加高度,则效果图如下图,同理,也是无法让子元素垂直居中的,只能让子元素水平居中。
例3:父元素是 inline 元素
<span class="parent">
<span class="child">span1</span>
<span class="child">span2</span>
<span class="child">span3</span>
</span>
.parent {
width: 500px;
/* height: 150px; */
margin-bottom: 10px;
background-color: orange;
display: flex;
flex-direction: row;
justify-content: center;
}
.child {
width: 50px;
height: 100px;
border: 1px solid black;
margin: 0 10px;
}
效果:
如果为父元素添加高度,则效果图如下图,同理,也是无法让子元素垂直居中的,只能让子元素水平居中。
总结
- 让子元素在父元素内水平居中,有以下思路可供考虑:
- 如果子元素为行内元素,则为父元素设置
text-align: center;
或者为父元素设置 flex布局。 - 如果子元素为 block 元素,则为父元素设置左右 margin都为 auto,或者为父元素设置 flex布局。
- 如果子元素为行内元素,则为父元素设置
- 1中提到的这些思路,在一定条件下还能实现 "让子元素垂直居中" 的效果,条件是:不为父元素显式地设置高度(height)。在此条件下,为父元素设置合适的 padding,即可实现 "让子元素同时在水平和垂直方向上都居中,并且流出来的空白也较为美观" 的效果。