【CSS】独立したtranslate・rotate・scaleを別々にアニメーションさせてみる
要素を移動や回転させる際にtransform
でまとめて指定していましたが、translate
、rotate
、scale
が独立し、個別に指定できるようになりました。
それにより、@keyframes
を使わず「移動させた後に回転させる」といったアニメーションが簡単にできるようになりました。
これらのCSSプロパティは2022年8月にChromeが対応したことで、主要ブラウザすべてでサポートされたということになります。
CSSプロパティの使い方
個別に指定できるCSSプロパティはtranslate
、rotate
、scale
の3つです。
ただし、translateY
のような個別の軸に対する指定はできません。
/* transformを使う場合 */
transform: translate(10px, 20px, 30px) rotate(90deg) scale(1.2);
↓
/* 直接指定する場合 */
translate: 10px 20px 30px;
rotate: 90deg;
scale: 1.2;
値の指定は、以下のようになっています。
- 1つ:X軸とY軸に同じ指定
- 2つ:X軸とY軸に別の指定
- 3つ:X軸とY軸とZ軸に別の指定
transformと競合しない
これらのCSSプロパティは、transform
とは別の扱いになるので、回転を2回繰り返すアニメーションも簡単に実装できます。
transform: rotate(45deg);
rotate: 90deg;
/* 回転の1秒後に90度回転させる */
transition: transform 0.3s, rotate 0.3s 1s;
ただ競合しないが故に、打ち消す場合には同じプロパティを当てる必要があるということは頭に入れておいた方が良いでしょう。
.item {
transform: translateX(30px);
}
.item {
translate: 0 0; /* 打ち消せない */
transform: translateX(0); /* 打ち消せる */
}
実行される順序に注意
処理の順番は決まっており、記述の順序を入れ替えたとしてもtranslate
→rotate
→scale
の順に実行されます。
順番を指定したい場合は、従来通りtransform
を使うか、transform
と組み合わせる必要があります。
また組み合わせた場合、記述の順序関係なくtransform
の方が後で実行されるようでした。
/* この順序で実行したい */
.item {
transform: translateY(-50%) scaleY(0.6) rotate(45deg);
}
/* 同じ結果にならない */
.item {
transform: translateY(-50%) scaleY(0.6);
rotate: 45deg;
}
/* 同じ結果にならない */
.item {
translate: 0 -50%;
transform: scaleY(0.6);
rotate: 45deg;
}
/* 同じ結果になる */
.item {
transform: rotate(45deg);
translate: 0 -50%;
scale: 1 .6;
}
※上記コードは、擬似要素で「>」アイコンを作る際などによく使用されます。
このことからtranslate
→rotate
→scale
→transform
の順に処理されるということが分かりました。
個別にアニメーションしてみる
以下のハンバーガーボタンは、開く時は「上下に移動させてから回転」、閉じる時は「回転させてから上下に移動」させています。
\ touch me! /
要点を絞るために少し書き換えていますが、アイコン部分は以下のような指定になっています。
/* バー */
.bar::before {
translate: 0 -8px;
}
.bar::after {
translate: 0 8px;
}
/* オープン時のバー */
.is-active {
.bar::before {
translate: 0;
rotate: 45deg;
}
.bar::after {
translate: 0;
rotate: -45deg;
}
}
アニメーションは、移動と回転が逆の動きになるようtransition-delay
の値を入れ替えて遅延させています。
/* バー */
.bar::before,
.bar::after {
transition: translate .3s .3s rotate 0.3s;
}
/* オープン時のバー */
.is-active {
.bar::before,
.bar::after {
transition: translate .3s, rotate 0.3s .3s;
}
}
全体のコード
<button id="button">
<span class="bar"></span>
</button>
<script>
document.getElementById("button").addEventListener("click", function() {
this.classList.toggle("is-active");
});
</script>
#button {
margin-inline: auto;
}
#button {
display: grid;
place-items: center;
place-content: center;
width: 60px;
height: 60px;
background: #ddd;
border: none;
cursor: pointer;
z-index: 999;
}
/* バー */
.bar,
.bar::before,
.bar::after {
width: 25px;
height: 3px;
background-color: #333;
transition: background-color 0s .3s, translate .3s .3s, rotate 0.3s;
}
.bar {
display: grid;
&::before,
&::after {
content: "";
grid-area: 1 / 1;
}
&::before {
translate: 0 -8px;
}
&::after {
translate: 0 8px;
}
}
/* オープン時のバー */
.is-active {
.bar {
background-color: transparent;
&::before,
&::after {
transition: translate .3s, rotate 0.3s .3s;
}
&::before {
translate: 0;
rotate: 45deg;
}
&::after {
translate: 0;
rotate: -45deg;
}
}
}
まとめ:使い分けができる
transform
でまとめて指定するか、個別に指定するか、順序や使い方に注意しないといけませんが、別々にCSSプロパティとして扱えるようになったのは大きなメリットです。
ちょっとしたアニメーションで使いたい場合は、直感的に実装することができるので、積極的に使っていきたいですね。
おすすめWEBスクール
WEB制作やWEBデザインを学びたいなら、SNSでも話題の「デイトラ」がおすすめ!
どのコースも10万円前後と業界最安値で、副業や転職に向けて十分なスキルを身につけることができます。
\ クリックしてジャンプ! /
お気軽にコメントどうぞ