IE9及其以下版本完全不支持CSS 3D transforms技术,Opera 12也不支持。具体支持信息请查看caniuse.com。
CSS动画是当前一种非常火爆的技术,我说的并不是一些简单的颜色变换或长短属性变换,我说的是3D变换技术;纯CSS实现的翻滚旋转立方体就是最典型的例子。网上能找到很多关于CSS动画的代码,但对于一个程序员来说,真正理解其为什么会动起来的原理是非常重要的。下面让我来一步一步的带你理解网页中相互嵌套的3D动画是如何实现的!
假设我们在一个门框内有一扇门:
![](http://bbs.html5cn.org/data/attachment/forum/201411/26/141044zkdzdp5gpr77vjkn.jpg)
HTML代码非常简单:
复制代码
为了打开这扇门,我们给它添加一个door--opencss类:
复制代码
现在,我们对它使用3D变换技术(通过对它的左侧应用transform-origin)属性:
复制代码
对于使用CSS 3D变换,你唯一需要添加的CSS前缀可能只有-webkit-。IE9是完全不支持的,但IE10+是不需要使用前缀的。Opera 12及其之前版本完全不支持CSS变换技术,之后的版本在使用-webkit-前缀后是支持的。火狐浏览器从V16版(2012年)起不需要使用前缀。
效果:
![](http://bbs.html5cn.org/data/attachment/forum/201411/26/141205l23f4v8kdr3vvojs.jpg)
现在的效果看起来并不是很真实。更真实实现这种效果的CSS属性叫做perspective(透视),它会让东西看起来近处的大,远处的小。
perspective属性必须应用到需要做3D变换的元素的父元素上。在WebKit浏览器里,只要是它的祖先元素都行,但在火狐或IE里只能是父元素。
现在我们要往门框元素上添加一个frame--realistic类:
复制代码
现在我们在其上设置perspective透视属性。透视属性的值约小,它就会显得离你的眼睛越近,这样,越近的东西会显得越大,越远的越小。
复制代码
我们就得到了下面的效果:
![](http://bbs.html5cn.org/data/attachment/forum/201411/26/141310cdmlfmn0qfg672d3.jpg)
这样看起来就好多了!但我们可以做得更好!比如,我们可以让这扇门动起来,并且具有3D效果。我们只需要在HTML和CSS里将door-open类换成door--ani类:
复制代码
效果:
------![](http://bbs.html5cn.org/data/attachment/forum/201411/26/142000l4tuxvklffuziivv.jpg)
现在,我们还想让这扇门的门框也以3D的形式动起来。这很简单,不是吗?只需要在门框上添加一个frame--ani类,设定一个动画动作,将perspective透视属性移动到它的父元素上:
HTML代码变成了这样:
复制代码
我们还需要添加下面的CSS代码:
复制代码
可是,我们得到的效果却是:
-----![](http://bbs.html5cn.org/data/attachment/forum/201411/26/142108ee6soilparaoeedo.jpg)
看起来有些怪。看起来门的动画效果被门框的摆动抵消了。的确,事情就是这样,因为transform-style属性(用来告诉浏览器一个具有3D变换属性的子元素是否附随父元素的3D变换属性)的缺省值是flat。
这个问题可以通过将其父元素设置transform-style: preserve-3d来纠正。这样,我们就可以看到更自然的效果了:
![](http://bbs.html5cn.org/data/attachment/forum/201411/26/14223743kqrs1yqw4k1szd.jpg)
![](http://bbs.html5cn.org/data/attachment/forum/201411/26/1422371ayf6s0yswe1u1sl.jpg)
但是,IE10/11只支持transform-style的flat值。有时我们会利用这种技术将父元素和子元素通过3D变换串联起来。
例如,我有一个稍微倾斜的立方体(没有顶部和底部面)。HTML代码是:
复制代码
相关的CSS:
复制代码
使用这些代码(这里有更详细的解释),我们得到了下面的效果:
如果你使用的是IE,我们需要在对每个面实施3D变换前先清空变换属性(如果这个立方体的父类也有变换特征,也需要先清空。)。我将立方体的父元素也处理了,就像下面:
复制代码
于是,在IE里也得到了同样的效果:
虽然不是很方便,但也不是很糟。代码不是很多,也不是很乱…然而,当我们想旋转这个立方体时却出现了问题。我们需要使用transform-style: preserve-3d属性,我们简单的增加了一个cube--ani类,这段CSS代码是:
复制代码
![](http://bbs.html5cn.org/data/attachment/forum/201411/26/142557g39wl4drwl4ldwrd.jpg)
可是,对于IE10/11来说,我们无法对立方体自身施加3D变换,我们只能对每个面单独实施3D变换。这就是说,我们要对所有的面设置变换属性。这就是说….每个面都要!
复制代码
这一**,就是为了实现这个效果:
![](http://bbs.html5cn.org/data/attachment/forum/201411/26/1427066zvv66ojohhpnz9j.jpg)
如果这么多的代码只是为了这4个面,那当需要面对100多个面时,你能想象是多恐怖的一堆代码吗?
你也许会想到上面的门也有这种问题,门的父元素有高度和宽度,是可见。如何在IE里实现?唯一能让门和门框在IE里一起动起来的方案就是修改HTML代码,让门和门框变成兄弟元素,单独对它们施加动画效果。
(英文:How Nesting 3D Transformed Elements Works.)
via:http://www.webhek.com/3d-transforms
CSS动画是当前一种非常火爆的技术,我说的并不是一些简单的颜色变换或长短属性变换,我说的是3D变换技术;纯CSS实现的翻滚旋转立方体就是最典型的例子。网上能找到很多关于CSS动画的代码,但对于一个程序员来说,真正理解其为什么会动起来的原理是非常重要的。下面让我来一步一步的带你理解网页中相互嵌套的3D动画是如何实现的!
假设我们在一个门框内有一扇门:
![](http://bbs.html5cn.org/data/attachment/forum/201411/26/141044zkdzdp5gpr77vjkn.jpg)
HTML代码非常简单:
- <div class='container'>
- <div class='frame'>
- <div class='door'></div>
- </div>
- </div>
为了打开这扇门,我们给它添加一个door--opencss类:
- <div class='container'>
- <div class='frame'>
- <div class='door door--open'></div>
- </div>
- </div>
现在,我们对它使用3D变换技术(通过对它的左侧应用transform-origin)属性:
- .door--open {
- transform-origin: 0 0 /*whatever y value you wish*/;
- transform: rotateY(-45deg);
- }
对于使用CSS 3D变换,你唯一需要添加的CSS前缀可能只有-webkit-。IE9是完全不支持的,但IE10+是不需要使用前缀的。Opera 12及其之前版本完全不支持CSS变换技术,之后的版本在使用-webkit-前缀后是支持的。火狐浏览器从V16版(2012年)起不需要使用前缀。
效果:
![](http://bbs.html5cn.org/data/attachment/forum/201411/26/141205l23f4v8kdr3vvojs.jpg)
现在的效果看起来并不是很真实。更真实实现这种效果的CSS属性叫做perspective(透视),它会让东西看起来近处的大,远处的小。
perspective属性必须应用到需要做3D变换的元素的父元素上。在WebKit浏览器里,只要是它的祖先元素都行,但在火狐或IE里只能是父元素。
现在我们要往门框元素上添加一个frame--realistic类:
- <div class='container'>
- <div class='frame frame--realistic'>
- <div class='door door--open'></div>
- </div>
- </div>
现在我们在其上设置perspective透视属性。透视属性的值约小,它就会显得离你的眼睛越近,这样,越近的东西会显得越大,越远的越小。
- .frame--realistic {
- perspective: 20em;
- }
我们就得到了下面的效果:
![](http://bbs.html5cn.org/data/attachment/forum/201411/26/141310cdmlfmn0qfg672d3.jpg)
这样看起来就好多了!但我们可以做得更好!比如,我们可以让这扇门动起来,并且具有3D效果。我们只需要在HTML和CSS里将door-open类换成door--ani类:
- .door--ani {
- transform-origin: 0 0;
- animation: doorani 1.3s ease-in-out infinite alternate;
- }
- @keyframes doorani {
- from { transform: rotateY(-43deg); }
- to { transform: rotateY(43deg); }
- }
效果:
------
![](http://bbs.html5cn.org/data/attachment/forum/201411/26/142000l4tuxvklffuziivv.jpg)
现在,我们还想让这扇门的门框也以3D的形式动起来。这很简单,不是吗?只需要在门框上添加一个frame--ani类,设定一个动画动作,将perspective透视属性移动到它的父元素上:
HTML代码变成了这样:
- <div class='container container--realistic'>
- <div class='frame frame--ani'>
- <div class='door door--ani'></div>
- </div>
- </div>
我们还需要添加下面的CSS代码:
- .container--realistic {
- perspective: 20em;
- }
- .frame--ani {
- animation: frameani 2s ease-in-out infinite alternate;
- }
- @keyframes frameani {
- from { transform: rotateY(-30deg); }
- to { transform: rotateY(30deg); }
- }
可是,我们得到的效果却是:
![](http://bbs.html5cn.org/data/attachment/forum/201411/26/142116qqqwnxqcu7d1un99.jpg)
![](http://bbs.html5cn.org/data/attachment/forum/201411/26/142108ee6soilparaoeedo.jpg)
看起来有些怪。看起来门的动画效果被门框的摆动抵消了。的确,事情就是这样,因为transform-style属性(用来告诉浏览器一个具有3D变换属性的子元素是否附随父元素的3D变换属性)的缺省值是flat。
这个问题可以通过将其父元素设置transform-style: preserve-3d来纠正。这样,我们就可以看到更自然的效果了:
![](http://bbs.html5cn.org/data/attachment/forum/201411/26/14223743kqrs1yqw4k1szd.jpg)
![](http://bbs.html5cn.org/data/attachment/forum/201411/26/1422371ayf6s0yswe1u1sl.jpg)
但是,IE10/11只支持transform-style的flat值。有时我们会利用这种技术将父元素和子元素通过3D变换串联起来。
例如,我有一个稍微倾斜的立方体(没有顶部和底部面)。HTML代码是:
- <div class='container container--realistic'>
- <div class='cube'>
- <div class='face'></div>
- <div class='face'></div>
- <div class='face'></div>
- <div class='face'></div>
- </div>
- </div>
相关的CSS:
- .cube {
- position: relative;
- width: 5em; height: 5em;
- transform-style: preserve-3d;
- transform: rotateY(30deg) rotateX(10deg);
- }
- .face {
- position: absolute;
- width: 100%; height: 100%;
- }
- .face:nth-child(1) {
- transform: /*rotateY(0deg)*/ translateZ(2.5em /* half the side length, 5em in this case */);
- }
- .face:nth-child(2) {
- transform: rotateY( 90deg) translateZ(2.5em);
- }
- .face:nth-child(3) {
- transform: rotateY(180deg) translateZ(2.5em);
- }
- .face:nth-child(4) {
- transform: rotateY(270deg) translateZ(2.5em);
- }
使用这些代码(这里有更详细的解释),我们得到了下面的效果:
![](http://bbs.html5cn.org/data/attachment/forum/201411/26/142353gskyikbjgrcrrzgq.jpg)
如果你使用的是IE,我们需要在对每个面实施3D变换前先清空变换属性(如果这个立方体的父类也有变换特征,也需要先清空。)。我将立方体的父元素也处理了,就像下面:
- .cube--ie {
- perspective: 20em;
- transform: none;
- }
- .face--ie:nth-child(1) {
- transform: rotateY(30deg) rotateX(10deg)
- translateZ(2.5em);
- }
- .face--ie:nth-child(2) {
- transform: rotateY(30deg) rotateX(10deg)
- rotateY( 90deg) translateZ(2.5em);
- }
- .face--ie:nth-child(3) {
- transform: rotateY(30deg) rotateX(10deg)
- rotateY(180deg) translateZ(2.5em);
- }
- .face--ie:nth-child(4) {
- transform: rotateY(30deg) rotateX(10deg)
- rotateY(270deg) translateZ(2.5em);
- }
于是,在IE里也得到了同样的效果:
虽然不是很方便,但也不是很糟。代码不是很多,也不是很乱…然而,当我们想旋转这个立方体时却出现了问题。我们需要使用transform-style: preserve-3d属性,我们简单的增加了一个cube--ani类,这段CSS代码是:
- .cube--ani {
- animation: rot 4s linear infinite;
- }
- @keyframes rot {
- to { transform: rotateY(-330deg) rotateX(370deg); }
- }
![](http://bbs.html5cn.org/data/attachment/forum/201411/26/142557g39wl4drwl4ldwrd.jpg)
![](http://bbs.html5cn.org/data/attachment/forum/201411/26/14255600cpkkppknkzke0i.jpg)
可是,对于IE10/11来说,我们无法对立方体自身施加3D变换,我们只能对每个面单独实施3D变换。这就是说,我们要对所有的面设置变换属性。这就是说….每个面都要!
- .cube--ie {
- animation: none;
- }
- .cube--ani .face--ie:nth-child(1) {
- animation: rot1 4s linear infinite;
- }
- @keyframes rot1 {
- to {
- transform: rotateY(-330deg) rotateX(370deg)
- translateZ(2.5em);
- }
- }
- .cube--ani .face--ie:nth-child(2) {
- animation: rot2 4s linear infinite;
- }
- @keyframes rot2 {
- to {
- transform: rotateY(-330deg) rotateX(370deg)
- rotateY(90deg) translateZ(2.5em);
- }
- }
- .cube--ani .face--ie:nth-child(3) {
- animation: rot3 4s linear infinite;
- }
- @keyframes rot3 {
- to {
- transform: rotateY(-330deg) rotateX(370deg)
- rotateY(180deg) translateZ(2.5em);
- }
- }
- .cube--ani .face--ie:nth-child(4) {
- animation: rot4 4s linear infinite;
- }
- @keyframes rot4 {
- to {
- transform: rotateY(-330deg) rotateX(370deg)
- rotateY(270deg) translateZ(2.5em);
- }
- }
![](http://bbs.html5cn.org/data/attachment/forum/201411/26/1427066zvv66ojohhpnz9j.jpg)
![](http://bbs.html5cn.org/data/attachment/forum/201411/26/1427064cr9ci04srtb9cbi.jpg)
如果这么多的代码只是为了这4个面,那当需要面对100多个面时,你能想象是多恐怖的一堆代码吗?
你也许会想到上面的门也有这种问题,门的父元素有高度和宽度,是可见。如何在IE里实现?唯一能让门和门框在IE里一起动起来的方案就是修改HTML代码,让门和门框变成兄弟元素,单独对它们施加动画效果。
(英文:How Nesting 3D Transformed Elements Works.)
via:http://www.webhek.com/3d-transforms