CSS

えっ!?まだtransformプロパティを使ってるの!?translate・rotate・scaleを使おう

みんな独立したプロパティ使ってる。使ってないのお前だけ。

transformは与えられた要素に移動(translate)、拡大縮小(scale)、回転(rotate)、傾斜(skew)などの変形(transform)を適応させるCSSプロパティです。

transform: translate(-50%, -50%);で中央寄せ(現在ではあまり使用されないレガシーな手法です)といった静的な配置に用いることもありますが、主にCSSアニメーションを実装する際に使われることが多いです。

そのtransformプロパティの値のうち傾斜(skew)以外は現在では独立したプロパティで指定することができます。

/* 従来の書き方 */
.sample {
	transform: translateY(12px) rotate(90deg) scale(1.1);
}

/* 独立した書き方 */
.sample {
	translate: 0 12px;
	rotate: 90deg;
	scale: 1.1;
}

プロパティを独立させるとアニメーションの管理がしやすくなる

従来のtransformプロパティでは複数の値が指定された際、1つの値だけをアニメーションする場合にも他の値を重複して指定する必要がありました。

CodePenで見る

簡単なボタンのサンプルです。

ボタンのシェブロンをCSSで表現するとして、従来のtransformプロパティで実装するとしたらだいたい次のようなCSSコーディングになると思います。

.button {
	display: inline-grid;
	grid-template-columns: 1fr auto 1fr;
	gap: 1em;
	align-items: center;
	inline-size: min(100%, 25rem);
	padding-block: 1em;
	padding-inline: 1.5em; /* padding:1em 1.5em;は物理プロパティなので分けて記述 */
	color: var(--color-text);
	background-color: var(--background);
	border-radius: var(--rounded-sm);
	transition: background-color var(--duration);

	&::before {
		content: ''; /* テキストを通常時は中央寄せにしながら、テキストが多い場合は左寄せにするために必要 */
	}

	&::after {
		display: inline-block;
		justify-self: end;
		inline-size: 0.5em;
		aspect-ratio: 1;
		content: '';
		border-block-start: 1px solid;
		border-inline-end: 1px solid;
		transform: rotate(45deg);
	}

	&:any-link:focus-visible {
		background-color: var(--background-hover);
	}

	@media (any-hover: hover) {
		&:any-link:hover {
			background-color: var(--background-hover);
		}
	}
}

ここにホバー時はシェブロンを右側に4px移動させるという条件を追加したら、transformプロパティだと次のように本来書かなくてもいいようなrotate(45deg)を含む必要があります。

.button {
	&::after {
		transform: rotate(45deg);
		transition: transform var(--duration);
	}

	&:any-link:focus-visible::after {
		transform: translateX(4px) rotate(45deg);
	}

	@media (any-hover: hover) {
		&:any-link:hover::after {
			transform: translateX(4px) rotate(45deg);
		}
	}
}

一方独立したプロパティを使用すればrotate(45deg)を含まずにtranslateの値を変えるだけで実現できます。

.button {
	&::after {
		rotate: 45deg;
		transition: translate var(--duration);
	}

	&:any-link:focus-visible::after {
		translate: 4px;
	}

	@media (any-hover: hover) {
		&:any-link:hover::after {
			translate: 4px;
		}
	}
}

今回は簡単な例ですが、アニメーションが複雑になればなるほど従来のtransformプロパティでは管理がしにくくなるでしょう。

独立したプロパティのほうが簡潔に書ける

独立したプロパティのほうが短く簡潔にスタイリングできます。

/* これが */
.sample {
	transform: translateX(12px);
	transform: rotate(45deg);
	transform: scale(1.2);
}

/* こうなる */
.sample {
	translate: 12px;
	rotate: 45deg;
	scale: 1.2;
}

ただし、難点としてはtranslateにはY軸(あるいはZ軸)のみの記述、scaleにはX軸Y軸(あるいはZ軸)のみの記述は存在しないため、そういった場合はX軸Y軸の指定も追加しないといけません。

.sample {
	transform: translateY(100%);
	transform: scaleX(1.1);
	transform: scaleY(1.2);
}

/* 独立したプロパティ */
.sample {
	translate: 0 100%;
	scale: 1.1 1;
	scale: 1 1.2;
}

それでもtransformプロパティよりは短い記述で済むことが多いです。

傾斜(skew)には独立したプロパティが無い

他の値に比べるとマイナー感が否めないskewですが、残念ながら独立したプロパティはございません。

ただし、独立したプロパティとtransformプロパティは共存できるため、skewを指定する場合はtransformプロパティをそれ専用として扱うのがベターだと思います。

独立したプロパティは全モダンブラウザで対応済み

独立したプロパティは全モダンブラウザで対応されております。懸念のiOS Safariも 14.1 14.5 から導入されているので使用しても差し支えないでしょう。

独立した変形プロパティ(translate / rotate / scale)

広く利用可能 2025年2月から(新しく利用可能になったのは2022年8月)

執筆時点(2024年3月)は「新しく利用可能」でした

Chrome
104
Edge
104
Firefox
72
Safari
14.1
iOS Safari
14.5

web-features 3.44.0 のデータ

webstatus.dev で見る

iOS Safariは14.1からという誤りがありましたが、正しくは14.5からです。ご指摘いただきありがとうございます。

ちなみに記事執筆時点でChatGPTには「そんなプロパティは存在しない」と怒られるため、CSSのレビューをChatGPTで行う際は注意しましょう。