前言:今天主要分享一个前端面试题中90%会问到的一个问题——关于如何实现盒子水平垂直居中,在面试时,面试官往往会问,有两个盒子,如何让一个盒子在另一个盒子中水平垂直居中,或者面试官直接在纸上画两个盒子,你跟我说说怎么让里面的盒子水平垂直居中,下面我列出主要的六大解决方案:
<div class="content" id="content">
<div class="main" id="main">我爱白雨童</div>
</div>
.content {
height: 200px;
width: 300px;
background-color: aquamarine;
}
.main {
box-sizing: border-box;
height: 50px;
width: 100px;
background-color: blue;
color: coral;
line-height: 48px;
border: 1px solid red;
font-size: 16px;
text-align: center;
}
.content {
position: relative;
}
.main{
position: absolute;
top: 50%;
left: 50%;
margin-top: -25px;
margin-left: -50px;
}
通过定位,给父级元素(content)添加position:relative属性,给子元素(main)添加position:absolute属性,再通过top和left值的50%实现里面盒子的左上角在外面盒子的中心,所以还需要通过margin值的计算来移动实现整个盒子处于居中,margin-top和margin-left的值均为内部盒子高和宽的一半,就能实现真正的居中;
注意:这种定位方式问题在于必须要知道内部盒子的具体宽和高,因为需要通过计算margin的值来移动相应的位置;
二、实现方式二(定位):
先贴代码:
.content {
position: relative;
}
.main{
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
}
这种定位方式较第一种不同的点主要在于盒子一定要有宽高,但是呢可以不考虑宽高的问题,因为不需要通过计算来移动盒子,将top,left,right,bottom的值都设为0,最后用margin:auto即可实现水平垂直居中;
三、实现方式三(定位):
先贴代码:
.content {
position: relative;
}
.main{
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
}
这种定位方式主要采用CSS3的trabsform:translate(-50%,-50%)属性,X轴和Y轴分别向左和向上移动宽高的一半,这种方式的好处是不需要具体的宽高就能实现。
以上三种均是基于定位实现盒子的水平垂直居中,接下来介绍一种CSS3新出的一种属性来实现——flex
四、flex实现:
先贴代码:
.content{
display:flex;
justify-content: center;
align-items: center;
}
该种方式先定义父级元素display:flex属性,其次设置justify-center:center属性是将内容沿着主轴(X轴)移到中心位置,align-items:center 属性是将内容沿着Y轴移到中心位置,所以父级元素里面的内容均会水平垂直居中显示。该种方式移动端使用的比较多。
五、JavaScript实现:
先贴代码:
<script>
/* 实现方式5 通过JavaScript操作 */
let contentH = content.offsetHeight,//获取外层盒子高度
contentW = content.offsetWidth,//获取外层盒子宽度
mainW = main.offsetWidth, //获取内层盒子宽度
mainH = main.offsetHeight;//获取内层盒子高度
content.style.position="relative"; //设置外层盒子定位
main.style.position = "absolute"; //设置内层盒子定位
main.style.top = (contentH - mainH) / 2 + 'px'; //设置内层盒子相对外层盒子定位的top值——外层高减去内层高再除以2
main.style.left = (contentW - mainW) / 2 + 'px'; //设置内层盒子相对外层盒子定位的left值——外层宽减去内层宽再除以2
</script>
主要通过JavaScript操作实现盒子的水平垂直居中,代码均有注释,应该比较好理解。
六、display:table-cell实现:
先贴代码:
.content{
display:table-cell;
vertical-align:middle;
text-align:center;
}
.main{
display:inline-block;
}
这种方式使用的情况并不多,但是也能够实现水平垂直居中,通过给父级元素添加display:table-cell属性,vertical-align:middle属性为文本垂直到中心,text-align:center属性为水平方向处于中心,但是问题在于该种方式仅仅只能对于文本内容可以实现垂直水平居中,因此我们需要将内层盒子转换为文本,可以通过display:inline-block或者inline即可具有文本特点,这样就能实现。
全部源代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>盒子水平垂直居中之定位</title>
<style>
html,
body {
margin: 0;
padding: 0;
overflow: hidden;
}
.content {
height: 200px;
width: 300px;
background-color: aquamarine;
}
.main {
box-sizing: border-box;
height: 50px;
width: 100px;
background-color: blue;
color: coral;
line-height: 48px;
border: 1px solid red;
font-size: 16px;
text-align: center;
}
/* 定位方式1 */
/* 这种居中的方式问题在于一定要知道盒子具体的宽高,因为要通过宽高计算margin的值 */
/* .content {
position: relative;
} */
/* .main{
position: absolute;
top: 50%;
left: 50%;
margin-top: -25px;
margin-left: -50px;
} */
/* top和left设置为50%是让main盒子的左上角位于content盒子中间 */
/* 往上移动main盒子高度的一半 */
/* 往左移动main盒子宽度的一半 */
/* 定位方式2 */
/* 这种居中方式较第一种可以不考虑宽高,但是需要有宽高,因为不需要用来计算 */
/* .main{
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
} */
/* 定位方式3 */
/* 不需要具体宽高 */
/* .content {
position: relative;
}
.main{
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
} */
/* 实现方式4 以上三种均是基于定位实现,CSS3中可以通过flex实现水平居中 ,移动端使用的比较多*/
/* justify-content: center; 内容沿着主轴X轴移到中心 */
/* align-items: center; 内容沿着Y轴移到中心 */
/* .content{
display:flex;
justify-content: center;
align-items: center;
} */
/* 实现方式5 display:table-cell */
/* 通过给父级元素添加display:table-cell,实际上是对文本居中,可以将文本转化为行内块 */
/* .content{
display: table-cell;
vertical-align: middle;
text-align: center;
}
.main{
display: inline-block;
} */
</style>
</head>
<body>
<div class="content" id="content">
<div class="main" id="main">我爱白雨童</div>
</div>
</body>
<script>
/* 实现方式6 通过JavaScript操作 */
let contentH = content.offsetHeight,
contentW = content.offsetWidth,
mainW = main.offsetWidth,
mainH = main.offsetHeight;
content.style.position="relative";
main.style.position = "absolute";
main.style.top = (contentH - mainH) / 2 + 'px';
main.style.left = (contentW - mainW) / 2 + 'px';
</script>
</html>
最后,当然,在一些情况下肯定还有其他的一些实现方案,但是我今天要分享的就是这六种,每种方式有他需要注意的地方,在何种场景下使用,需要大家斟酌。
最后的最后,分享一个当面试官问到这个问题时可能是一个比较好的回答方式,不过纯属个人建议,我也是在看一些视频播客中学习到的,回答如下:
您好,您问的这个需求也是在我之前的项目中非常常见的,最开始的话我主要通过三种定位方式…还有通过JavaScript操作来实现,后来在学习CSS3的过程中呢,发现flex是非常方便的,尤其是在移动端,实现起来是非常强大的,有段时间我在看掘金的博客中发现display:table-cell这种方式虽然不常用,但是也能实现,所以我就记下来了!
今天的分享到此结束,后面会继续分享一些面试时可能遇到的高频面试题~~