Heim >Web-Frontend >HTML-Tutorial >CSS3 transform介绍_html/css_WEB-ITnose

CSS3 transform介绍_html/css_WEB-ITnose

WBOY
WBOYOriginal
2016-06-24 11:17:021286Durchsuche

CSS里transform变形这个属性有点学习难度,尤其在CSS3里加上了3D效果之后,2维变3维学习成本更是成倍提高。为什么设计师的眼里饱含着泪水,因为对页面效果爱的深沉。本篇就介绍一下transform。(擎天柱:Autobot transform!)

transform本质上是一系列变形函数,分别是translate位移,scale缩放,rotate旋转,skew扭曲,matrix矩阵。戒骄戒躁,我们一个个讲。

  • 前置属性:
    • transform-origin
    • transform-style
    • perspective
    • perspective-origin
    • backface-visibility
  • 2D变形:
    • translate
    • scale
    • rotate
    • skew
    • matrix
  • 3D变形:
    • translate3d
    • scale3d
    • rotate3d
    • matrix3d
  • 层级影响

前置属性

transform-origin

用于指定元素变形的中心点。默认中心点就是元素的正中心,即XYZ轴的50% 50% 0处。可以通过该属性改变元素在XYZ轴的中心点,正值表示正向位移,负值表示负向位移。(XYZ轴的正向分别是往右,往下,靠近用户眼睛。反之为反向)

表示2维的x-offset/y-offset可以设px值也可以设%百分比,也可设top / right / bottom / left / center等keyword。表示3维的z-offset只能设px值,不能设%百分比,也没有keyword。

默认中心点在元素正中心,因此关键字top等价于top center等价于50% 0%(x轴仍旧留在50%处,y轴位移到0%处)。同理各关键字例如right等价于right center等价于100% 50%,不多赘述。

一图胜千言:为图片设置不同的中心点后,看它们旋转,扭曲,缩放的效果。例如图1表头的第一行center表示transform-origin: center。第二行rotate(30deg);表示transform: rotate(30deg);。

另外transform-origin指定变形中心点对translate位移没有影响。translate位移始终相对于元素正中心进行位移,有怀疑精神的可以自己试一下。

transform-style

这个属性比较简单只有两个值flat和preserve-3d。用于指定舞台为2D或3D,默认值flat表示2D舞台,所有子元素2D层面展现。preserve-3d看名字就知道了表示3D舞台,所有子元素在3D层面展现。注意,在变形元素自身上指定该属性是没有用的,它用于指定舞台,所以要在变形元素的父元素上设置该属性。设定后,所有子元素共享该舞台。一图胜千言:

.div1 {    float: left;    background-color: red;    transform: perspective(200px) rotateY(45deg);}.div1 img{    transform: translateZ(16px);}.p3d {    transform-style: preserve-3d;}<div class="div1"><img  src="head75.png" / alt="CSS3 transform介绍_html/css_WEB-ITnose" ></div><div class="div1 p3d"><img  src="head75.png" / alt="CSS3 transform介绍_html/css_WEB-ITnose" ></div>

两图唯一的区别是:右图的父div上设了transform-style: preserve-3d;,因此呈现了3d效果。左图的父div没有设transform-style默认是flat,因此元素不会在Z轴展开(translateZ(16px)失效),只能呈现2D效果。

另外如果同时设了transform-style: preserve-3d;和overflow: hidden;,3D效果将失效,等价于transform-style: flat;。如果你发现3D效果没有像预想地那样出现,可以检查一下(包括祖先元素)是否有overflow: hidden;,该属性将flatten everything…

perspective

指定3D的视距。默认值是none表示无3D效果,即2D扁平化。上面例子代码里其实已经用到过该属性了。介绍它之前,先借用rotateX / rotateY / rotateZ来明确一下xyz轴坐标的基本概念。一图胜千言,依次是rotateX轴旋转,rotateY轴旋转,rotateZ轴旋转:

.x {    transform: perspective(200px) rotateX(60deg);}.y {    transform: perspective(200px) rotateY(60deg);}.z {    transform: perspective(200px) rotateZ(60deg);}<img  class="x" src="head75.png" / alt="CSS3 transform介绍_html/css_WEB-ITnose" ><img  class="y" src="head75.png" / alt="CSS3 transform介绍_html/css_WEB-ITnose" ><img  class="z" src="head75.png" / alt="CSS3 transform介绍_html/css_WEB-ITnose" >

从图中也可以看出,烤羊肉串就是x轴旋转,钢管舞就是y轴旋转,彩票转盘就是z轴旋转。上面z轴只是一个点,想象一下就能明白,该点其实是一根垂直于屏幕的线,而perspective视距就是该线从屏幕到用户眼睛的距离。

