# CSS 让盒子水平垂直居中的方案
在之前的项目中经常会遇到这样的需求,一般使用的解决方案是 .....
后来,发现了 CSS3 中出现了 xxx
新技术,然后就开始使用这种技术,因为它更加 .....
最后,在逛一些博客的时候又发现了 xxx
等方案,感觉很有意思,于是 .....
# 基础
示例的 HTML 结构:
<body>
<div class="parent">
<div class="child"></div>
</div>
</body>
基础样式以便观察:
body {
padding: 100px;
}
.parent {
width: 100px;
height: 100px;
background-color: darkgray;
}
.child {
width: 50px;
height: 50px;
background-color: aqua;
}
# 知父子宽高
使用外边距:
.parent {
display: flow-root; /* establishes a new block formatting context */
}
.child {
margin: 25px;
}
使用内边距:
.parent {
padding: 25px;
}
两者在水平和垂直方向上任意结合。
也可以使用定位:
.parent {
position: relative;
}
.child {
position: absolute;
top: 25px;
left: 25px;
}
# 知父宽高
表格布局:
.parent {
display: table-cell;
text-align: center;
vertical-align: middle;
}
.child {
display: inline-block;
}
缺陷是父级必须有确定的宽高(相对宽高不生效)。
# 知子宽高
使用定位:
.parent {
position: relative;
}
.child {
position: absolute;
top: 50%;
left: 50%;
margin-top: -25px;
margin-left: -25px;
}
上面使用的是负外边距,其实配合 calc
也可以:
.parent {
position: relative;
}
.child {
position: absolute;
top: calc(50% - 25px);
left: calc(50% - 25px);
}
# 未知宽高
# 定位
.parent {
position: relative;
}
.child {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
margin: auto;
}
虽然它不关心父/子的宽高,但是当子级没有指定宽/高时将会将对应方向的距离拉得和父级一样。
结合 CSS3 中提供的 transform
则可以避免这样的问题:
.parent {
position: relative;
}
.child {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
# 弹性盒子
.parent {
display: flex;
align-items: center;
justify-content: center;
}
# 网格布局
.parent {
display: grid;
align-items: center;
justify-content: center;
}
# JavaScript
当然,可行和通常都不会采用的就是使用 JavaScript 来获取父子的宽高,然后设置相应的样式来达到居中的目的。
// 仅供参考
const parent = $('.parent'),
child = $('.child'),
pw = parent.clientWidth,
ph = parent.clientHeight,
cw = child.clientWidth,
ch = child.clientHeight
parent.style.position = 'relative'
child.style.cssText = `position: absolute; top: ${(ph - ch) / 2}px; left: ${(pw - cw) / 2}px;`
function $(selecter) {
return document.querySelector(selecter)
}
# 附录
文本水平垂直居中:
.child {
line-height: 50px; /* 和高度保持一致 */
text-align: center;
}
多行文本时需要在 child
元素中加上一层结构并指定以下样式:
.grandson {
display: inline-block;
line-height: 1.5;
vertical-align: middle;
}
图片水平居中:
img {
display: block;
margin: 0 auto;
}
块级元素水平居中(需要有宽度,可以是相对宽度):
.child {
margin-right: auto;
margin-left: auto;
}
块级元素垂直居中:
.parent {
display: table-cell;
vertical-align: middle; /* 通常用来使行内元素盒模型与其行内元素容器垂直对齐,如文案和图片之间 */
}
行内块元素水平居中:
.parent {
text-align: center;
}
.child {
display: inline-block; /* inline-flex | inline-grid | inline-table | -webkit-inline-box */
}
数组去重 →