这是一篇关于transform-style和perspective属性的使用分享!
transform-style属性
transform-style属性是3D空间中一个极为重要的属性,指定嵌套元素是如何在3D空间中进行效果呈现的。它主要油两个属性值:
flat 和 preserve-3d
transform-style 属性的使用语法十分简单:
transform-style: flat | preserve-3d
其中 flat 值为默认值,表示所有子元素在 2D 平面中呈现效果。
preserve-3d 则表示所有元素在 3D 空间中呈现。
也就是说,如果你对一个元素设置了
transform-style 的值为 “flat” ,那么,该元素所有子元素都将会平展到该元素的 2D 平面中进行呈现。不管是沿着X轴或是Y轴方向去旋转该元素都将会导致位于正或负Z轴位置的子元素显示在该元素的平面上,而并非显示在它的前面或是后面。如果对其中一个元素设置了 transform-style 值为 “preserve-3d” 它表示不执行平展操作,他的所有子元素将位于 3D 空间中。
transform-style 属性需要设置在父元素中,并且高于任何嵌套的变性元素。最后,我们运用一个翻转的例子来为大家加深一下对“transform-style” 属性的印象:
HTML模板
<div class="wrap"> <div class="spin"> <div class="rotate"> <img src="images/cardKingClub.png" alt="" width="142" height="200" /> </div> </div> </div> <div class="wrap"> <div class="spin"> <div class="rotate three-d"> <img src="images/cardKingClub.png" alt="" width="142" height="200" /> </div> </div> </div>
CSS代码段
.wrap { width: 500px; height: 300px; margin: 30px auto; position: relative; background: url(images/bg-grid.jpg) no-repeat center center; background-size: 100% 100%; } /*设置动画*/ @keyframes spin{ 0%{ transform:rotateY(0deg) } 100%{ transform:rotateY(360deg) } } .spin { width: 142px; height: 200px; position: absolute; top: 50%; left: 50%; margin-left: -72px; margin-top: -101px; border: 1px dashed orange; cursor: pointer; transform-style: preserve-3d; } /*调用动画*/ .spin:hover{ animation:spin 5s linear infinite; } .rotate { background: url(images/cardKingClub.png) no-repeat center; background-size: 100% 100%; border: 5px solid hsla(50,50%,50%,.9); transform: perspective(200px) rotateY(45deg); } .rotate img{ border: 1px solid green; transform: rotateX(15deg) translateZ(10px); transform-origin: 0 0 40px; } /*改变transform-style的默认值*/ .three-d { transform-style: preserve-3d; }
这里需要进行声明的是:为了能够节省更多的篇幅,便于大家更快浏览和阅读内容,在CSS3属性的代码中省略了各大浏览器的私有前缀,而在实际操作中需要将各大浏览器前缀加上,效果才能够得以呈现!
效果展示:
正如你上面看到的效果一样,如果给元素设置了 “.rotate” 设置了 “flat” 值的时候,其子元素 “img” 不会根据 “translateZ()” 值摊开,而是只在同一个平面进行旋转,正确上图见到的一样;
当元素 “.rotate” 设置了 “preserve-3d” 值的时候,其子元素 “img” 会根据 “translateZ()” 值摊开,不会再出现堆叠在一起的现象出现,这也正如上图下面部分所呈现的效果一样。
在这里需要提醒大家的一点是:如果你的元素设置了 “transform-style” 值为 “preserve-3d” 你就不能够因为防止子元素溢出容器而同时设置 “overflow” 值为 “hidden” ,如果设置了 “overflow:hidden” 同样可以迫死子元素出现在同一个平面(和元素设置了 “transform-style” 为 “flat” 一样的效果),如同下图效果所示:
perspective 属性
“perspective”属性对于3D变形来说有着至关重要的功能。这个属性会设置查看着的位置,并将可视内容映射到一个视锥上面,继而投到一个2D视平面上。如果不为其指定透视,则X轴空间中的所有点将会平铺到同一个2D视平面中,并且变换的结果中也将不存在任何的景深概念。
上面的描述可能让大家难以理解,其实对于 “perspective” 属性来说,我们大可简单的将其理解为“视距”,用来设置用户和元素3D空间Z平面之间的距离。而其效应则是由他的“值”来决定的,值越小,用户与3D空间Z平面距离就会越近,视觉效果当然更会令看到的人印象深刻;反之,值越大,用户与3D空间Z平面距离就会越远,视觉效果就变得很小。
在3D变形中,对于某些变形而言,例如下面所演示的沿着Z轴的变形示例中 “perspective” 属性对于查看变形的效果来说是必不可少的。
我们先通过一个简单实例,制作一个扑克牌的3D旋转效果,并且一个在扑克牌的父元素中添加了 视距 “perspective” ,而一个却没有设置:
HTML模板
<div> <img src="images/cardKingClub.png" alt="" width="142" height="200" /> <img src="images/cardKingClub.png" alt="" width="142" height="200" /> </div> <div> <img src="images/cardKingClub.png" alt="" width="142" height="200" /> <img src="images/cardKingClub.png" alt="" width="142" height="200" /> </div>
CSS代码段
div { width: 500px; height: 300px; margin: 30px auto; position: relative; background: url(images/bg-grid.jpg) no-repeat center center; background-size: 100% 100%; } div img { position: absolute; top: 50%; left: 50%; margin-left: -71px; margin-top: -100px; transform-origin: bottom; } div img:nth-child(1){ opacity: .5; z-index: 1; } div img:nth-child(2){ z-index: 2; transform: rotateX(45deg); } div:nth-of-type(2){ perspective: 500px; }
效果如下图:
效果说明一切,由上面的效果可以看到,在没有对父节点设置 “perspective” 情况下,梅花King的3D旋转效果并不明显,而当对父节点设置了 “perspective” 之后,梅花King才像个3D旋转。
上面的示例简单的对 “perspective” 的使用方法做了演示,下面我们来看一下关于 “perspective” 的使用语法:
perspective:none | <length>
“perspective” 属性包括两个属性:“none” 和具有单位的长度值。 其中 “perspective” 属性的默认值为 “none” ,则表示通过无限的角度来看3D物体,但是看上去却像是一个平的。 另一个值 “< length >” 接受一个长度单位大于“0”的值。而且其单位不能为百分比的值。
“< length >” 的值越大,则角度出现的就越远,从而创建一个相当低的强度和非常小的3D空间的变化。反之,值越小,角度出现的就会越近,从而创建一个高强度的角度和一个大型的3D变化。
如果说你站在10英尺和1000英尺的地方去看一个10英尺的立方体。在10英尺的地方,你距离立方体却是一样的尺寸。所以视角转变远远大于站在1000英尺处的效果,立体尺寸是你距离立方体距离的百分之一。同样的思维也适用于 “perspective” 的 “< length >” 值。下面我们一起来看这样一个实例,加强一下对这方面的理解:
HTML模板
<div class="wrapper w2"> <div class="cube"> <div class="side front">1</div> <div class="side back">6</div> <div class="side right">4</div> <div class="side left">3</div> <div class="side top">5</div> <div class="side bottom">2</div> </div> </div> <div class="wrapper w1"> <div class="cube"> <div class="side front">1</div> <div class="side back">6</div> <div class="side right">4</div> <div class="side left">3</div> <div class="side top">5</div> <div class="side bottom">2</div> </div> </div>
CSS代码段
.wrapper { width: 50%; float: left; } .cube { font-size: 4em; width: 2em; margin: 1.5em auto; transform-style: preserve-3d; transform: rotateX(-40deg) rotateY(32deg); } .side { position: absolute; width: 2em; height: 2em; background: rgba(255, 99, 71, 0.6); border: 1px solid rgba(0, 0, 0, 0.5); color: white; text-align: center; line-height: 2em; } .front { transform: translateZ(1em); } .top { transform: rotateX(90deg) translateZ(1em); } .right { transform: rotateY(90deg) translateZ(1em); } .left { transform: rotateY(-90deg) translateZ(1em); } .bottom { transform: rotateX(-90deg) translateZ(1em); } .back { transform: rotateY(-180deg) translateZ(1em); } .w1 { perspective: 100px; } .w2{ perspective: 1000px; }
通过这段代码 你将会看到下面图片中的效果:
根据上面的介绍,我们大可对 “perspective” 取值来做一个简单的结论:
1、Perspective取值为 none 或不设置,就没有真的3D空间
2、Perspective取值越小,3D效果就越明显,也就是说你的眼睛就越靠近3D。
3、Perspective的值无穷大时,或是值为“0”时与取值为 none 效果是一样的。
为了让大家能够更好的去理解 “perspective” 属性,我们很有必要的把他和 “translateZ” 的关系结合起来。其实完全可以把 “perspective” 的值简单的理解为人的眼睛到显示器的距离,但是 “translate” 则是3D物体距离源点的距离,下面引用W3C的一张图来作为解说 “perspective” 和 “translateZ” 之间的微妙关系。
通过上面这张图我们可以发现 “perspective” 属性和 “translateZ” 的位置比例。要顶部的图,Z是半个d,为了使用原始圆(轮廓)看起来出现在Z轴上(虚线圆),画布上的实体圆将扩大为两部分,如浅蓝色的圆、在底部图中显示,圆按比例缩小,致使虚线圆出现在画布后面,并且z的大小是距离原始位置三分之一处的。
在3D变形中,除了 “perspective” 属性可以激活一个3D空间之外,在3D变形的函数中的 “perspective () ” 也是可以激活3D空间。他们的不同点是 “perspective” 用在舞台元素上(变形元素们的共同父元素);“perspective () ” 就是用在当前变形元素上,并且可以与其他的 “transform” 函数一起使用,如同下面实例;当我们把 ".stage { perspective: 600px } " 写成 ".stage .box { transform: perspective(600px); } " 的时候,大家来看一下效果吧:
HTML模板
<div class="stage"> <div class="container"> <img src="images/cardKingClub.png" alt="" width="142" height="200" /> </div> </div> <div class="stage"> <div class="container"> <img src="images/cardKingClub.png" alt="" width="142" height="200" /> </div> </div>
CSS代码段
.stage { width: 500px; height: 300px; margin: 30px auto; position: relative; background: url(images/bg-grid.jpg) no-repeat center center; background-size: 100% 100%; } .container { position: absolute; top: 50%; left: 50%; width: 142px; height: 200px; border: 1px dotted orange; margin-left: -71px; margin-top: -100px; } .container img{ transform: rotateY(45deg); } .stage:nth-child(1) .container{ perspective: 600px; } .stage:nth-child(2) img { transform:perspective(600px) rotateY(45deg); }
你会看到下面的效果展示:
通过上面这张效果图可以看出,虽然在书写形式和属性名不同的情况下,所展示出来的效果确是一样的。
虽然 “perspective” 属性和 “perspective () ” 函数所起到的功能是一样的,但是其取值以及运用的对象却是不同的:
“perspective” 属性可以取值为 “none” 或是长度值; 而 “perspective () ” 函数取值只能是“大于0”的值,如果取值为“0”或是比“0”还小的值,那么将无法激活3D空间了;
“perspective” 属性用于变形对象父元素;而 “perspective ()” 函数用于变形对象自身,并且和 “transform” 其他函数一起来使用。
perspective-origin属性
“perspective-origin” 属性是3D变形中另外一个重要的属性,主要用来决定 “perspective” 属性的源点角度。它实际上设置了X轴和Y轴的位置,并且在该位置观看者好像在观看该元素的子元素。
“perspective-origin” 属性的使用语法也很简单:
perspective-origin:[<percentage> | <length> | left | center | right | top | bottom] | [[<percentage> | <length> | left | center | right] && [<percentage> | <length> | top | center | bottom]]
该属性的默认值为“50% 50%”(也就是center),其他可以设置为一个值,也可以设置为两个长度的值;
第一个长度值指定相对于元素的包含框的X轴上的位置。它可以是长度值(以受支持的长度单位表示)、百分比或下三个关键词之一: “left” (表示在包含框的X轴方向长度的0%),“center” (表示中间点)或 right(表示长度的100%)。
第二个长度值指定相对于元素的包含框的Y轴上的位置。它可以是长度值、百分比或下三个关键词之一: “top”(表示在包含框的Y轴方向长度为0%),“center”(表示中间点)或 “bottom” (表示长度的100%)。
在这里需要注意的是,为了指转换子元素变形的深度, “perspective-origin” 属性必须定义父元素上。通常 “perspective-origin” 本身不做任何事情,它必须被定义在设置了 “perspective” 属性的元素上。也就是说 “perspective-origin” 属性需要同 “perspective” 相结合起来才能够使用,以便将视点移至元素的中心以外的位置,如下图所示效果:
通常我们看一个东西的时候不可能一直都在中心位置上,我们会更换不同的角度去看得更清楚一下,需要满足这个条件的时候,我们就需要通过 “perspective-origin” 这个属性来实现效果,下面来自于W3C官方上的图片来帮助大家理解这一观点:
下面的示例则演示了修改 “perspective-origin” 的属性值对立方体产生的影响;
backface-visibility属性
“backface-visibility”属性决定元素旋转背面是否可见。对于未旋转的元素来说,该元素的正面是面向观看者的。当其Y轴旋转约180度的时候,则会导致元素的背面面对观众。 “backface-visibility” 属性使用的语法也很简单;
backface-visibility: visible | hidden
该属性被设置为以下两个关键词之一:
visible:为 backface-visibility 的默认值,表示反面可见
hidden:表示反面不可见
一个元素的可见性与“backface-visibility: visible | hidden ” 决定如下:
当元素在3D环境下渲染上下文的时候,将会根据3D变形矩阵来计算,反之元素不在3D环境下渲染上下文,将会根据2D变形矩阵来计算。
但是如果组件的矩阵在第3行、3列是负值,那么元素反面是隐藏的,反之则是可见的。
简单点来说:“backface-visibility " 属性可用于隐藏内容的背面。在默认情况下。背面是可见的,这也就意味着即使在翻转后,旋转的内容仍然是可见的。但是当“backface-visibility”设置为“hidden”的时候,旋转后内容就将会被隐藏,因为旋转后正面将不再可见。该功能可以帮助你去模拟多面的对象,具体效果看下面纸牌的效果图吧。我们通过将“backface-visibility” 设置为“hidden”,你就可以轻松确保这只有正面是可见的。
HTML模板
<div class="stage"> <div class="container"> <div class="card front"></div> <div class="card back"></div> </div> </div> <div class="stage"> <div class="container"> <div class="card front"></div> <div class="card back"></div> </div> </div> <div class="stage"> <div class="container"> <div class="card front"></div> <div class="card back"></div> </div> </div> <div class="stage"> <div class="container"> <div class="card front"></div> <div class="card back"></div> </div> </div> <div class="stage"> <div class="container"> <div class="card front"></div> <div class="card back"></div> </div> </div> <div class="stage"> <div class="container"> <div class="card front"></div> <div class="card back"></div> </div> </div> <div class="stage"> <div class="container"> <div class="card front"></div> <div class="card back"></div> </div> </div>
CSS代码段
*{ margin: 0; padding: 0; } body { background-color: hsla(173,80%,21%,.9); } .stage{ float: left; border: 1px dotted orange; position: relative; margin: 20px; border-radius: 8px; perspective: 1000; } .container { width: 102px; height: 142px; position: relative; transition: 0.5s; transform-style: preserve-3d; } .card { position: absolute; top: 0; right: 0; bottom: 0; left: 0; backface-visibility: hidden; } .front { background: url(images/cardjfront.png) no-repeat center/100% 100%; z-index: 2; } .back { background: url(images/cardjback.png) no-repeat center/100% 100%; transform: rotateY(180deg); } .stage:nth-child(1) .container{ transform: rotateY(0deg); } .stage:nth-child(2) .container{ transform: rotateY(30deg); } .stage:nth-child(3) .container{ transform: rotateY(60deg); } .stage:nth-child(4) .container{ transform: rotateY(90deg); } .stage:nth-child(5) .container{ transform: rotateY(120deg); } .stage:nth-child(6) .container{ transform: rotateY(150deg); } .stage:nth-child(7) .container{ transform: rotateY(180deg); }
你将会看到这样的效果:
在这个示例中,未旋转的时候,你将会看到扑克牌的正面,也就是红桃J,这是由于其定位于顶部。但是随着向扑克牌应用的旋转超过了90度的时候,第二个“div”的“backface-visibility:hidden”属性所导致其变为不可见,所以将显示扑克牌的正面。接下来我们将第三个“div”的“backface-visibility” 设置为“visible” :
.card { position: absolute; top: 0; right: 0; bottom: 0; left: 0; backface-visibility: visible; }
则会出现下面的效果:
根据上面的示例,从视觉上并不太好让人理解,我们可以通过两个3D立方体来做一个能够让你从视觉上更容易去区分的示例:
"backface-visibility"取值为“hidden”和“visible”的区别如下图所示的效果:
HTML模板
<div class="container"> <h1>backface-visibility:visible</h1> <div class="cube backface-visibility-visible"> <div class="side front">1</div> <div class="side back">2</div> <div class="side right">3</div> <div class="side left">4</div> <div class="side top">5</div> <div class="side bottom">6</div> </div> </div> <div class="container"> <h1>backface-visibility:hidden</h1> <div class="cube backface-visibility-hidden"> <div class="side front">1</div> <div class="side back">2</div> <div class="side right">3</div> <div class="side left">4</div> <div class="side top">5</div> <div class="side bottom">6</div> </div> </div>
CS代码段
.container { width: 500px; height: 300px; float: left; position: relative; margin: 30px; border: 1px solid #CCC; perspective: 1200px; } .cube { width: 100%; height: 100%; position: absolute; animation: spinCube 8s infinite ease-in-out; transform-style: preserve-3d; transform: translateZ( -100px ); } @keyframes spinCube { 0% { transform: translateZ( -100px ) rotateX( 0deg ) rotateY( 0deg ); } 100% { transform: translateZ( -100px ) rotateX( 360deg ) rotateY( 360deg ); } } .side { display: block; position: absolute; width: 196px; height: 196px; border: 2px solid black; line-height: 196px; font-size: 120px; font-weight: bold; color: white; text-align: center; } .cube.backface-visibility-visible .side { backface-visibility: visible; } .cube.backface-visibility-hidden .side { backface-visibility: hidden; } .cube .front { background: hsla( 0, 100%, 50%, 0.7 ); } .cube .back { background: hsla( 60, 100%, 50%, 0.7 ); } .cube .right { background: hsla( 120, 100%, 50%, 0.7 ); } .cube .left { background: hsla( 180, 100%, 50%, 0.7 ); } .cube .top { background: hsla( 240, 100%, 50%, 0.7 ); } .cube .bottom { background: hsla( 300, 100%, 50%, 0.7 ); } .cube .front { transform: translateZ( 100px ); } .cube .back { transform: rotateX( -180deg ) translateZ( 100px ); } .cube .right { transform: rotateY( 90deg ) translateZ( 100px ); } .cube .left { transform: rotateY( -90deg ) translateZ( 100px ); } .cube .top { transform: rotateX( 90deg ) translateZ( 100px ); } .cube .bottom { transform: rotateX( -90deg ) translateZ( 100px ); }
效果如下图所示:
上面这个效果图是否让你更容易理解了呢?
“backface-visibility”的“visible”和“hidden”的区别,上图中左边立方体每个页我们都能够看得到,而右边的这个立方体我们只能够看到在在视野中的几个面。
以上内容就是“transform-style和perspective属性的使用!”希望能够给大家带来更多的帮助!