实现3D的关键就是要有perspective视距,如果将上述代码中perspective(200px)去掉,效果如下:

除了z轴旋转不受影响外,xy轴虽然还在旋转,但失去了3D效果,是2D扁平化的旋转。原因就是因为不设perspective的话,其默认值为none,没有视距没有3D。

perspective只能设px值,不能设%百分比。值越小表示用户眼睛距离屏幕越近,相当于创建一个较大的3D舞台。反之,值越大表示用户眼睛距离屏幕越远,相当于创建一个较小的3D舞台。这很容易理解,离的越近东西看起来越大,离的越远东西看起来越小。但具体该怎么设呢?借用W3C的图配合translateZ来帮助理解视距。

图中d就是perspective视距,Z就是translateZ轴的位移。Z轴正向位移时,3D舞台将放大。反之,Z轴负向位移时,3D舞台将缩小。上图Z是d的一半,因此3D舞台上的元素将是原来的2倍。下图Z同样是d的一半,但由于是负值,所以3D舞台上的元素将缩小三分之一。实际试试:

.divsp {    display: inline-block;    border: 1px blue dashed;    margin-left: 30px;    perspective: 100px;}.z1 {    transform: translateZ(-75px);}.z2 {    transform: translateZ(0px);}.z3 {    transform: translateZ(25px);}.z4 {    transform: translateZ(101px);}<div class="divsp"><img  class="z1" src="head75.png" / alt="CSS3 transform介绍_html/css_WEB-ITnose" ></div><div class="divsp"><img  class="z2" src="head75.png" / alt="CSS3 transform介绍_html/css_WEB-ITnose" ></div><div class="divsp"><img  class="z3" src="head75.png" / alt="CSS3 transform介绍_html/css_WEB-ITnose" ></div><div class="divsp"><img  class="z4" src="head75.png" / alt="CSS3 transform介绍_html/css_WEB-ITnose" ></div>

4张图的视距都是100px,表示4张图的3D舞台距离你的眼睛100px。我们从右往左来理解。图4的translateZ(101px)看到图片消失了,因为3D舞台距离你眼睛100px,而图片从舞台往Z轴正向位移101px,图片到了你脑袋后面自然什么都看不见。如果设成translateZ(100px),相当于图片紧贴着你的眼睛,所以全屏都是图片。图3的translateZ(25px),原始图片为75px,放大后的图片为100px。这是道初中数学题,你可以画一个底边是75px(图片原始尺寸),高是75px(视距100px-Z轴位移25px=75px)的等腰三角形,然后高扩展到100px,底边将等比例扩大3分之1至100px。图2的translateZ(0px)表示Z轴没有位移,因此仍旧是原始大小。图4的translateZ(-75px),同样是道初中数学题,原始图片为75px,缩小到42.85px,再看看上面W3C的图理解一下,很容易算出来。

仔细看代码的可以看出来,上面介绍XYZ轴旋转时是直接在变形元素img上指定的transform: perspective(200px) rotateX(60deg);。而上面的代码是给变形元素img的父div指定perspective: 100px;。你可以理解为前一种方式是perspective()函数,后一种方式是perspective属性。两种指定方式是有区别的:

  1. 前者perspective()函数指定只针对当前变形元素,需要和transform其他函数一起使用,仅表示当前变形元素的视距。
  2. 后者perspective属性指定用于3D舞台,即3D舞台的视距,里面的子元素共享这个视距
perspective-origin

设置视距的基点,看W3C的图就能明白

基点默认值是50% 50%即center,表示视距基点在中心点不进行任何位移。你可以让基点在XY轴上进行位移,产生上图那样的效果。注意该属性同样应该定义在父元素上,适用于整个3D舞台。它需要和perspective属性结合着一起用。效果如下图:

.td1 {     transform-style: preserve-3d;    perspective: 200px;    perspective-origin: center;}

为节约篇幅,只贴出来图1的3D舞台的配置,其余8图只需根据表头修改perspective-origin即可。根据上面9宫格图就比较容易理解perspective-origin视距基点的意思了。默认值50% 50%即center表示眼睛在舞台正中心。然后根据XY轴的位移量,或关键字left(等价于x轴0%)等,调整眼睛看3D舞台的位置。

backface-visibility

用于是否可以看见3D舞台背面,默认值visible表示背面可见,可以设成hidden让背面不可见。通常当旋转时,如果不希望背面显示出来,该属性就很有用,设成hidden即可。一图胜千言:

