让前端飞前端开发

CSS中优雅地实现垂直水平居中

2018-11-15  本文已影响2人  番茄沙司a

前言

在CSS中对元素进行水平居中是非常简单的。

块级元素水平居中:对其自身设置 margin:0 auto
这里上下的外边距随便设置,不一定是0,左右要自适应即可。
行内元素水平居中:对其父元素设置 text-align: center

然而对一个元素进行垂直居中,就令人头皮发麻,原因是:

下面就来探索一下垂直居中的解决方案。

行内元素垂直居中:设置 line-heightheight 一样高。

垂直水平居中的解决方案

结构代码如下所示:

<main>
    <h1>Am I centered yet?</h1>
    <p>Look, I'm centered.</p>
</main>

1. 基于绝对定位的解决方案

利用绝对定位 + margin 反向偏移

早期的垂直居中方法,要求元素具有固定宽和高。

   main {
       position: absolute;
       top: 50%;
       left: 50%;
       margin-top: -3em;/* (height + padding)/2 */
       marigin-left:-9em;/* (width + padding)/2 */
       width: 18em;
       height: 6em;
   }

实现过程:

  1. 把该元素左上角放置在视口的正中心
  2. 将元素的正中心放置在视口的正中心 - 利用负外边距把它向左、向上移动(移动距离相当于它自身宽高的一半)

利用绝对定位 + margin:auto

main {
  position: absolute;
  margin: auto;/*注意不要遗漏margin自适应*/
  bottom: 0;
  top: 0;
  left: 0;
  right: 0;
}

实现原理:利用css定位规则,让css根据定位计算margin值,用 CSS hack 的方式实现居中。

居中块的尺寸需要可控,因为css计算margin时也需要参考尺寸值,由于四周为0,所以自动计算的尺寸是与父容器一样的。无论是设置width、height 或者是 max-height、max-width,都是让尺寸不会扩大到与父级一样。

优化:借助强大的calc()函数

   main {
       position: absolute;
       top: calc(50% - 3em);
       left: calc(50% - 9em);
       width: 18em;
       height: 6em;
   }

局限性:要求显式设置宽高

那么能不能找到一个属性的百分比值以元素自身的宽高作为解析基准。

优化:CSS变形属性

使用场景:主要是针对不定宽高(即宽高为百分比的情况),定宽高的话可以用负的margin值来做到。

这正是我们所需要的,只要换用基于百分比的CSS变形来对元素进行偏移,就可以解除对固定尺寸的依赖。

   main {
       position: absolute;
       top: 50%;
       left: 50%;
       width: 50%; /*注意这里的宽高都为百分比*/
       height: 30%;
       transform: translate(-50%, -50%);
   }

局限性:

2. 基于视口单位的解决方案

CSS3定义了一套新的单位,称为视口相关的长度单位。

例子中,适用于外边距的是vh单位:

main {
    width: 18em;
    padding: 1em 1.5em;
    margin: 50vh auto 0;
    transform: translateY(-50%)
}

3. 基于Flexbox 的解决方案(最佳方案)

body {
    display: flex;
    min-height: 100vh;
    margin: 0;
}

main {
    margin: auto;
}

步骤:

Flexbox还可以将匿名容器(即没有被标签包裹的文本节点)垂直居中

main {
    display: flex;
    justify-content: center;
    align-items: center;
    width: 18em;
    height: 10em;
}

4. 利用table 实现垂直水平居中

例:

<div class="vertical center">
    <div class="box-container">
        <span class="box">miamia</span>
    </div>
</div>

实现:

.vertical {
    width: 100%;
    height: 100%;
    display: table;
}
.vertical.center {
    text-align: center;
}

.vertical .box-container {
    display: table-cell;
    vertical-align: middle;
}

.vertical .box-container .box {
    vertical-align: middle;
}

优点:适用性很强,没有兼容性问题
缺点:会增加冗余的HTML结构。

总结

CSS3已经对垂直水平居中做了很大的改良,根据CSS3的计划,在未来,只需要下面一行代码即可实现:

align-self:center;

这听起来多么令人振奋!

上一篇下一篇

猜你喜欢

热点阅读