元素居中,看这篇就够了

4,330 阅读4分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第1天,点击查看活动详情

前言

元素水平居中、垂直居中和水平垂直居中是日常开发中频繁会出现的需求,实现起来并没有难度。但对于新手而言,我个人认为,真正的痛点在于分不清不同的场景下应该使用哪种方法来实现。

要解决上述问题,最好的办法就是归纳总结,没有之一。通过这篇文章的学习,你将对元素居中有一个全面且清晰的了解。

水平居中

行内元素

实现行内元素水平居中,首先看它的父元素是不是块级元素,如果是,可以直接给父元素设置text-align: center

<style>
    #father {
        width: 500px;
        height: 300px;
        background-color: skyblue;
        text-align: center;
    }
</style>

<div id="father">
    <span>我是行内元素</span>
</div>

如果父元素不是块级元素,则先将父元素设置为块级元素,再给父元素设置text-align: center

<style>
    #father {
        display: block;
        width: 500px;
        height: 300px;
        background-color: skyblue;
        text-align: center;
    }
</style>

<span id="father">
    <span>我是行内元素</span>
</span>

效果:

1.png

块级元素

方案一:

如果需要居中的元素有宽度,就给其设置margin: 0 auto,使盒子自己居中:

<style>
    #father {
        width: 500px;
        height: 300px;
        background-color: skyblue;
    }
    
    #son {
        width: 100px;
        height: 100px;
        background-color: green;
        margin: 0 auto;
    }
</style>

<div id="father">
    <div id="son">我是块级元素</div>
</div>

效果:

2.png

如果需要居中的元素没有设置宽度,那么它会继承父元素的宽度,这时需要给其设置display: inline-blockdisplay: inline将其转换成行内块或行内元素,再给父元素设置text-align: center

<style>
    #father {
        width: 500px;
        height: 300px;
        background-color: skyblue;
        text-align: center;
    }
    
    #son {
        background-color: green;
        display: inline;
    }
</style>

<div id="father">
    <div id="son">我是块级元素</div>
</div>

效果(将子元素转换成行内元素,高度由内容撑起,设置高度无效):

3.png

方案二:

将父元素设置为相对定位,子元素设置为绝对定位,子元素设置left: 50%

如果子元素有宽度:给子元素设置margin-left: -(子元素宽度的一半)px,或者设置transform: translateX(-50%)

<style>
    #father {
        position: relative;
        width: 500px;
        height: 300px;
        background-color: skyblue;
    }
    
    #son {
        position: absolute;
        width: 100px;
        height: 100px;
        background-color: green;
        left: 50%;
        margin-left: -50px;
    }
</style>

<div id="father">
    <div id="son">我是块级元素</div>
</div>

如果子元素没有设置宽度:利用 CSS3 新增属性transform: translateX(-50%)

<style>
    #father {
        position: relative;
        width: 500px;
        height: 300px;
        background-color: skyblue;
    }
    
    #son {
        position: absolute;
        height: 100px;
        background-color: green;
        left: 50%;
        transform: translateX(-50%);
    }
</style>

<div id="father">
    <div id="son">我是块级元素</div>
</div>

效果:

4.png

方案三:

使用 flexbox 布局,不需要考虑定不定宽度,只需要给待处理元素的父元素设置属性display: flex; justify-content: center

<style>
    #father {
        display: flex;
        justify-content: center;
        width: 500px;
        height: 300px;
        background-color: skyblue;
    }
    
    #son {
        position: absolute;
        height: 100px;
        background-color: green;
    }
</style>

<div id="father">
    <div id="son">我是块级元素</div>
</div>

效果:

5.png

垂直居中

单行的行内元素

将父元素的行高设置成和高度一样即可:

<style>
    #father {
        width: 500px;
        height: 300px;
        background-color: skyblue;
        inline-height: 300px;
    }
    
    #son {
        background-color: green;
    }
</style>

<div id="father">
    <span id="son">我是单行的行内元素</span>
</div>

效果:

6.png

多行的行内元素

给父元素设置display: table-cellvertical-align: middle属性即可:

<style>
    #father {
        width: 500px;
        height: 300px;
        background-color: skyblue;
        display: table-cell;
        vertical-align: middle;
    }
    
    #son {
        background-color: green;
    }