.stage{    float: left;    margin: 5px;    perspective: 200px;}.container {    transform-style: preserve-3d;}.image {    backface-visibility: hidden;}.front {    position: absolute;    z-index: 1;}.back {    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); }<div class="stage">    //为节约篇幅该DOM请无脑复制7个    <div class="container">        <img  class="image front" src="head75.png" / alt="CSS3 transform介绍_html/css_WEB-ITnose" >        <img  class="image back" src="bg75.png" / alt="CSS3 transform介绍_html/css_WEB-ITnose" >    </div></div>

DOM结构中就能看出,是两张图片(一正一反)叠在了一起。由于变形元素img设了backface-visibility: hidden;,当Y轴旋转超过90度时(Y轴旋转正好90度时,正中间图4为一片空白,就像丁字裤在视线里消失了^_^),正面的图片将不可见,底下的背面图片显示出来了。如果将img的backface-visibility属性去掉(默认为visibility),效果如下图。Y轴旋转超过90度时,将显示正面的图片的背部(所谓背部对屏幕来说其实就是图片矩阵的X轴值取反):

至此5个前置属性介绍完毕。它们多用于3D场合,因此常见的3D的HTML结构如下:

<舞台>         //为舞台加上perspective    <容器>     //为容器加上preserve-3d,使容器内元素共享同一个3D渲染环境        <元素> //为元素加上transform效果    </容器></舞台>

2D变形

2D变形有translate位移,scale缩放,rotate旋转,skew扭曲,matrix矩阵。基本的内容就不细说了,自行参照w3cschool,这里只介绍一些w3cschool上没有讲的内容。

translate位移

translate位移系列中用于2D的有:translate,translateX,translateY

translate位移,类似于position:relative属性。可设单值,也可设双值。正数表示XY轴正向位移,负数为反向位移。设单值表示只X轴位移,Y轴坐标不变,例如transform: translate(100px);等价于transform: translate(100px,0);。这点和CSS中其他单值属性稍有不同,不要误以为单值是X轴和Y轴均位移。当然最好还是用双值,如果真的和Y轴无关,也请用translateX(100px),虽然效果是一样的,但代码可读性更高。同理如果和X轴无关,可以用transform: translateY(100px);等价于transform: translate(0, 100px);

上面说了效果类似于position:relative属性,但和position语义不同,position用于页面布局,而translate属于transform中的一个系列,用于元素变形。你可能觉得语义不同有什么卵用,效果OK不就行了?就看你用什么标准来衡量效果了。CSS的神奇之处在于你可以将一个属性用在完全违背它原意的场景下,抛开代码可读性不谈,违背原意有时还是会有细微差别的。如结合动画效果时,translate能小于1px过渡,因此动画效果更为平滑。但position最小单位就是1px,动画效果肯定打折扣。另外用translate实现动画时,可以使用GPU,动画的FPS更高,而position显然无法享受这个优势。其他如回流和重绘也都有差异。因此如果你在该用translate的地方用了position,今后一些需求变动达不到要求,你也没什么立场可抱怨的了。

scale缩放

scale缩放系列中用于2D的有:scale,scaleX,scaleY

scale缩放,同样可以设单值和双值。单值时表示X轴和Y轴等值缩放。默认值为1,要缩小请设0.01~0.99之间的值,要放大请设超过1的值。例如缩小一倍可以transform: scale(.5);,放大一倍可以transform: scale(2);。效果在最上面介绍transform-origin时图片里已经有了,不多赘述。

如果只想X轴缩放,可以用scaleX(.5)相当于scale(.5, 1)。同理只想Y轴缩放,可以用scaleY(.5)相当于scale(1, .5)。

设双值可以实现X轴Y轴不等比例缩放,如transform: scale(.5, 1.5);,原本75*75px的图片变成了37.5*112.5px大小。如左图:

w3cschool上没说的是,scale还能设负数,负数会先将元素反转再缩放,如transform: scale(-.5, -1.5);,效果见上面右图。为何反转能理解吧?XY轴像素矩阵各值取反后,效果等价于反转。当然你同样可以用rotate实现反转。

rotate旋转

rotate旋转系列中用于2D的有:rotate

rotate旋转,比较简单,只能设单值。正数表示顺时针旋转,负数表示逆时针旋转。如transform: rotate(30deg);,效果在最上面介绍transform-origin时图片里已经有了,不多赘述。(注意和上面不同,在2D层面上没有rotateX / rotateY,它俩和rotateZ都是3D旋转)

skew扭曲

skew扭曲系列中用于2D的有:skew,skewX,skewY

