要实现标题全屏居中(同一时候在垂直和水平方向居中)。有若干种方法,包含使用弹性布局、表格单元、绝对定位和自己主动外边距等。
全屏居中
当中眼下比較流行也比較easy理解的方法是使用绝对定位+偏移实现。也就是分两步来把元素居中:
1. 第一步先把元素放在离视口左上角(坐标原点)50%视口宽和50%视口高的地方。
2. 第二步把元素反向偏移其自身宽高的50%。
html,body{background: #333;height:100%; 100%;margin:0;padding:0;} h1 { margin-left: -25%; margin-top: -35px;/* h1元素边框的高度一半 */ color: white; 50%; height: 30px; text-align: center; position: absolute; left: 50%; top: 50%; padding: 20px 0; border: 1px solid #666; }上述代码使用绝对定位,top: 50%, left: 50%完毕第一步,margin-left和margin-top完毕第二步。
注意标题元素宽度使用百分比,可在水平方向自适应屏幕宽度。
最好设置下min-width,以免屏幕过小时,标题文本溢出。
这种代码是能够工作的。
可是吹毛求疵的话,代码的性能并不好。当然在这种简单用例下不太会被暴露出来。
性能优化
可是假设你想给这个标题加入一些动画效果,比方上下晃动的话,那么就非常有必要优化一下代码。
第二步完毕相对自身尺寸的偏移,刚好能够使用CSS3变换中的translate(使用百分比取值时。以其边框border box尺寸为參照)来实现。
我们先给出代码。然后说明为什么要这样,有什么优点和坏处。
*{margin:0;padding:0;} html,body{background: #333;height:100%; 100%;} h1 { -ms-transform: translate3d(-50%, -50%, 0); -webkit-transform: translate3d(-50%, -50%, 0); transform: translate3d(-50%, -50%, 0); color: white; 50%; text-align: center; position: absolute; left: 50%; top: 50%; }
我们首先须要了解浏览器的渲染过程:
- 解析DOM Tree。创建一个或多个渲染层(layer)
- 将每一个层独立地绘制进位图(bitmap)中(计算样式->布局->栅格化)
- 将层作为纹理(texture)上传至 GPU
- 复合(composite)多个层来生成终于的屏幕图像
- 每一个层的样式出现调整后,要又一次计算样式->又一次布局(可能没有)->又一次栅格化(可能没有)->又一次组合
使用top/left仅仅会创建一个层。而使用translate方法将促使浏览器(webkit)把h1元素提取出来放在GPU单独的渲染层中(RenderLayer)。这样有3点益处:
1. 该元素不论什么合成属性(Composite Property)的变化将不会影响原有文档,不会导致原文档被又一次布局(relayout或reflow),所谓又一次布局就是又一次计算位置和尺寸,这是前端性能的杀手。位置和角度就是典型的合成属性。
2. 该层将由GPU(Compositor Thread)负责渲染,从而节省CPU资源,不会堵塞主线程JS代码的运行。
3. 动画更为平滑,这是由于使用translate将能够以小于像素的单位(sub-pixel)来绘制。并在帧之间加入了blur(模糊)效果。
可能带来的负作用是额外的渲染层导致很多其它的线程间通信,假设过度使用,导致生成成百上千的渲染层,那反而会导致组合各层图像的成本迅速上升成为主要矛盾,且我们须要记住GPU也是有内存限制的。当然另一个前提是translate方法得到了浏览器支持。这在移动端没有问题。
另外使用translate的3D版本号和translate 2d版本号的差别在于能够强迫在声明后就创建独立的渲染层。这样一旦动画開始,无需等待。
在线实例
这里有一个在线用例是居中标题区块的完整实现:
http://wow.techbrood.com/fiddle/6908
还有两个在线用例用来比較top/left和translate方法的性能(你须要学会使用Chrome DevTools):
http://wow.techbrood.com/fiddle/17737
http://wow.techbrood.com/fiddle/17739