老生常谈的水平垂直居中的几种方案

599 阅读5分钟

如何让一个盒子水平垂直居中,我想大家都有自己的办法了,但是我还是想系统化的收集、比较和总结一下,以方便自己的学习,那让我们来交流讨论一下吧,如果错了的地方,欢迎大家指点,如果大家还有其他没有提到的方法欢迎在评论区教下我,谢谢!

首先,我们先弄一个父盒子和一个子盒子,然后给他们一宽度,高度,背景颜色来区分他们,like this:
<body>
    <div class="father">
      <div class="children"></div>
    </div>
</body>
<style>
    .father{
       width: 1000;
       height: 500;
       background-color: aquamarine;
      
    }
    .children{
       width: 100px;
       height: 200px;
       background-color: black;

    }
</style>
在页面中的效果like this:

60$_YC9Z{{@VCX_PD)JLQ.png

那现在我们的目的就是让这个黑div在这个蓝绿(我也不知道这是啥颜色)div里面水平垂直居中!
so,let's get it!

第一种方案:定位然后给子div left,top属性

我们给father加上一个position:relative(相对定位),然后给children加个一个position: absolute(绝对定位),简称父相子绝,这样我们通过调整children相对于father的位置即可做到水平垂直居中,代码如下:
<body>
    <div class="father">
      <div class="children"></div>
    </div>
</body>
<style>
    .father{
       height: 500px;
       width: 1000px;
       background-color: aquamarine;
       
       position: relative;
    }
    .children{
       width: 100px;
       height: 200px;
       background-color: black;

       position: absolute; 
       top: 50%;
       left:50%;
    }
</style>

但是有个地方要注意一下,就是当给children加上top: 50%;left:50%;之后他的居中是相对于children左上角那个点的居中,但是不是children整体的居中,示意图如下:

W1NX1U%(4II[E)6P7DHH4.png

所以我们还需要做一下小调整,也就是把整个盒子往左上移动一点,具体就是往左边移动半个宽度,往上面移动半个高度!(这里是没有边框的情况,有边框的还要考虑边框的宽度)

那我们怎么移动呢?这里就有几种方法了

第一种:用margin-top和margin-top取赋值即可!也就是在children里面加个margin-top: -100px;margin-left: -50px;(高度的一半和宽度的一半!)

第二种:既然是移动,那么我们为啥不能用css3里面transform:translate()呢?所以我们就在children里面加个transform:translate(-50%,-50%);向左和向上都是负的,这个50%是相对于children的50%。

虽然这两种移动都能成功,但是如果仔细取对比一下,可以发现区别很大,区别如下:

1.margin-top和margin-left需要填盒子具体的负宽高/2,如果盒子的宽高变化的话,显然这个margin-top和margin-left里面的数字也要重新计算然后改变,就失去了灵活性!相比之下,transform:translate(-50%,-50%)是相对于children宽高百分比,是随着children宽高的变化而变化的,这样就不需要再去管chidren的宽高了!

2.transform:translate(-50%,-50%)当盒子宽高没有时还是可以是的垂直水平居中生效!此时宽高就是div内部东西所占的宽高,如下图:

transform:translate(-50%,-50%);children有宽高:

3L(Q3)J(E780O}9JS3FZ3PX.png

transform:translate(-50%,-50%);children不设置宽高:

PNHL8YZ6~}9`Z%LWF184N.png

margin-top:-100px; margin-left: -50px children;不设置宽高( 明显歪了,因为不设置宽高之后,childre就是文字的宽高,但是margin-top:-100px; margin-left: -50px;显然不适配此时的宽高):

U`_CH(25Q%6Z10}DWNJE8H0.png

3.以上是定位后移动的两种方案,还有一种是定位之后用margin来定位,我们称他为第三种:同样还是先父相子绝定位,但是children里面直接用margin:auto来实现水平垂直居中,但是注意这里children里面要要top,left,right,bottom都为0(原因我也不清楚,自己的理解就是应该先把位置对应关系清掉再用margin来实现居中)children代码如下:

.children{
       width: 100px;
       height: 200px;
       background-color: black;
       color: aliceblue;

       position: absolute; 
       top: 0;
       left:0;
       right: 0;
       bottom: 0;
       margin: auto;
    }

这种方法的优先就是也不要计算宽高了,直接用margin:auto就搞定,缺点就是:虽然不用管chidren宽高,但是children一定要有宽高!!!!,chidren没有宽高就会变成这样(直接占满father):

HXU9{I8)FUC7}B5BFBGQ{L9.png

这就是使用定位方案实现水平垂直居中的三种办法,总的来说定位之后left:50%;top:50%之后再transform:translate(-50%,-50%)是最不需要宽高的,但是有可能带来不兼容的问题

第二种方案:display

4.现在我们来讲第四种方法了,它是基于display:flex(弹性伸缩盒模型)的方法,相对来说,代码就会少很多了。当给father一个display:flex(display 属性可以设置元素的内部和外部显示类型,flex是元素的内部显示类型,可以控制其子元素的布局)时,然后用justify-content来控制左右(水平)的布局,用align-items来控制上下(垂直)的布局即可。所以只要在father里面写下如下代码即可:

.father{
       height: 500px;
       width: 1000px;
       background-color: aquamarine;
       
       display: flex;
       justify-content: center;
       align-items: center;
    }

5.第五种是也是用display,但是使用另外一个属性display: table-cell;这相当于是对于行内元素的居中,所以children中需要加上display: inline-block属性;然后father中用vertical-align: middle;text-align: center;对children进行居中,代码如下:

<style>
    .father{
       height: 500px;
       width: 1000px;
       background-color: aquamarine;
       
       display: table-cell;
       /* //行内元素的水平垂直对齐 */
       vertical-align: middle;
       text-align: center;
    }
    .children{
       display: inline-block;

       width: 100px;
       height: 200px;
       background-color: black;
       color: aliceblue;
    }
</style>

这种方法不仅仅children水平垂直居中了,连children里面的文字都跟着左右居中了!如图:

}E9LRX@2~L(U(53H37JRABR.png

第三种方案:js

6.第六种方法是用js获取father div的宽高w1,h1、children div的宽高w2,h2,然后定位之后用top:(h1-h2)/2;left:(w1-w2)/2;代码如下:

<body>
    <div class="father" id="father">
      <div class="children" id="children">zjrzjrzjrzjr</div>
    </div>
</body>
<style>
    .father{
       height: 500px;
       width: 1000px;
       background-color: aquamarine;
       position: relative;
    }
    .children{
       width: 100px;
       height: 200px;
       background-color: black;
       color: aliceblue;
       position:absolute;
    }
</style>
<script>
    let father = document.getElementById('father');
    let children = document.getElementById('children');
    children.style.left=(father.offsetWidth-children.offsetWidth)/2+'px';
    children.style.top=(father.offsetHeight-children.offsetHeight)/2+'px';
</script>

写在最后:好累,写了好久,如果看了你对有一点点帮助的话点个赞再走吧哈哈哈!