CSS中的水平居中

492 阅读5分钟

[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;
}

效果:

image.png

注意:

  1. 上述css中,我们没有为父元素 .parent 显式地设置高度,则从上图来看,它会紧紧包裹子元素。如果我们想要效果稍微美观点,可以给它添加一些 padding等。但是只要没有显式地为父元素设置高度,那么很容易被误解为,这种代码设置方式,不仅能让子元素水平居中,还能让子元素垂直居中。至于原因,请看下面2的探讨。
  2. 如果我们为父元素 .parent 显式地设置高度,效果如何呢?修改css中.parent的代码,为其添加设置高度的代码,如下:
.parent{
    ...
    height: 100px;
}

则效果图如下:

image.png

由上图可以发现,这里所介绍的代码设置方式,只能实现“让子元素水平居中”的效果,无法让子元素垂直居中。当然了,如果不显式地为父元素设置高度,那么从实际效果上看,确实能同时实现让子元素水平和垂直居中的效果,但你需要知道这其中的原因,避免突然有一天为父元素显式设置了高度以后,原先子元素垂直居中的效果没了,你还在困惑。

让 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;
}

效果:

image.png

和前边的例子同理,该例子中,我们也是没有显式地为父元素设置 padding和高度,导致呈现的效果看上去像“同时实现了让子元素水平和垂直居中”。但你也要意识到,一旦为父元素显式地设置了高度,那么子元素就不再垂直居中了。例如:我们为上述代码中的 .parent 添加代码 height: 300px;, 则效果如下图:

image.png

由上图发现,一旦为父元素显式设置了高度,那么子元素就不再垂直居中了。

让 inline 或 inline-xxx 或 block 元素在父元素内水平居中,或者让 inline 元素在另一个 inline 元素内水平居中

  • 前提:
    1. 如果是让inline 或 inline-xxx 或 block 元素在父元素内水平居中,则前提:
      • 父元素可以是block元素,也可以是 inline-block 元素。
      • 要居中的子元素必须有一个固定的 width 数值
    2. 如果是让inline 或 inline-xxx 元素在 inline父元素内水平居中,则似乎没有什么前提条件。如果父元素不设置宽度,则在为其设置了 display: flex 以后,其宽度默认是占满其父容器的宽度。
  • 设置方式: 为父元素使用 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;
}

效果:

image.png

同理,上述代码也是没有显式地为父元素设置高度,如果显式设置了高度,例如设置 height: 150px, 则效果如下:

image.png

也是无法让子元素垂直居中的。

例2:父元素是 inline-block元素

将上述例1中的css代码做简单修改,为 .parent 添加 display: inline-block; 即可

.parent {
    ...
    display: inline-block; 
    ...
}

效果:

image.png 从上图来看,每个父元素内部的子元素都水平居中。但因为父元素自己是行内元素,导致两个父元素排到一行内了,而不是分布在两行。

如果为父元素添加高度,则效果图如下图,同理,也是无法让子元素垂直居中的,只能让子元素水平居中。 image.png

例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;
}

效果:

image.png

如果为父元素添加高度,则效果图如下图,同理,也是无法让子元素垂直居中的,只能让子元素水平居中。

image.png

总结

  1. 让子元素在父元素内水平居中,有以下思路可供考虑:
    • 如果子元素为行内元素,则为父元素设置 text-align: center; 或者为父元素设置 flex布局。
    • 如果子元素为 block 元素,则为父元素设置左右 margin都为 auto,或者为父元素设置 flex布局。
  2. 1中提到的这些思路,在一定条件下还能实现 "让子元素垂直居中" 的效果,条件是:不为父元素显式地设置高度(height)。在此条件下,为父元素设置合适的 padding,即可实现 "让子元素同时在水平和垂直方向上都居中,并且流出来的空白也较为美观" 的效果。

参考资料