- CSSでアニメーションをつけたいけど、コードの意味がいまいち理解できない…
- transformプロパティをあてたけど思うように効かない…
こんなお悩みありませんか?
初学者にとっては難しく感じるプロパティかもしれませんが、アニメーションを実装する場合、transformの理解は必須です…。
そこで今回はtransformプロパティの基礎的な使い方を解説!アニメーションサンプルも交えつつ、想定通りに効かない場合の対処パターンも紹介します!
基礎を理解するだけでも実装できる範囲がグッと広がります。
この記事を読んで、オシャレなWebサイトにも実装されているCSSアニメーションの基礎をおさえましょう!
transformとは
要素に「移動」「回転」「拡大・縮小」「傾斜」の動きを与えられるプロパティで、transformプロパティに対応した値で指定します。
要素は2D(縦横方向)変形だけでなく、3D(縦横奥行き方向)の変形も可能です。
ボタンにマウスカーソルを乗せたときや、JavaScriptでスクロールに連動させたときなど、要素を動かすアニメーションを実装する場合は高確率で採用されるプロパティです。
ブラウザ対応状況
古い情報だと、transformを使うためにベンダープレフィックスが記載されていることもありますが、モダンブラウザの対応状況から現時点でプレフィックス対応は不要と思っておいていいでしょう。
CSS3 2D Transforms 値一覧
効果 | 値名 | 指定する値 |
---|---|---|
移動 | translate 、translateX、translateY | 移動距離(px など) |
回転 | rotate | 角度(deg) |
拡大・縮小 | scale、scaleX、scaleY | 倍率(1や2 …など) |
傾き | skew、skewX、skewY | 角度(deg) |
縦や横など、平面方向への動きが再現されます。
CSS3 3D Transforms 値一覧
効果 | 値名 | |
---|---|---|
移動 | translateZ、translate3d | 移動距離(px など) |
回転 | rotateX、rotateY、rotateZ | 角度(deg) |
拡大・縮小 | scaleZ、scale3d | 倍率(1や2 …など) |
奥行き含めた3次元方向の動きが再現されます。skew(傾き)に3Dの動きはありません。
3Dのtransformを扱う場合、X・Y・Z軸のイメージを意識しておきましょう。
transformプロパティの値を解説
それぞれの書き方や、動きのイメージについて解説します。
transform: translate(移動)
translateは要素の表示位置を移動させられる値です。()内には動かす距離を指定します。
translateX()・translateY()
translateXはX方向、translateYはY方向に動きます。
/* X方向 */
transform: translateX(30px);
/* Y方向 */
transform: translateY(10px);
translate()
translate()はtranslateXとtranslateYのショートハンドです。
/* 値が一つ → X方向のみ */
transform: translate(10px);
/* 値が二つ → 一つ目がX方向・二つ目がY方向 */
transform: translate(30px , 10px);
値がひとつの場合はtranslateX、ふたつ指定する場合はカンマ( , )で区切って左側がX方向、右側がY方向になります。
上のCodePenのRunPenから動きを確認してみてください。
<div class="container">
<img class="transform-img" src="image.png" alt="">
</div>
.translate-container:hover img{
transform: translate(180px , 30px);
}
動きを与えているCSSは上の部分だけです。X方向に180px、Y方向に30px移動させています。
translateZ()
translateZは3D方向(奥行き)に要素が動くプロパティです。
/* Z方向 */
transform: translateZ(100px);
どういうことかはCodePenで確認してみてください。
三次元空間は現実同様、視点に近くなれば要素は大きく見え、遠くなれば小さく見えます。上の例では要素が手前方向に動き、連動して要素の大きさ(見た目)も自動的に変わっています。
このとき、translateZの値だけ指定しても効きません。
<div class="container">
<img class="transform-img" src="image.png" alt="">
</div>
.container {
height: 150px;
width: 300px;
perspective: 300px;
}
.container:hover .transform-img {
transform: translateZ(100px);
}
動かしたい要素の親要素に、奥行き方向の大きさ(視点からの距離)を作るため、perspectiveプロパティを指定します。
うえの場合、横300px・縦150px・奥行き300pxの立方体の箱を作り、その空間の中で手前に100px動かしているイメージです。
あとでも解説しますが、perspectiveプロパティは、奥行きのあるアニメーションに必要となるため、覚えておきましょう。
translate3d()
translate3dはtranslateX、translateY、translateZのショートハンドです。値はカンマ( , )で区切ります。
/* X方向 , Y方向 , Z方向 */
transform: translate3d(100px , -30px , -200px);
数値にマイナス( – )を指定すると、Xは左、Yは上、Zは奥に移動します。※translateZで説明した通り、親要素にはperspectiveプロパティで奥行き方向の距離を指定しています。
transform: rotate(回転)
rotateは要素を回転させられる値です。()内には回転させる角度を指定します。
rotate()
要素を平面方向に回転させる値です。
transform: rotate(360deg);
rotateで指定する値の単位はdegです。degは角度のことで、Degreeの略です。
時計回りに360度回転します。マイナス( – )指定すると反時計回りに角度が変わります。
rotateX()・rotateY()
Xは水平方向、Yは垂直方向の軸を基準に回転角度がつきます。
/* rotateX:水平方向の軸を基準に回転 */
transform: rotateX(360deg);
/* rotateY:垂直方向の軸を基準に回転 */
transform: rotateY(360deg);
rotateZ()
rotateZは3D方向(奥行き)方向の軸を基準に回転角度がつきます。
/* rotateZ:奥行き方向の軸を基準に回転 */
transform: rotateZ(360deg);
rotateZの場合、手前から奥方向に軸があるため、画像のように中心点が基準になります。
そのため、CodePenで見るとわかりますが、回転方向はrotateと同じ平面、時計回りに回転します。
rotateでZ軸方向に指定する場合、X方向とY方向セットで指定する必要があるため、次のrotate3dを使います。
rotate3d()
rotate3dはrotateX、rotateY、rotateZと回転角度のショートハンドです。値はカンマ( , )で区切ります。
/* X軸 , Y軸 , Z軸 , 回転角度 */
rotate3d(1 , 1 , 1 , 360deg);
※スマホからだとCodePenで上手く挙動しないかもしれないです…。
rotate3dの数値は他のtransformプロパティの値と異なり、それぞれのベクトル(数値は0か1)を指定し、4つ目に回転角度(deg)を記述します。
上ではX・Y・Zすべての方向にベクトルを設定しています。
rotate3d(1 , 1 , 0 , 360deg);
※スマホからだとCodePenで上手く挙動しないかもしれないです…。
0を指定した軸方向にはベクトルがなくなります。上のCodePenではZ方向だけ0指定しています。
動きを理解するには数学的な知識も必要で、理解するのはなかなか難しいですよね。
現実的には、視覚的に操作しながら動きがわかるジェネレータを使って数値を取得するのがいいでしょう。
transform: scale(拡大・縮小)
scaleは要素を拡大・縮小させられる値です。()内には伸縮させる倍率を指定します。
scaleX()・scaleY()
Xは水平方向、Yは垂直方向に伸縮します。
/* scaleX:水平方向に拡大・縮小 */
transform: scaleX(1.5);
/* scaleY:垂直方向に拡大・縮小 */
transform: scaleY(1.5);
値は単位をつけない数値で、倍率を指定します。
transform: scaleY(-1.5);
マイナス( – )指定すると逆方向に伸縮します。
回転しているようにも見えますが、0で軸方向に縮小したのち、反転して拡大(縮小)しています。
scale()
scale()はscaleXとscaleYのショートハンドです。
/* 値が一つ → X・Y軸の伸縮倍率 */
transform: skew(2);
/* 値が二つ → X軸の伸縮倍率 , Y軸の伸縮倍率 */
transform: scale(0.7 , 1.3);
値をカンマ( , )で区切り、左側X方向・右側Y方向の伸縮倍率を指定します。
値を一つしか指定しなかった場合、X軸のみの指定となりますが、Y軸の伸縮倍率にも同じ値が適用されるため、scale(2)はscale(2,2)と同じ指定になります。
scaleZ()
scaleZは3D方向(奥行き)に要素が伸縮するプロパティです。
/* Z軸の伸縮倍率 */
transform: scaleZ(1.3);
CodePenで挙動を見ても、transformが効いてないですよね。
この理由は、平面(2D)にたいし、Z軸方向(手前や奥方向)だけ指定をしても、見た目上変化は与えらない(効果自体がない)からです。
奥行き方向に拡大縮小の変化を与えるには、X方向やY方向とセットで指定する必要があるため、次のscale3d()を使います。
scale3d()
scale3dはscaleX、scaleY、scaleZのショートハンドです。値はカンマ( , )で区切ります。
/* X軸の伸縮倍率 , Y軸の伸縮倍率 , Z軸の伸縮倍率 */
transform: scale3d(1.5 , 1.5 , -5);
注意点として、Z軸方向の動きを与えるためには、他のtransformプロパティで3D方向の値を指定しておかないと効きません。
初期状態rotateY(45deg)で傾けています。
/* 親要素:奥行きの大きさ(視点からの距離) */
.container {
perspective: 200px;
}
/* アニメーション要素:初期値としてY軸(縦)を基準に45度回転 */
.transform-img {
transform: rotateY(45deg);
}
/* X方向1.5、Y方向1.5、Z方向に-5 */
.container:hover .transform-img {
transform: scale3d(1.5 , 1.5 , -5);
}
ちなみに、scaleZの値を初期値「1」にした場合、奥行き方向は変化しないため、下の画像のような動きになります。
transform: skew(傾斜)
skewは要素を傾斜させられる値です。()内には傾ける角度を指定します。
skewX()・skewY()
Xは水平方向、Yは垂直方向に要素が傾斜します。
/* skewX:水平方向に拡大・縮小 */
transform: skewX(-30deg);
/* skewY:垂直方向に拡大・縮小 */
transform: skewY(30deg);
指定する数値は角度なので、rotateと同じく単位はdegで指定します。
skew()
skew()はskewXとskewYのショートハンドです。
/* 値が一つ → X方向のみ */
transform: skew(10deg);
/* 値が二つ → X方向の傾き , Y方向の傾き */
transform: skew(10deg , 45deg);
値はカンマ( , )で区切ります。値を一つしか指定しない場合、X方向のみ指定したことになります。
transformプロパティで3D変形させる時のポイント
perspectiveプロパティ
perspectiveプロパティは、translate3dやscale3dなど、3Dアニメーションで必要なプロパティ。
上でも何度か触れましたが、奥行き方向の距離(視点からの距離)を指定します。
<div class="container">
<div class="animation"></div>
</div>
.container {
perspective: 300px;
}
.animation {
transform: translateZ(100px);
}
奥行きのあるアニメーションを指定する場合、動かす要素の親要素に記述し、3Dの領域を確保する必要があります。
perspective-originプロパティ
perspective-originは、perspectiveプロパティで指定した、奥行き方向に対する視点を変えるプロパティです。
/* 中心基準の視点で見る */
perspective-origin: center center;
/* 左上基準の視点で見る */
perspective-origin: left top;
/* 左側から全体と、上からの視点で見る */
perspective-origin: 100% 0;
()内にはXとYの基準位置をカンマ区切りで指定します。初期値は(center , center)で、要素の中心が基準位置となっています。
動画ではY軸の視点を変化させています。値は名詞だけでなく、「50%」など数値%で指定することもできます。
transform-styleプロパティ
transform-styleは、動かす要素に指定することで、2D表示と3D表示を切り替えるプロパティです。
それぞれ指定したグレー背景は、50%透過させています。
rotateX-2Dのほうは、Z軸方向に形としては傾いて見えますが、グレー背景の上・平面状で形が変わっているだけです。
rotateX-3Dのほうは、視点から遠い位置に傾いた際、平面の背景を透過して奥側に傾いているような表示(3D表示)になっているのがわかるかと思います。
flat(2D)
transform-style: flat;
flatは初期値ですので指定する必要はありません。3D方向に変形して見えても、表示としては平面上(2D)で処理されます。
preserve-3d(3D)
transform-style: preserve-3d;
preserve-3dは、要素がアニメーションする際に3Dとして表示されます。
transformの値(効果)を複数指定する場合
transform: translateX(30px) rotate3d(1 , 1 , 0 , 360deg) scale(1.3) skewX(20deg);
transformの各値を同時に指定する場合、半角スペースを空けながらそれぞれ記述します。
- translateXで右側に30px移動
- rotate3dでXY軸方向に360度回転
- scaleで縦横1.3倍に拡大
- skewXでX軸方向に20度傾ける
上の例だと4つのアニメーションを同時に指定しています。
CSS transformを使ったアニメーションサンプル
ここではよく見るアニメーションのサンプルを紹介します。
<div class="container">
<img class="transform-img" src="image.png" alt="">
</div>
回転しながら移動
.container:hover .transform-img {
transform: translateX(70vw) rotate(720deg);
}
translateXで右方向に移動させる距離を指定し、rotateで720度回転させています。
ゆらゆらと動く
/* transform要素 */
.transform-img {
animation: shake 3s both infinite;
}
@keyframes shake {
0% {
transform: translateX(0%);
transform-origin: 50% 50%;
}
15% {
transform: translateX(-20px) rotate(-6deg);
}
30% {
transform: translateX(20px) rotate(6deg);
}
45% {
transform: translateX(-15px) rotate(-3.6deg);
}
60% {
transform: translateX(9px) rotate(2.4deg);
}
75% {
transform: translateX(-15px) rotate(-3.6deg);
}
100% {
transform: translateX(0%);
transform-origin: 50% 50%;
}
}
animationプロパティと組み合わせています。
translateXとrotate、それぞれマイナスからプラス方向に動かすことで、揺れのアニメーションを再現しています。
ぽよんと弾む
/* transform要素 */
.transform-img {
animation: bounce 2s both infinite;
}
@keyframes bounce {
0% {
transform: translate(0, -150px) scale(1, 1);
}
10% {
transform: translate(0, 10px) scale(1.1, 1) ;
}
15% {
transform: translate(0, 10px) scale(.9, .9);
}
30% {
transform: translate(0, 20px) scale(1.3, .8) ;
}
50% {
transform: translate(0, -20px) scale(.8, 1.3) ;
}
70% {
transform: translate(0, 10px) scale(1.1, .9) ;
}
100% {
transform: translate(0, 0) scale(1, 1);
}
}
弾力感をだすため、translateで上下の動き、scaleで伸縮をさせています。
transformが効かない場合
transformのルールを理解していないと、思うように効かせられないことも多いです。
ここではよくあるケースの解決方法をまとめておきます。
インラインレベルの要素に指定している
<span class="transform-inline">spanタグのテキスト</span>
.transform-inline {
background-color: #2188b6;
padding: 20px;
transition: transform 1.5s;
}
.transform-inline:hover {
cursor: pointer;
transform: translate(50px , 50px);
}
spanタグなどインラインレベルの要素にはtransformが効きません。そのため、うえのコードではアニメーションが実行されないです。
適用させるには、inline以外のdisplayプロパティを適用させる必要があります。
CodePenの①は加工なし、②はinline-blockの値を付与しており、②のほうだけホバー(タップ)するとtranslateが効くのがわかります。
inline以外であればいいので、FlexBoxでフレックスアイテム化している要素にもtransformは効きます。
値をまとめず記載している
画像のように、右側に100pxの移動と、1.5倍の拡大変化を期待して、
.transform-selector {
transform: translateX(100px);
transform: scale(1.5);
}
うえのようなコードを書いたとしても、
実際は画像のように拡大(scale)しか適用されません。
これは、プロパティを分けて記述すると、下に書かれたtransformの値しか適用されない仕様だからです。
.transform-selector {
transform: translateX(100px) scale(1.5);
}
上でも解説したとおり、値(効果)を複数適用させる場合、transformプロパティにまとめて空白スペース区切りで指定すれば解決します。
まとめ
transformプロパティも、基礎的なルールを把握しておけば難しくありません。
効果 | 値名 | 指定する値 |
---|---|---|
移動 | translate 、translateX、translateY、translateZ、translate3d | 移動距離(px など) |
回転 | rotate、rotateX、rotateY、rotateZ | 角度(deg) |
拡大・縮小 | scale、scaleX、scaleY、scaleZ、scale3d | 倍率(1や2 …など) |
傾き | skew、skewX、skewY | 角度(deg) |
慣れない内は当記事をブックマークして、必要なときにチェックしてもらえると嬉しいです!
CSSアニメーションを実装するには、「transitionプロパティ」と「animationプロパティ」、セットで使われることが多いので、こちらの記事もあわせてご覧ください!