[知识点滴]HTML5元素垂直居中那些事?

来源:互联网 发布:esp8266的单片机教程 编辑:程序博客网 时间:2024/06/06 02:17

一 摘要

让一个元素水平居中对于CSS来说非常简单:如果是一个内联元素,我们可以在他的父元素上设置text-align:center;;如果是一个块元素,我们可以使用margin:auto;。然而,只要一想到让一个元素垂直居中,让人死的心都有了。

多年来,垂直居中已成为CSS的不朽神话,也是前端专业人士群体中的一个内部笑话。原因是:

  1. 经常需要使用
  2. 理论上看上去非常简单
  3. 过去实战中要实现是极其困难,特别是元素大小固定时

下面我们来看一下,垂直居中的几种方案:

1.绝对定位解决方案

2.视窗单位的解决方案

3.Flexbox的解决方案

一一给打家演示一下

示例代码

h1,p{    width:200px;    height:100px;}h1{    background: #f3d91f;}p{    background:#4cf3ed;}<div>    <h1>this is H1 mark!</h1>    <p>Center me, please!</p></div>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

正常没有居中的情况

这里写图片描述

1.绝对定位解决方案

最早实现垂直居中的技术是元素需要一个固定的宽度和高度:

代码

方式一

div{    position: absolute;    top: 50%;    left: 50%;    margin-top: -3em; /* 6/2 = 3 */    margin-left: -9em; /* 18/2 = 9 */    width: 18em;    height: 6em;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

方式二

div{  position: absolute;  top: calc(50% - 3em);  left: calc(50% - 9em);  width: 18em;  height: 6em;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

显然,这种方法最大的问题是,元素需要一个固定的尺寸,而需要垂直居中元素的尺寸常常是需要由它的内容来决定。如果我们有办法使用百分比来控制元素尺寸,我们的问题就解决了。不幸的是,对于大多数CSS属性(包括margin)百分比的值是相对于其父元素的宽度来决定。

方式三

在CSS中常常可以看到很多解决方案是不可思议。在这个例中,就可以使用CSS3的transform。可以在transform中的translate()使用百分比,让元素移动是相对于自身的宽度和高度,这种方案正是我们需要的。

div{    position: absolute;    top: 50%;    left: 50%;    transform: translate(-50%, -50%);}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

这里写图片描述

当然,没有哪门技术是完美的,在实际使用中要注意一下以下几个事项:

  1. 绝对定位通常不是一个很好的选择,因为它对整体的布局影响相当的大。
  2. 如果垂直居中元素的内容比视窗高度更高的话,它的顶部会被裁剪掉,如下图所示。但是这个问题可以解决,只不过需要使用一些Hack手段。
  3. 在一些浏览器中,可能会导致元素出现略微的模糊,那是因为元素有可能被放置在半个像素位置上。我们可以通过transform-style:preserve-3d来解决,尽管这是一个Hack手段,不能保证它不会过时。

2.视窗单位的解决方案

CSS Values and Units Level 3定义了一种新的单位,称为相对视窗(viewport-relative)长度单位。

  1. vw是相对于视窗的宽度。与你预期刚好相反,1vw相当于视窗宽度的1%,而不是100%
  2. 与vw相似的是,1vh相当于视窗高度的1%
  3. 如果视窗的宽度小于高度,1vmin等于1vw,反之,如果视窗宽度大于高度,1vmin等于1vh
  4. 如果视窗的宽度大于高度,1vmax等于1vw,反之,如果视窗宽度小于高度,1vmax等于1vh
  5. 在这个示例中,我们需要给margin的值设置vh单位:

代码

div{    width: 18em;    padding: 1em 1.5em;    margin: 50vh auto 0;    transform: translateY(-50%);}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

这里写图片描述

3. Flexbox的解决方案

这无疑是最好的解决方案,因Flexbox的出现就是为了解决这样的问题。其他解决方案仍然可用,唯一原因是他们能更好的在浏览器上呈现,不过Flexbox在现代浏览器也得到更好的好支持。

只需要两个样式,在需要垂直居中的父元素上设置display:flex(这个示例中就是)和在垂直居中的元素上设置margin:auto

body {    display: flex;    min-height: 100vh;    margin: 0; }div {    margin: auto;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

这里写图片描述
注意,当使用Flexbox和margin:auto时,元素不仅水平居中,而且也会垂直居中。也注意,我们甚至没有设置宽度(如果我们想要也可以设置),其实指定的宽度相当于max-content。

我们可以通过align-items和justify-content属性使设置固定尺寸的

容器里面的文本居中.

div {    display: flex;    align-items: center;    justify-content: center;    width: 18em;    height: 10em;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

同样也可以得到居中的效果

这里写图片描述

0 0
原创粉丝点击