skew扭曲可以设单值和双值。单值时表示只X轴扭曲,Y轴不变,如transform: skew(30deg);等价于transform: skew(30deg, 0);。考虑到可读性,不推荐用单值,应该用transform: skewX(30deg);。skewY表示只Y轴扭曲,X轴不变。效果在最上面介绍transform-origin时图片里已经有了,不多赘述。

matrix矩阵

matrix矩阵前面没有直接接触,但却是所有2D变形的本质,上面所有2D变形效果都可以用matrix矩阵来实现。本篇先略过,将它和3D矩阵matrix3d留到下一篇再介绍。

3D变形

3D变形有translate3d位移,scale3d缩放,rotate3d旋转, matrix3d矩阵。(注意skew扭曲是没有3D的)。3D的用法和2D差不多,只不过多了个Z轴的值而已(这不是废话么…)。

translate3d位移

translate3d位移系列中用于3D的有:translate3d,translateZ

translate3d(tx,ty,tz),其中tz的Z轴长度只能为px值,不能为%百分比。translateZ等价于translate3d(0,0,tz)。Z轴的值越大表示离眼睛越近,元素就越大,但当值大于perspective视距时元素将消失,因为眼睛无法看见眼睛背后的东西,这在上面介绍perspective时已经介绍过,不再赘述。值越小表示离眼睛越远,元素就越小。实际使用中translateZ效果和2D的scale缩放效果非常像,但原理是有区别的,translateZ是Z轴上位移,而scale是XY轴的缩放。还是那句话,尽量将属性用在符合属性愿意的场合。

scale3d缩放

scale3d缩放系列中用于3D的有:scale3d,scaleZ

scale3d(sx,sy,sz),其中sz为Z轴的缩放比例,取值同sx,sy一样,在0.01~0.99时元素缩小,1时大小不变,大于1时元素变大。scaleZ等价于scale(1,1,sz)。需要注意的是单独使用scale3d或scaleZ不会有任何效果,需要配合其他属性在3D舞台上才能出现效果,否则Z轴的缩放比例根本无法定义。

rotate3d旋转

rotate3d旋转系列中用于3D的有:rotate3d,rotateX,rotateY,rotateZ

rotate3d(x,y,z,a)这里多了一个参数a(读音是阿尔法…)表示3D舞台上旋转的角度,而xyz的取值为0~1为各轴的旋转矢量值。rotate3d,rotateX,rotateY,rotateZ的效果在上面都有展示,不赘述。

matrix3d矩阵

最后matrix3d矩阵是所有3D变形的本质,上面所有3D变形效果都可以用matrix3d矩阵来实现。本篇先略过,将它和上面的2D矩阵matrix留到下一篇再介绍。

层级影响

现在来看看变形对CSS层级的影响。说起层级,absolute绝对是层级间的高富帅,见一个睡一个,sorry,是见一个压一个,sorry,是见一个覆盖一个。

//左图<img    style="max-width:90%" src="bg100.png" / alt="CSS3 transform介绍_html/css_WEB-ITnose" ><img  src="head75.png" / alt="CSS3 transform介绍_html/css_WEB-ITnose" >//右图<img    style="max-width:90%" src="bg100.png" / alt="CSS3 transform介绍_html/css_WEB-ITnose" ><img    style="max-width:90%" src="head75.png" / alt="CSS3 transform介绍_html/css_WEB-ITnose" >

左图因为第一张img具有absolute,完全无视DOM结构中的顺序,妥妥地覆盖了第二张img。右图给第二张img设了transform,通常我们会认为scale(1)是废代码,但实际从右图已经看出,由于设立transform,使元素具有了相当于absolute的层级,因此两张img平级了,根据DOM中的顺序,后者覆盖了前者。

(这里使用的是scale,你可以改成rotate,skew等,效果都一样。即层级和transform有关,但和具体哪个transform函数无关)

因为absolute和transform平级,你可以调整上面两张img的顺序,这样设了transform的图片会被absolute覆盖。如果你非要让absolute高人一等,可以设z-index:1这样层级会高于transform,达到覆盖效果。

和absolute同系列的relative和fixed也适用上述层级关系。如果你页面上有个fixed广告标签,页面滚动时被transform元素覆盖了,请不要惊讶,试试设一下z-index。

总结

transform变形的用法介绍到这就差不多了。为缩减篇幅,文中代码都省略-ms,-o等前缀,需要浏览器全适应的请自行加上。下一篇matrix/matrix3d会更深入其本质,看看这些变形函数究竟是如何变换坐标位置,显示出各种效果的。

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn