美文网首页
css垂直居中的解决方案

css垂直居中的解决方案

作者: xuehairong | 来源:发表于2019-05-14 16:48 被阅读0次

准备代码:

<!--html-->
<main>
  <h1>Am I centered yet?</h1>
  <p>Center me, please!</p>
</main>
/*css*/
*{
  margin:0
}
main{
  background:#FFF000;
  padding:10px;
  text-align:center;
}

初始效果如图1:


图1

一.绝对定位解决方案

main {
  position: absolute;
  top: 50%;
  left: 50%;
  margin-top: -3em; /* 6/2 = 3 */
  margin-left: -9em; /* 18/2 = 9 */
  width: 18em;
  height: 6em;
}

此解决方案的思路是,距离左上角绝对定位,topleft各50%,然后再负值定位自身的一半的宽度和高度,也可以使用calc()简化代码,效果如图2

main {
  position: absolute;
  top: calc(50% - 3em);
  left: calc(50% - 9em);
  width: 18em;
  height: 6em;
}
图2
很显然,这里最大的问题是需要被定位的元素有固定的大小,然而大部分情况下被垂直居中的元素都是跟随其内容的大小。如果我们有一种方法来使用解析到元素的百分比,我们的问题就会得到解决!但是大多数的CSS属性(包括margin),比例都依赖于他们的父元素。但是当我们把比例用在translate()时,我们移动元素是基于他自身的宽度和高度,这正是我们所需要的,实现效果如图3:
main {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
图3

但此技术有些使用警告:

  • 绝对定位通常不是一个好的选项,因为它对整个布局的影响相当激烈
  • 如果要居中的元素比视口高,就会剪切其顶部(图4)。
  • 在一些浏览器上,会导致元素出现轻微的模糊,因为他们被放在一半像素上(可以通过transform-style: preserve-3d来解决,但不能保证以后会不会被支持)
    图4

二.视口单位(viewport unit)解决方案

假设我们避开使用绝对定位,我们仍然可以使用他translate()讲元素的宽度和高度移动自身一半的技巧,但是我们如何不使用lefttop将元素放到中间呢,我们第一个想到的是用margin属性:

main {
  width: 18em;
  padding: 1em 1.5em;
  margin: 50% auto 0;
  transform: translateY(-50%);
}
图5
然而我们确得到图5的结果,因为margin属性的‘比例’是基于父级的宽度,幸好,让一个元素在视口居中还是可以的,CSS3定义了新的长度单位家族,叫做viewport-relative length:
  • vw基于视口的宽度,与大多数期望的不同,1vw代表视口宽度的1%而不是100%
  • vm相似,1vh代表视口高度的1%
  • 1vmin相对于视口的宽度或高度中较小的那个。
  • 1vmax 相对于视口的宽度或高度中较大的那个。
    所以我们可以将代码修改为:
main {
  width: 18em;
  padding: 1em 1.5em;
  margin: 50vh auto 0;
  transform: translateY(-50%);
}

三.Flexbox 解决方案

这无疑是最好的解决方案,其他解决方案还在使用的唯一原因是因为他们可以更好的支持浏览器,尽管现在的浏览器对Flexbox的支持也非常好了:

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

The End

相关文章

网友评论

      本文标题:css垂直居中的解决方案

      本文链接:https://www.haomeiwen.com/subject/qcisaqtx.html