</style>

<div id="father">
    <span id="son">我是多行的行内元素我是多行的行内元素我是多行的行内元素我是多行的行内元素我是多行的行内元素我是多行的行内元素我是多行的行内元素我是多行的行内元素我是多行的行内元素</span>
</div>

效果:

7.png

块级元素

方案一:

将父元素设置为相对定位,子元素设置为绝对定位,子元素设置top: 50%

如果子元素设置了高度:给子元素设置margin-top: -(元素高度的一半)px,或者设置transform: translateY(-50%)

<style>
    #father {
        position: relative;
        width: 500px;
        height: 300px;
        background-color: skyblue;
    }
    
    #son {
        position: absolute;
        top: 50%;
        margin-top: -50px;
        height: 100px;
        background-color: green;
    }
</style>

<div id="father">
    <div id="son">我是块级元素</div>
</div>

如果子元素没有设置高度:利用 CSS3 新增属性transform: translateY(-50%)

<style>
    #father {
        position: relative;
        width: 500px;
        height: 300px;
        background-color: skyblue;
    }
    
    #son {
        position: absolute;
        top: 50%;
        transform: translateY(-50%);
        background-color: green;
    }
</style>

<div id="father">
    <div id="son">我是块级元素</div>
</div>

效果:

8.png

方案二:

使用 flexbox 布局,给待处理元素的父元素设置display: flex; align-items: center

<style>
    #father {
        dispaly: flex;
        align-items: center;
        width: 500px;
        height: 300px;
        background-color: skyblue;
    }
    
    #son {
        width: 100px;
        height: 100px;
        background-color: green;
    }
</style>

<div id="father">
    <div id="son">我是块级元素</div>
</div>

效果:

9.png

水平垂直居中

已知高度和宽度的元素

方案一:

给父元素设置相对定位,子元素设置绝对定位,子元素设置top: 0; right: 0; bottom: 0; left: 0; margin: auto;

<style>
    #father {
        position: relative;
        width: 500px;
        height: 300px;
        background-color: skyblue;
    }
    
    #son {
        position: absolute;
        width: 100px;
        height: 100px;
        background-color: green;
        top: 0;
        right: 0;
        bottom: 0;
        left: 0;
        margin: auto;
    }
</style>

<div id="father">
    <div id="son">我是块级元素</div>
</div>

效果:

10.png

方案二: 设置父元素为相对定位,子元素为绝对定位,子元素设置left: 50%; top: 50%; margin-left: -(元素宽度的一半)px; margin-top: -(元素高度的一半)px;

<style>
    #father {
        position: relative;
        width: 500px;
        height: 300px;
        background-color: skyblue;
    }
    
    #son {
        position: absolute;
        width: 100px;
        height: 100px;
        background-color: green;
        left: 50%;
        top: 50%;
        margin-left: -50px;
        margin-top: -50px;
    }
</style>

<div id="father">
    <div id="son">我是块级元素</div>
</div>

效果:

11.png

未知高度和宽度的元素

方案一:

设置父元素为相对定位,子元素为绝对定位,子元素设置left: 50%; top: 50%; transform: translateX(-50%) translateY(-50%);

<style>
    #father {
        position: relative;
        width: 500px;
        height: 300px;
        background-color: skyblue;
    }
    
    #son {
        position: absolute;
        background-color: green;
        left: 50%;
        top: 50%;
        transform: translateX(-50%) translateY(-50%);
    }
</style>

<div id="father">
    <div id="son">我是块级元素</div>
</div>

效果:

12.png

方案二:

设置父元素为 flexbox 布局,并设置justify-content: center; align-items: center;

<style>
    #father {
        display: flex;
        justify-content: center;
        align-items: center;
        width: 500px;
        height: 300px;
        background-color: skyblue;
    }
    
    #son {
        background-color: green;
    }
</style>

<div id="father">
    <div id="son">我是块级元素</div>
</div>

效果:

14.png

最后

推荐优先使用 flexbox 布局

如果文中有错误或者不足之处,欢迎大家在评论区指正。

你的点赞是对我莫大的鼓励!感谢阅读~