CSS垂直水平居中

1,513 阅读2分钟

toast组件

1.需求: 宽高不定,上下左右垂直居中

// html
<div class="toast">提交成功</div>

//css
.toast {
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(50%, 50%);
    padding: 13px 16px;
    font-size: 14px;
    color: #ccc;
    background: rgba(37, 38, 45, 0.9);
    border-radius: 2px;
}

2.需求:Toast组件一行最多能有12个中文字符,超过的时候折行

//新增代码
    <div class="toast">测试十二个字提交成功状态</div>

.toast {
    width: auto;
    max-width: 12em;
}

效果如下:

可以看到,第九个字的时候便会折行了。这是因为设置为position:fiexd元素不仅位置相对于屏幕边界定位,如果不指定元素宽高的话,宽高同样也会相对于屏幕边界被截断。

解决方案

// html
<div class="toast-container">
    <div class="toast"></div>
</div>

// css
.toast-container {
    position: fixed;
    top: 100%;          // core
    left: 100%;         // core
    width: 100%;
    height: 100%;
}
.toast {
    position: absolute;
    top: -50%;
    left: -50%;
    transform: tranlate(-50%, -50%);
    width: auto;
    max-width: 12em;
    padding: 13px 16px;
    font-size: 14px;
    color: #ccc;
    background: rgba(37, 38, 45, 0.9);
    border-radius: 2px;
}

在toast外加一个和屏幕宽高相同的.container容器,将.container容器fixed定位到窗口外层,在讲.toast通过absolute定位翻转过来

基于vertical-align属性的水平垂直居中弹框

// html
<div class="container">
    <div class="dialog"></div>
</div>

// css
.container {
    postition: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    text-align: center;
    font-size: 0;
    white-space: nowrap;
    overflow: auto;
}
.container:after {
    content: '';
    display: inline-block;
    height: 100%;
    vertical-align: middle;
}
.dialog {
    display: inline-block;
    vertical-align: middle;
    text-align: left;
    font-size: 14px;
    white-space: normal;
}

核心原理如下:

  1. 由于font-size:0,所以x中心点的位置就是.container的上边缘,此时高度100%的宽度为0的伪元素和这个中心店对齐。如果中心点位置不动,这个伪元素上面一半的位置应该在.container外面,但是CSS中默认是左上方排列对齐的,所以伪元素和这个原本在容器上边缘的x中心点一起往下移动了半个容器宽度,也就是此时x中心点就在容器的垂直中心线上。
  2. 弹框元素.dialog也设置了vertical-align: middle。根据定义,弹框的垂直中心位置和x中心点位置对齐,此时,x中心点就在容器的垂直中心位置,于是.dialog元素就是和容器的垂直中心位置对齐了,从而实现垂直居中效果
  3. 水平居中就text-align: center实现

参考地址: 再谈自适应垂直居中