CSS のtransform 属性は学習するのが少し難しく、特に CSS3 に 3D 効果が追加された後は、2 次元から 3 次元に変更する学習コストが 2 倍になります。デザイナーの目に涙があふれているのは、ページのエフェクトがとても気に入っているからです。この記事ではトランスフォームについて紹介します。 (オプティマス プライム: オートボットのトランスフォーム!)
Transform は本質的に一連の変換関数であり、変位の変換、スケーリングのスケール、回転の回転、歪みの歪み、および行列の行列です。傲慢さや衝動性を避けて、一つずつ話していきましょう。
は、2 次元の x オフセット/y オフセットを px に設定できることを意味します。値、% パーセンテージ、または上/右/下/左/中央およびその他のキーワード。 3 次元 Z オフセットでは % パーセンテージではなくピクセル値のみを設定でき、キーワードがないことを示します。
デフォルトの中心点は要素の中心にあるため、キーワード top は top center と等価で、これは 50% 0% に相当します (x 軸は 50% のままで、y 軸は にシフトします) 0%)。同様に、right などの各キーワードは右中央、つまり 100% 50% に相当するため、詳細は説明しません。
百聞は一見にしかず: 写真にさまざまな中心点を設定した後、回転、歪み、拡大縮小の効果を観察します。たとえば、図 1 のヘッダーの最初の行の center は、transform-origin: center を表します。 2行目のrotate(30deg)はtransform:rotate(30deg);を意味します。
さらに、transform-origin で指定された変換中心点は、移動変位には影響しません。移動変位は常に要素の中心を基準とします。懐疑的な場合は、自分で試してみてください。
変換スタイル
この属性は比較的単純で、値は flat と prepare-3d の 2 つだけです。ステージが 2D か 3D かを指定するために使用されます。デフォルト値の flat は 2D ステージを示し、すべてのサブ要素が 2D で表示されます。名前からわかるように、preserve-3d は 3D ステージを表し、すべてのサブ要素が 3D レベルで表示されます。このプロパティは、ステージを指定するために使用されるため、transform 要素自体に指定しても意味がありません。このプロパティは、transform 要素の親要素に設定します。設定すると、すべての子要素がステージを共有します。百聞は一見にしかず:
.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" /></div><div class="div1 p3d"><img src="head75.png" /></div>
また、transform-style:preserve-3d; と overflow:hidden; を同時に設定すると、transform-style: flat; と同等の 3D 効果が無効になります。 3D 効果が期待どおりに表示されない場合は、overflow: hidden; (祖先要素を含む) があるかどうかを確認できます。
視点
3D 表示距離を指定します。デフォルト値は none で、3D 効果、つまり 2D 平坦化がないことを意味します。この属性は、上記のコード例で実際に使用されています。導入する前に、rotateX/rotateY/rotateZを使ってxyz軸座標の基本概念を明確にしておきましょう。回転するには、百聞は一見に如かずです。 ターンテーブルは Z 軸を中心に回転します。上の Z 軸は単なる点ですが、実際にはその点は画面に垂直な線であり、透視視距離は画面からユーザーの目までの距離であることがわかります。3D を実現するための鍵は、視点の表示距離を設定することです。上記のコードの視点 (200px) を削除すると、次のような効果が得られます:
Z 軸の回転は影響を受けません。 xy 軸はまだ回転していますが、3D 効果は失われ、2D の平らな回転になります。その理由は、視点が設定されていない場合、デフォルト値はなしであり、視距離がなければ 3D は存在しないためです。
パースペクティブは % パーセンテージではなく、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" /></div><div class="divsp"><img class="z2" src="head75.png" /></div><div class="divsp"><img class="z3" src="head75.png" /></div><div class="divsp"><img class="z4" src="head75.png" /></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属性。两种指定方式是有区别的:
设置视距的基点,看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" /> <img class="image back" src="bg75.png" /> </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变形有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のシリーズに属し、要素の変換に使用されます。意味が異なっていても仕方ないと思うかもしれませんが、効果だけで十分ではないでしょうか。どのような基準で効果を測定するかによって異なります。 CSS の魅力は、コードの読みやすさに関係なく、本来の意図に完全に反する状況でもプロパティを使用できることです。本来の意図に反する場合には、微妙な違いが生じることがあります。アニメーション効果と組み合わせると、移動は 1px 未満で遷移できるため、アニメーション効果がよりスムーズになります。ただし、位置の最小単位は 1px なので、アニメーション効果は確実に損なわれます。さらに、translate を使用してアニメーションを実装すると、GPU を使用できるようになり、アニメーションの FPS が高くなりますが、位置では明らかにこの利点を享受できません。リフローやリドローなどのその他の機能にも違いがあります。したがって、translate を使用する必要がある位置で使用し、将来の需要の変更によって要件を満たせなくなっても、文句を言う必要はありません。
スケール スケーリング2D に使用されるスケール スケーリング シリーズは、scale、scaleX、scaleY です
スケール スケーリング、単精度および倍精度の値も設定できます。単一の値は、X 軸と Y 軸のスケーリングが等しいことを示します。デフォルト値は 1 です。縮小する場合は 0.01 ~ 0.99 の値を設定してください。拡大する場合は 1 を超える値を設定してください。たとえば、サイズを 2 倍にする場合は、transform:scale(.5); を使用でき、サイズを 2 倍にする場合は、transform:scale(2); を使用できます。この効果は、冒頭でtransform-originを紹介したときにすでに図に示されているので、詳細は説明しません。
X 軸のみをスケールしたい場合は、scale(.5, 1) と同等のscaleX(.5) を使用できます。同様に、Y 軸のみをスケールしたい場合は、scale(1, .5) と同等のscaleY(.5) を使用できます。
X 軸と Y 軸の不均等なスケーリングを実現するには、transform:scale(.5, 1.5); のように double 値を設定すると、元の 75*75px の画像が 37.5*112.5px になります。左に示すように:
w3cschool が言っていなかったのは、transform:scale(- のように、負の数値を最初に要素を反転してからスケーリングすることもできるということです。 5、-1.5);、その効果は上の右の図に示されています。なぜ逆転が起こるのか理解できましたか? XY 軸ピクセル マトリックスの各値を反転すると、その効果は反転と同等になります。もちろん、回転を使用して反転することもできます。
回転回転2D の回転回転シリーズには、次のものが含まれます: 回転
回転回転。これは比較的単純で、単一の値のみを設定できます。正の数値は時計回りの回転を表し、負の数値は反時計回りの回転を表します。たとえば、transform:rotate(30deg); の場合、その効果は、transform-origin が上部に導入されたときにすでに図に示されているため、詳細は説明しません。 (上記とは異なり、2D レベルには回転 X / 回転 Y がないことに注意してください。それらと回転 Z は両方とも 3D 回転です)
スキュー歪み2D に使用されるスキュー歪みシリーズは次のとおりです: skew、skewX、skewY
スキュー歪みは次のとおりです。個別の値と倍精度の値を設定します。単一の値は、X 軸のみがねじれ、Y 軸は変更されないことを意味します。たとえば、transform: skew(30deg); は、transform: skew(30deg, 0); と同等です。読みやすさを考慮すると、単一の値を使用することはお勧めできません。 Transform: skewX(30deg); skewY は、Y 軸のみがねじれ、X 軸は変化しないことを意味します。この効果は、冒頭でtransform-originを紹介したときにすでに図に示されているので、詳細は説明しません。
マトリックスマトリックスの前に直接の接触はありませんが、これがすべての 2D 変形の本質です。マトリックス マトリックスを使用すると、上記の 2D 変形エフェクトはすべて実現できます。この記事は今のところスキップし、3D マトリックス Matrix3d については次の記事に残しておきます。
3D 変形には、translate3d 変位、scale3d スケーリング、rotate3d 回転、matrix3d マトリックスが含まれます。 (スキュー歪みは 3D ではないことに注意してください)。 3D の使用法は 2D の使用法と似ていますが、Z 軸の値が追加される点が異なります (これはナンセンスではないでしょうか...)。
translation3d 変位3D に使用されるtranslate3d 変位シリーズは次のとおりです:translate3d、translateZ
translate3d(tx,ty,tz)。tz の Z 軸の長さは % パーセンテージではなく、px 値のみです。 translateZ は、translate3d(0,0,tz) と同等です。 Z軸の値が大きいほど目に近くなり、要素が大きくなりますが、透視距離よりも大きい値になると後ろが見えなくなり要素が消えてしまいます。これは上記の遠近法を紹介するときに導入されました。値が小さいほど、目から遠くなるほど要素が小さくなります。実際の使用では、translateZ エフェクトは 2D スケール スケーリング エフェクトと非常に似ていますが、translateZ は Z 軸の変位であり、scale は XY 軸のスケーリングです。繰り返しになりますが、属性に適した状況で属性を使用するようにしてください。
scale3d スケーリング3D に使用されるscale3d スケーリング シリーズは次のとおりです:scale3d、scaleZ
scale3d(sx,sy,sz)、sz は Z 軸のスケーリング比、値は 0.01 の間の sx、sy と同じです。および 0.99 1 の場合、要素のサイズは変わりません。1 より大きい場合、要素は大きくなります。 scaleZ は、scale(1,1,sz) と同等です。 3D ステージに影響を与えるには、scale3d またはscaleZ を単独で使用しても効果がないことに注意してください。そうしないと、Z 軸のスケーリング率をまったく定義できません。
rotate3d 回転rotate3d 3D で使用される回転系列は、rotate3d、回転角度、xyz の値は 0~1 で、各軸の回転ベクトル値です。 rotate3d、rotateX、rotateY、rotateZ の効果はすべて上に示されているため、詳細な説明は省略します。
matrix3d矩阵最后matrix3d矩阵是所有3D变形的本质,上面所有3D变形效果都可以用matrix3d矩阵来实现。本篇先略过,将它和上面的2D矩阵matrix留到下一篇再介绍。
现在来看看变形对CSS层级的影响。说起层级,absolute绝对是层级间的高富帅,见一个睡一个,sorry,是见一个压一个,sorry,是见一个覆盖一个。
//左图<img style="position:absolute;" src="bg100.png" /><img src="head75.png" />//右图<img style="position:absolute;" src="bg100.png" /><img style="transform:scale(1);" src="head75.png" />
左图因为第一张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会更深入其本质,看看这些变形函数究竟是如何变换坐标位置,显示出各种效果的。