让元素居中是每个前端都会经历的一个问题,而解决该问题的方法也各不相同,各有长短,今天总结下所知晓的方法,并分析利弊。
基础代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>订阅发布</title>
<style>
.bigBox {
width: 500px;
height: 500px;
background-color: aqua;
}
.smallBox {
width: 100px;
height: 100px;
background-color: antiquewhite;
}
</style>
</head>
<body>
<div class="bigBox">
<div class="smallBox"></div>
</div>
<script>
</script>
</body>
</html>
基础效果:
1.定位法
1.1 margin回移法
<style>
.bigBox {
position: relative;
width: 500px;
height: 500px;
background-color: aqua;
}
.smallBox {
position: absolute;
left: 50%;
top: 50%;
margin-top: -50px;
margin-left: -50px;
width: 100px;
height: 100px;
background-color: antiquewhite;
}
</style>
原理: 使用简单的父相子绝定位法,利用left和top控制子元素的左上角垂直水平居中。然后使用margin-top和margin-left进行盒子位置的回移。
效果展示:
缺陷: 上面的方法完美实现了小盒子在大盒子中间垂直水平居中,但是有一个缺陷是必须提前知道小盒子的宽高,如果不知晓则无法精准居中。而真实项目里元素样式很多时候数据源来自后台请求,所以拿不到元素的具体宽高。
1.2 定位取值为0法
根据上文方法的缺陷进行调整优化,得出一下代码:
<style>
.bigBox {
position: relative;
width: 500px;
height: 500px;
background-color: aqua;
}
.smallBox {
margin: auto;
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
width: 100px;
height: 100px;
background-color: antiquewhite;
}
</style>
原理: 让小盒子四个方向的定位都为0,此时小盒子还位于原位,使用margin: auto让他上和下,左和右的外边距保持一致。由于小盒子四个方向的定位值都为0,所以会自动将小盒子拉到正中间,不会是右上角在正中间。
缺陷: 上面的方法虽然可以不知道小盒子的宽高就进行居中显示,但是小盒子宽高必须存在。如果不设置宽高,会自动铺满全屏(绝对定位后,四个方位值为0的效果,不设置宽,则宽铺满,不设置高则高铺满,都不设置则宽高铺满)。
1.3 transform: translate(-50%, -50%)
css3的transform属性的推出,终于让定位居中这种方式有了最优解。
<style>
.bigBox {
position: relative;
width: 500px;
height: 500px;
background-color: aqua;
}
.smallBox {
position: absolute;
left: 50%;
top: 50%;
width: 100px;
height: 100px;
background-color: antiquewhite;
transform: translate(-50%, -50%);
}
</style>
原理: 跟第一种定位方法一样,先将左上角定位到大盒子中间位置。然后使用transform属性里面的translate方法,该方法表示平移自身元素的多少位置。translateX为平移横坐标,translateY平移纵坐标,translate则平移横纵坐标。参数一为横坐标,参数二为纵坐标。使用-50%表示向左向上平移自身一半位置,达到居中效果。
缺陷: 因为使用了css3,所以有一点兼容问题,但是定位方案内还是最推荐此方法。
2.flex流动布局法
<style>
.bigBox {
display: flex;
justify-content: center;
align-items: center;
width: 500px;
height: 500px;
background-color: aqua;
}
.smallBox {
width: 100px;
height: 100px;
background-color: antiquewhite;
}
</style>
原理: flex的流动布局也是非常推荐的一种解决布局的方法,直接设置为flex流动布局,然后让大盒子内的元素位于x轴,y轴居中即可。
缺陷: 好的东西总有相同的问题存在,那就是兼容问题(其实现在依旧可以不考虑兼容问题了)
3.table-cell布局法
最不常用的方法。
<style>
.bigBox {
display: table-cell;
width: 500px;
height: 500px;
text-align: center;
vertical-align: middle;
background-color: aqua;
}
.smallBox {
display: inline-block;
width: 100px;
height: 100px;
background-color: antiquewhite;
}
</style>
**原理:**该方法是对文本使用的居中方法。将父元素display设置为table-cell后,就可以对内部文本元素进行居中显示,text-align: center实现文本水平居中,vertical-align: middle实现文本垂直居中。然后将子元素设置为行内元素或者行内块级元素即可。
为了达到居中目的而将元素设置为行内元素是不可取的,会丧失块级元素的特性,得不偿失。并且大盒子的宽高必须设置为具体值,不能设置为百分比或空缺。
4.grid
<style>
.bigBox {
display: grid;
place-items: center;
width: 500px;
height: 500px;
background-color: aquamarine;
}
.smallBox {
width: 100px;
height: 100px;
background-color: red;
}
</style>
5.js布局法
万能的js当然也可以将元素进行居中布局。原理很简单,这里就只粘贴代码了。
let bigBox = document.querySelector('.bigBox')
let smallBox = document.querySelector('.smallBox')
let bigWidth = bigBox.clientWidth
let smallWidth = smallBox.clientWidth
let bigHeight = bigBox.clientHeight
let smallHeight = smallBox.clientHeight
smallBox.style.position = 'relative'
smallBox.style.left = (bigWidth-smallWidth)/2 + 'px'
smallBox.style.top = (bigHeight-smallHeight)/2 + 'px'
目前本人掌握的布局大概就这几种,若有不足或错误,欢迎补充和纠正。