一、父子元素高度确定
简单粗暴, 直接通过设置合适的
padding
或margin
实现居中
<style>
.p {
padding: 20px 0;
background: rgba(255, 0, 0, 0.1);
}
.c {
width: 40px;
height: 20px;
background: blue;
}
</style>
<div class="p">
<div class="c"></div>
</div>
二、Flex(弹性) 布局
<style>
.p {
height: 100px;
background: rgba(255, 0, 0, 0.1);
display: flex;
align-items: center; /* 垂直居中 */
justify-content: center; /* 水平居中 */
}
.c {
width: 40px;
height: 20px;
background: blue;
}
</style>
<div class="p">
<div class="c"></div>
</div>
三、Grid(网格) 布局
<style>
.p {
height: 100px;
background: rgba(255, 0, 0, 0.1);
display: grid;
place-items: center; /* 直接水平垂直居中 */
}
.c {
width: 40px;
height: 20px;
background: blue;
}
</style>
<div class="p">
<div class="c"></div>
</div>
四、子元素通过「绝对定位 + 偏移」实现居中
4.1 子元素高度不固定, 使用 transform
进行偏移
依据: 绝对定位百分比, 是相对于
父元素
进行计算、transform
百分比, 则是相对于自身
进行计算
<style>
.p {
height: 100px;
background: rgba(255, 0, 0, 0.1);
position: relative;
}
.c {
width: 40px;
background: blue;
top: 50%;
position: absolute;
transform: translateY(-50%);
}
</style>
<div class="p">
<div class="c">
1111<br>2222
</div>
</div>
4.2 子元素高度固定, 直接使用 margin
进行偏移
依据: 绝对定位百分比, 是相对于
父元素
进行计算
<style>
.p {
height: 100px;
background: rgba(255, 0, 0, 0.1);
position: relative;
}
.c {
width: 40px;
height: 40px;
background: blue;
position: absolute;
top: 50%; /* 该百分比, 相对于父元素高度进行计算 */
margin-top: -20px; /* 手动计算, 等于高度的一半 */
}
</style>
<div class="p">
<div class="c"></div>
</div>
4.3 「补充」margin
、padding
百分比计算方式
margin
、padding
上下两个方向的百分比, 相对于父元素自适应
的一边进行计算, 默认情况下是根据父元素宽度
进行计算的 (因为块元素默认宽度自适应
), 之所以要相对于自适应一边进行计算, 是为了避免在未设置宽高情况下, 子元素设置了边距, 引起容器尺寸的变化, 从而造成百分比重新计算, 引起死循环
<style>
.p {
width: 200px;
height: 400px;
background: rgba(255, 0, 0, 0.1);
}
.c {
margin: 10%; /* 上下左右边距都, 相对于父元素宽度: 20px */
padding: 10%; /* 上下左右边距都, 相对于父元素宽度: 20px */
display: inline-block;
background: blue;
}
</style>
<div class="p">
<div class="c">
</div>
</div>
通过
writing-mode: vertical-lr
可元素内容 (文字、子元素) 从上到下垂直流动, 元素将从宽度自适应
改为高度自适应
, 这时其子元素paddin
margin
百分比将相对于父元素的高度
进行计算
<style>
.p {
writing-mode: vertical-lr; /* 元素内容从上到下垂直流动、高度将自适应*/
width: 200px;
height: 400px;
background: rgba(255, 0, 0, 0.1);
}
.c {
margin: 10%; /* 上下左右边距都, 相对于父元素宽度: 40px */
padding: 10%; /* 上下左右边距都, 相对于父元素宽度: 40px */
display: inline-block;
background: blue;
}
</style>
<div class="p">
<div class="c">
</div>
</div>
五、自适应特性 + margin: auto
众所周知
margin: auto
, 可以很容器实现元素的水平居中, 而之所以能够实现水平居中, 是因为父元素宽度自适应
, 只有在自适应情况下margin: auto
才能正确计算出合适的值
<style>
.p {
width: 200px;
height: 200px;
background: rgba(255, 0, 0, 0.1);
}
.c {
width: 40px;
height: 40px;
background: blue;
margin: auto;
}
</style>
<div class="p">
<div class="c">
</div>
</div>
从上面例子可以看出,
margin: auto
之所以能实现水平居中, 就是因为父元素宽度自适应
了, 那么很自然就可以想到, 如果可以使父元素高度自适应
, 那么我们就可以借用margin: auto
实现元素的垂直居中
5.1 通过 writing-mode
使元素高度自适应
writing-mode
属性定义了元素内容(文本、子元素)水平或垂直的排列方式, 其中vertical-lr
属性值可使内容由水平流动
改为垂直流动
, 同时元素的宽度自适应
也将变为高度自适应
<style>
.p {
width: 200px;
height: 200px;
background: rgba(255, 0, 0, 0.1);
writing-mode: vertical-lr; /* 将子元素流向从水平改为垂直, 同时宽度自适应也将变为高度自适应 */
}
.c {
width: 40px;
height: 40px;
background: blue;
margin: auto;
}
</style>
<div class="p">
<div class="c">
</div>
</div>
5.2 为子元素设置绝对定位, 使得在对应方向上具有自适应特性
<style>
.p {
width: 200px;
height: 200px;
background: rgba(255, 0, 0, 0.1);
position: relative;
}
.c {
width: 40px; /* 需要设置宽度 */
height: 40px; /* 需要设置高度 */
background: blue;
top: 0;
left: 0;
right: 0;
bottom: 0;
position: absolute;
margin: auto;
}
</style>
<div class="p">
<div class="c">
</div>
</div>
六、子元素为文本或内联元素(包括内联块元素)
6.1 line-height
一把梭哈
对于父元素
高度确定
, 且子元素是单行文本
或者内联元素
, 可直接通过line-height
实现居中
<style>
.p {
line-height: 80px;
background: rgba(255, 0, 0, 0.1);
}
.inline-block {
display: inline-block;
height: 20px;
width: 40px;
background: blue;
}
</style>
<div class="p">
11111111111111111111
</div>
<br/>
<div class="p">
<div class="inline-block"></div>
</div>
6.2 伪元素(::after
) + vertical-align
通过伪类创建一个
隐藏的内联元素
, 高度为父元素高度, 并借用vertical-align
使所有内容垂直居中
<style>
.p {
width: 200px;
height: 200px;
background: rgba(255, 0, 0, 0.1);
}
.p::after {
content: '';
height: 100%;
display: inline-block;
vertical-align: middle;
}
.c {
width: 40px; /* 需要设置宽度 */
height: 40px; /* 需要设置高度 */
background: blue;
display: inline-block;
}
</style>
<div class="p">
<div class="c">
</div>
</div>
<br>
<div class="p">
111111111111111111111
</div>
6.3 display: table-cell
+ vertical-align
<style>
.p {
width: 200px;
height: 200px;
background: rgba(255, 0, 0, 0.1);
display: table-cell;
vertical-align: middle;
}
.c {
width: 40px; /* 需要设置宽度 */
height: 40px; /* 需要设置高度 */
background: blue;
}
</style>
<div class="p">
<div class="c">
</div>
</div>
<br>
<div class="p">
111111111111111111111
</div>