【CSS】独立したtranslate・rotate・scaleを別々にアニメーションさせてみる

【CSS】独立したtranslate・rotate・scaleを別々にアニメーションさせてみる

要素を移動や回転させる際にtransformでまとめて指定していましたが、translaterotatescaleが独立し、個別に指定できるようになりました。

それにより、@keyframesを使わず「移動させた後に回転させる」といったアニメーションが簡単にできるようになりました。

これらのCSSプロパティは2022年8月にChromeが対応したことで、主要ブラウザすべてでサポートされたということになります。

目次

CSSプロパティの使い方

個別に指定できるCSSプロパティはtranslaterotatescaleの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); /* 打ち消せる */
}

実行される順序に注意

処理の順番は決まっており、記述の順序を入れ替えたとしてもtranslaterotatescaleの順に実行されます。

順番を指定したい場合は、従来通り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;
}

※上記コードは、擬似要素で「>」アイコンを作る際などによく使用されます。

このことからtranslaterotatescaletransformの順に処理されるということが分かりました。

個別にアニメーションしてみる

以下のハンバーガーボタンは、開く時は「上下に移動させてから回転」、閉じる時は「回転させてから上下に移動」させています。

\ 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万円前後と業界最安値で、副業や転職に向けて十分なスキルを身につけることができます。

役に立ったら他の方にシェア

お気軽にコメントどうぞ

コメントする

目次