CSS 居中
居中一般分为水平居中、垂直居中、文字居中
对于CSS,如果实现一个元素水平居中,还是比较容易实现的:
- 行内元素:在父元素上设置text-align:center;
- 块级元素:margin:auto。
但是,要实现元素垂直居中,还是比较困难的,尤其是元素大小固定时。
不讨论的方法:
- 表格布局,因为需要一些冗余的HTML标签
- inline-block,需要使用很多的hack
下面的示例用的HTML结构都是<body>元素中插入下面的标签:
1 <div> 2 <h1>居中了么?</h1> 3 <p>请居中!</p> 4 </div>
1 绝对定位解决方法
1.1 最早实现垂直居中的技术是元素需要一个固定的宽度和高度:
1 div{ 2 position:absolute; 3 top:50%; 4 left:50%; 5 margin-top:-3em; 6 margin-left:-9em; 7 width:18em; 8 height:6em; 9 }
从本质上讲,将元素的左上角移到视窗中心点,然后使用负margin(使用margin-left和margin-top),而margin的值是元素宽度和高度的一半,使元素中心点与视窗的中心点重合。
1.2 如果使用calc()可以减少两个样式:
1 div{ 2 position:absolute; 3 top : calc(50% - 3em); 4 left : calc(50% - 9em); 5 width: 18em; 6 height: 6em; 7 }
显然,这种方法的最大问题,是元素需要一个固定的尺寸,而需要垂直居中元素的尺寸常常需要由它的内容来决定。如果有办法使用百分比来控制元素的尺寸,我们的问题就可以解决了。不幸的是,大多数CSS属性(包括margin)百分比的值是对于其父元素的宽度来决定的。
1.3 transform
在CSS中常常可以看到很多解决方案是不可思议的。在这个例子中,可以使用CSS3的transform。可以在transform中的translate()使用百分比,让元素元素移动是相对自身的宽度和高度,这种方案正式我们需要的。
1 div{ 2 position:absolute; 3 top:50%; 4 left:50%;
-webkit-transform:translate(-50%,-50%);
-moz-transform:translate(-50%,-50%);
5 transform:translate(-50%, -50%); 6 }
使用绝对定位通常不是一个很好地选择,因为它对整体的布局影响相当大。
如果垂直居中元素的内容比视窗宽度更高的话,它的顶部会被裁剪掉,如下图所示。但这个问题可以解决掉,只不过需要使用一些hack手段。
在一些浏览器中,可能会导致元素出现略微的模糊,那是因为元素可能被放置在半个元素位置上。我们可以通过transform-style:preserve-3d来解决,尽管这是一个hack手段,不能保证它不会过时。
2 视窗单位
如果想避免使用绝对定位,仍然可以使用translate()方法,其值刚好是原宽度和高度的一半。然而,我们如何不使用top和left,将元素从top和left移动50%的偏移量呢?
2.1 margin属性一个百分号
首先给margin属性一个百分数,像这样:
1 div{ 2 width:18em; 3 padding:1em 1.5em; 4 margin:50% auto 0; 5 transform:translateY(-50%); 6 }
但这种会产生奇怪的效果,并没有真正的垂直居中,主要原因margin的百分比计算是相对于父容器的width来计算的。
如果想让元素在视窗中居中,还是可以的。
CSS Values and Units Level 3定义了一种新的单位,称为相对视窗(Viewport-relative)长度单位。
- vw是相对视窗的宽度。1vw相当于视窗宽度的1%,而不是100%;
- 如果视窗的宽度小于高度,1vmin等于1vm,反之,如果视窗宽度大于高度,1vmin等于1vh;
- 如果视窗宽度大于高度,1vmax等于1vw,反之,如果视窗宽度小于高度,1vmax等于1vh.
1 div{ 2 width:18em; 3 padding:1em 1.5em; 4 margin:50vh auto 0; 5 transform:translateY(-50%); 6 }
可以实现很好的垂直居中效果。
这种方法只适合元素在视窗中垂直居中。
3 flexbox
这种解决方案无疑是最好的,因为它在现代浏览器中可以得到很好地支持。
3.1 flex
只需要两个样式,在需要垂直居中的父元素上设置display:flex;
这个示例<body>和垂直居中元素上设置margin:auto
body {
display: flex;
min-height: 100vh;
margin: 0;
}
div {
margin: auto;
}
元素不仅实现水平居中,而且还会垂直居中,没有设置宽度。
flexbox还有一个优点,可以让匿名容器垂直居中。
3.2 align-items和justify-content
可以通过align-items和justify-content属性设置固定的尺寸的div容器里面的文本
可以在<body>和需要的居中的元素div使用相同的属性,同时使用margin:auto作为备用,易于优雅降级。
div {
display:flex;
align-items:center;
justify-content:center;
width:18em;
height:10em;
}
4 IE兼容问题
一般情况下,需要将div居中显示,使CSS样式margin:0 auto;或margin:0 auto 1px;,但有时使用margin:0 auto;能够在ff和chrome中正常居中显示,但对于IE6之前浏览器则不能实现水平居中
margin:0 auto
上面的margin:0 auto不能实现水平居中,怎么解决呢?
解决IE的兼容的bug,搜索了下,有两种解决方法
1、通过在body或父级元素设置text-align:center来实现居中
2、和方法一差不多,在居中的外层加一个div,并使其居中即可。
3、出现这个原因,主要在于文档的dtd声明问题,DOCTYPE为 xhtml 1.0 tranditional (html 4.01 下无效)。
修改DTD为下<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
另外还可以使用<center></center>这个是HTML5
1、不能使用float(无论是使用float:left还是float:right);
2、对body设置text-align:center;
3、对最外层设置margin:0 auto;兼容各大浏览器水平居中样式