HTMLとCSSを使ったWEBサイトの実践的な作り方を紹介。

応用69.要素の移動、回転、変形(transform)

      2019/04/29   hatano

transformプロパティ

transformとは

指定した要素を2Dまたは3D的に、移動、回転、変形が行えるプロパティです。
transformプロパティの値は、関数で指定します。値(関数)は、半角スペースで区切ることで複数指定できます。

注意点

  • transformプロパティは見た目を変更しますが、指定した要素の元々の位置や領域は変化しません。これは、position: rerative; と似た状態で、周辺の要素の位置は変化しません。
  • displayプロパティの指定がない、またはdispalay: inline;の場合、transformは実行されません。a要素span要素before疑似要素after疑似要素などはdisplayの初期値がないので、transformプロパティを使用する場合はdispalayプロパティを設定してください。

各ブラウザの対応状況

2D、3Dでブラウザの対応状況が異なります。Internet Explorer10以上。Android Browser5以上であれば、すべて対応しています。
この章でのサンプルは、ベンダープレフィックスは付与していません。必要に応じてベンダープレフィックスを付与してください。

CSS3 2D Transforms

※Internet Explorer9以上から対応。
※ベンダープレフィックスの対応は下記の通りです。
-ms- … Internet Explorer9で必要。(10以降は不要)
-webkit- … Android Browser2~4.4.4で必要(5以降不要)

2D transformの各ブラウザの対応状況
Can I use -CSS3 2D Transforms-

CSS3 3D Transforms

※Internet Explorer10以上から対応。
※ベンダープレフィックスの対応は下記の通りです。
-webkit- … Android Browser3~4.4.4(5以降不要)

3D transformの各ブラウザの対応状況
Can I use -CSS3 3D Transforms-

translate - X軸、Y軸の移動(2D)

  • translateX(X軸の移動距離)
  • translateY(Y軸の移動距離)
  • translate(X軸の移動距離, Y軸の移動距離)

指定した対象をX軸、Y軸で2D移動します。
移動距離の単位は絶対値(px)相対値(%, emなど)どちらでも指定できます。値が整数の場合、X軸は右方向、Y軸は下方向に移動します。値が負(マイナス)の場合、逆方向に移動します。
translate()は、translateX()とtranslateY()を同時に指定できます。引数は、カンマで区切ります。

相対値は、指定した要素の幅、高さが基準ですので注意してください。例えば幅100pxの要素に対し、translateX(50%)を指定した場合、移動距離は50pxになります。
対象の移動は、positionプロパティでも可能ですが、CSSアニメーション(transitionプロパティ、Keyframe Animation)の場合、positonプロパティより滑らかな動きになります。

下記はtransitionを使った移動アニメーションのサンプルです。ホバーまたはタップで動作します。
※iOS Safaraiではタップで処理を実行する場合、ontouchstart=""が必要です。

translateX
translateY

<div class="translate-x" ontouchstart="">
	<div>translateX</div>
</div>
<div class="translate-y" ontouchstart="">
	<div>translateY</div>
</div>


.translate-x div, .translate-y div{
	transition: transform 0.4s;
	width: 100px;
	height: 100px;
	line-height: 100px;
	text-align: center;
	color: #fff;
}
.translate-x div{ background-color: #f00; }
.translate-x:hover div{ transform: translateX(100px); }
.translate-y div{ background-color: #00f; }
.translate-y:hover div{  transform: translateY(100px); }

translate - Z軸の移動(3D)

  • translate3d(X軸の移動距離, Y軸の移動距離, Z軸の移動距離)
  • translateZ(Z軸の移動距離)

指定した対象をZ軸で3D移動します。Z軸の移動は3Dとなるため、親要素に下記のプロパティを指定をしないと3Dの表示として機能しません。
transform-style: preserve-3d;
perspectiveプロパティ

Z軸の指定は、絶対値(px)のみです。相対値(%, emなど)は指定できません。値が整数の場合、Z軸は上に重なるように移動します。値が負(マイナス)定の場合、下に重なるように移動します。
translate3d()は、translateX()translateY()、translateZ()を同時に指定できます。引数は、カンマで区切ります。

下記は、transformを使った立方体のサンプルです。変形の基点は、各要素の上下左右中央で行っています。

front
back
left
right
top
bottom

<div class="translate-3d">
	<div class="front">front</div>
	<div class="back">back</div>
	<div class="left">left</div>
	<div class="right">right</div>
	<div class="top">top</div>
	<div class="bottom">bottom</div>
</div>


.translate-3d{
	transform-style: preserve-3d;
	perspective: 270px;
	position: relative;
	width: 100px;
	height: 100px;
}
.translate-3d div{
	position: absolute;
	top: 0;
	left: 0;
	margin-left: 100px;
	margin-top: 200px;
	width: 100px;
	height: 100px;
	line-height: 100px;
	text-align: center;
}
.front{
	background-color: rgba(236, 236, 53, 0.5);
}
.back{
	transform: translateZ(-100px);
	background-color: rgba(228, 228, 44, 0.5);
}
.left{
	background-color: rgba(214, 122, 157, 0.5);
	transform: translate3d(-50px, 0, -50px) rotateY(90deg);
}
.right{
	transform: translate3d(50px, 0, -50px) rotateY(-90deg);
	background-color: rgba(214, 122, 157, 0.5);
}
.top{
	transform: translate3d(0, -50px, -50px) rotateX(90deg);
	background-color: rgba(124, 114, 214, 0.5);
}
.bottom{
	transform: translate3d(0, 50px, -50px) rotateX(90deg);
	background-color: rgba(245, 238, 174, 0.5);
}

rotate - 回転(2D)

  • rotate(回転角度または回転数)

指定した対象を2D回転させます。
引数は、角度を表すdeg、回転数を表すturnを単位で指定します。値が整数の場合、時計回りに回転します。値が負(マイナス)の場合、反時計回りに回転します。
右回りに1回転
transform: rotate(1turn);
左回りに360度回転
transform: rotate(-360deg);

下記はtransitionを使った回転アニメーションのサンプルです。ホバーまたはタップで動作します。
※iOS Safaraiではタップで処理を実行する場合、ontouchstart=""が必要です。

rotation

<div class="rotation" ontouchstart="">rotation</div>


.rotation{
  transition: transform 1s;
  width: 100px;
  height: 100px;
  line-height: 100px;
  background-color: #ddd;
  text-align: center;
}
.rotation:hover{ transform: rotate(2turn); }

rotate - 回転(3D)

  • rotateX(X軸を基点とした回転角度または回転数)
  • rotateY(Y軸を基点とした回転角度または回転数)
  • rotateZ(Z軸を基点とした回転角度または回転数)

指定した対象を3D回転させます。 引数は、角度を表すdeg、回転数を表すturnを単位で指定します。値が整数の場合、時計回りに回転します。値が負(マイナス)の場合、反時計回りに回転します。
3Dのため、下記のプロパティの影響を受けます。
transform-styleプロパティ
perspectiveプロパティ
backface-visibilityプロパティ

rotateZ()は、transform-style: preserve-3d;perspectiveを使用しない場合、rotate()と同じ2D回転になります。またrotateZ()は、X軸、Y軸の指定も併用しないと、奥行きがでません。

下記はtransitionを使ったX軸回転アニメーションのサンプルです。ホバーまたはタップで動作します。.rotation-x2のみ、transform-style: preserve-3d;perspectiveを指定しています。
※iOS Safaraiではタップで処理を実行する場合、ontouchstart=""が必要です。

rotation-x1
rotation-x2

<div class="rotation-x1" ontouchstart="">
	<div>rotation-x1</div>
</div>
<div class="rotation-x2" ontouchstart="">
  <div>rotation-x2</div>
</div>


.rotation-x1,
.rotation-x2{
  width: 100px;
  height: 100px;
}
.rotation-x2{
  transform-style: preserve-3d;
  perspective: 150px;
}
.rotation-x1 div,
.rotation-x2 div{
  transition: transform 2s;
  width: 100px;
  height: 100px;
  line-height: 100px;
  background-color: #ddd;
  text-align: center;
}
.rotation-x1 div:hover,
.rotation-x2 div:hover{
  transform: rotateX(2turn);
}

下記はtransitionを使ったY軸回転アニメーションのサンプルです。ホバーまたはタップで動作します。.rotation-y2のみ、transform-style: preserve-3d;perspectiveを指定しています。
※iOS Safaraiではタップで処理を実行する場合、ontouchstart=""が必要です。

rotate-y1
rotate-y2

<div class="rotate-y1" ontouchstart="">
  <div>rotate-y1</div>
</div>
<div class="rotate-y2" ontouchstart="">
  <div>rotate-y2</div>
</div>


.rotate-y1,
.rotate-y2{
  width: 100px;
  height: 100px;
}
.rotate-y2{
  transform-style: preserve-3d;
  perspective: 150px;
}
.rotate-y1 div,
.rotate-y2 div{
  transition: transform 2s;
  width: 100px;
  height: 100px;
  line-height: 100px;
  background-color: #ddd;
  text-align: center;
}
.rotate-y1 div:hover,
.rotate-y2 div:hover{
  transform: rotateY(2turn);
}

下記はtransitionを使ったX軸、Y軸、Z軸を併用した回転アニメーションのサンプルです。ホバーまたはタップで動作します。
※iOS Safaraiではタップで処理を実行する場合、ontouchstart=""が必要です。

rotate-z1
rotate-z2

<div class="rotate-z1" ontouchstart="">
  <div>rotate-z1</div>
</div>
<div class="rotate-z2" ontouchstart="">
  <div>rotate-z2</div>
</div>


.rotate-z1,
.rotate-z2{
  width: 100px;
  height: 100px;
}
.rotate-z2{
  transform-style: preserve-3d;
  perspective: 100px;
}
.rotate-z1 div,
.rotate-z2 div{
  transition: transform 4s;
  width: 100px;
  height: 100px;
  line-height: 100px;
  background-color: #ddd;
  text-align: center;
}
.rotate-z1 div:hover,
.rotate-z2 div:hover{
  transform: rotateZ(2turn) rotateX(2turn) rotateY(2turn);
}

skew - 傾斜の値(2D)

  • skewX(X軸の傾斜角度)
  • skewY(Y軸の傾斜角度)
  • skew(X軸の傾斜角度, Y軸の傾斜角度)

指定した対象を2D傾斜させます。
引数は、角度を表すdegを単位で指定します。値が整数の場合、X軸は左方向に、Y軸は下方向に傾斜します。値が負(マイナス)の場合、反対方向に傾斜します。
skew()は、skewX()、skewY()を同時に指定できます。引数は、カンマで区切ります。

下記はtransitionを使った傾斜アニメーションのサンプルです。ホバーまたはタップで動作します。
※iOS Safaraiではタップで処理を実行する場合、ontouchstart=""が必要です。

skew-x
skew-y
skew-xy

<div class="skew-x" ontouchstart="">
  <div>skew-x</div>
</div>
<div class="skew-y" ontouchstart="">
  <div>skew-y</div>
</div>
<div class="skew-xy" ontouchstart="">
  <div>skew-xy</div>
</div>


.skew-x,
.skew-y,
.skew-xy{
  width: 100px;
  height: 100px;
  margin-bottom: 30px;
}
.skew-x div,
.skew-y div,
.skew-xy div{
  transition: transform 1s;
  width: 100px;
  height: 100px;
  line-height: 100px;
  background-color: #ddd;
  text-align: center;
}
.skew-x div:hover{ transform: skewX(30deg) }
.skew-y div:hover{ transform: skewY(30deg) }
.skew-xy div:hover{ transform: skew(30deg, 30deg) }

scale - 伸縮の値(2D)

  • scaleX(X軸での伸縮率)
  • scaleY(Y軸での伸縮率)
  • scale(X軸での伸縮率, Y軸での伸縮率)

指定した対象を2D伸縮させます。
引数には、伸縮率を100% = 1を基準に整数、浮動小数で指定します。単位はつけません。0.5の場合は、50%縮小。1.5の場合は150%拡大となります。
scale()は、scaleX()、scaleY()を同時に指定できます。引数は、カンマで区切ります。

相対値は、指定した要素の幅、高さが基準ですので注意してください。例えば幅100px、高さ50pxの要素に対し、scale(0.5, 0.5)を指定した場合、幅50px、高さ25pxに縮小します。

下記はtransitionを使った2D伸縮アニメーションのサンプルです。ホバーまたはタップで動作します。
※iOS Safaraiではタップで処理を実行する場合、ontouchstart=""が必要です。

scale-x
scale-y
scale-xy

<div class="scale-x" ontouchstart="">
  <div>scale-x</div>
</div>
<div class="scale-y" ontouchstart="">
  <div>scale-y</div>
</div>
<div class="scale-xy" ontouchstart="">
  <div>scale-xy</div>
</div>


.scale-x,
.scale-y,
.scale-xy{
  width: 100px;
  height: 100px;
}
.scale-x div,
.scale-y div,
.scale-xy div{
  transition: transform 1s;
  width: 100px;
  height: 100px;
  line-height: 100px;
  background-color: #ddd;
  text-align: center;
}
.scale-x div:hover{ transform: scaleX(0.5) }
.scale-y div:hover{ transform: scaleY(0.5) }
.scale-xy div:hover{ transform: scale(0.5, 0.5) }

scale - 伸縮の値(3D)

  • scaleZ(Z軸での伸縮率)
  • scale3d(X軸での伸縮率, Y軸での伸縮率, Z軸での伸縮率)

指定した対象を3D伸縮させます。
scale3d()は、scaleX()scaleY()、scaleZ()を同時に指定できます。引数は、カンマで区切ります。
3D伸縮の場合、奥行きがない状態だと変化がありません。translate()と同じ2D移動になります。3D伸縮を表現する場合は、3D回転transform-originperspectiveを併用します。また、親要素にtransform-style: preserve-3d;がない場合、親要素は2Dとして扱われます。 例えば、親要素にtransform-style: preserve-3d;がある場合、perspectiveのz軸に負の値をすると、親要素に子要素が食い込む形で表示されます。

下記はtransitionを使い、3D伸縮アニメーションのサンプルです。ホバーまたはタップで動作します。scale-z2には、transform-style: preserve-3d;を指定しています。
※iOS Safaraiではタップで処理を実行する場合、ontouchstart=""が必要です。

scale-z1
scale-z2

<div class="scale-z1" ontouchstart="">
  <div>scale-z1</div>
</div>
<div class="scale-z2" ontouchstart="">
  <div>scale-z2</div>
</div>


.scale-z1,
.scale-z2{
  perspective: 600px;
  width: 200px;
  height: 200px;
  margin-top: 50px;
  background-color: #ddd;
}
.scale-z2{ transform-style: preserve-3d; }
.scale-z1 div,
.scale-z2 div{
  transition: transform 1s;
  transform-origin: right top -200px;
  transform: rotateY(30deg);
  width: 100px;
  height: 100px;
  background-color: #f00;
}
.scale-z1:hover div,
.scale-z2:hover div{
  transform: rotateY(30deg) scaleZ(2);
}

transform-originプロパティ

transformプロパティを指定した要素の2Dまたは3Dの基点を指定するプロパティ。各値は、半角スペースで区切ります。
※Internet Explorerは、Z軸のみ未対応。
※ベンダープレフィックスは、Android Browser3~4.4.4に対応する場合、-webkit-が必要。

2Dの場合、X軸の位置、Y軸の位置の順に指定。
3Dの場合、X軸の位置、Y軸の位置、Z軸の距離の順に指定。
初期値は下記のようになり、要素の中央が基点となります。
transform-origin: 50% 50%; /* 2Dの初期値 */
transform-origin: 50% 50% 0; /* 3Dの初期値 */

X軸、Y軸の指定は、絶対値(px)または相対値(%,emなど)で指定します。Z軸の指定は、絶対値(px)のみです。相対値(%, emなど)は指定できません。X軸、Y軸のみキーワードの指定も可能です。

  • X軸…left・center・right
  • Y軸…top・center・bottom
  • Y軸…キーワード指定はありません。

下記はtransitionを使い、Y軸の3D回転を使った基点の違いのサンプルです。ホバーまたはタップで動作します。
※iOS Safaraiではタップで処理を実行する場合、ontouchstart=""が必要です。

default
left top
right top

<div class="default" ontouchstart="">
  <div>default</div>
</div>
<div class="left-top" ontouchstart="">
  <div>left top</div>
</div>
<div class="right-top" ontouchstart="">
  <div>right top</div>
</div>


.default,
.left-top,
.right-top{
  transform-style: preserve-3d;
  perspective: 270px;
  width: 100px;
  height: 100px;
  margin-left: 100px;
}
.default div,
.left-top div,
.right-top div{
  transition: transform 1s;
  width: 100px;
  height: 100px;
  line-height: 100px;
  background-color: #ddd;
  text-align: center;
}
.default:hover div,
.left-top:hover div,
.right-top:hover div{
  transform: rotateY(1turn);
}
.left-top div{ transform-origin: left top; }
.right-top div{ transform-origin: right top; }

backface-visibilityプロパティ

3Dの要素がユーザーに対して裏側を向いたときに、裏面を表示するかどうかを指定するプロパティ。
transform: rotateX(); transform: rotateY(); transform: rotateZ(); と併用します。
hiddenを指定した場合、裏側になった時に、何も表示されなくなります。
※Internet Explorer未対応。
※ベンダープレフィックスは、Android Browser3~4.4.4に対応する場合、-webkit-が必要。
※iOS safari9〜12で、hiddenを使用する場合、-webkit-が必要。

  • visible…表示(初期値)
  • hidden…非表示

下記はtransitionを使い、front-onlyのみhiddenを指定したサンプルです。ホバーまたはタップで動作します。
※iOS Safaraiではタップで処理を実行する場合、ontouchstart=""が必要です。

default
hidden

<div class="front-back" ontouchstart="">
  <div>default</div>
</div>
<div class="front-only" ontouchstart="">
  <div>hidden</div>
</div>


.front-back,
.front-only{
  width: 100px;
  height: 100px;
  transform-style: preserve-3d;
  perspective: 270px;
}
.front-back div,
.front-only div{
  transition: transform 2s;
  width: 100px;
  height: 100px;
  line-height: 100px;
  background-color: #ddd;
  text-align: center;
}
.front-only div{
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
}
.front-back:hover div,
.front-only:hover div{
  transform: rotateY(2turn);
  width: 100px;
  height: 100px;
  line-height: 100px;
  background-color: #ddd;
  text-align: center;
}

transform-styleプロパティ

3Dの子要素がある場合に、親要素にも奥行きを持つかを指定するプロパティ。3D transformを利用した場合に、親要素にpreserve-3dを指定します。
※Internet Explorerは未対応。
※ベンダープレフィックスは、Android Browser3~4.4.4に対応する場合、 -webkit-が必要。

  • flat…2Dとして扱う(初期値)
  • preserve-3d…3Dとして扱う

preserve-3dを指定しない場合、下記が正しく機能しません。

perspectiveプロパティ

3Dの要素の遠近感を演出します。値は、消失点からの距離をpxで指定します。1px以上の数値で指定します。負の値は指定できません。また小数点を含む数値の場合、表示が崩れる場合があります。消失点の位置は、transform-originプロパティで決定されます。
※Internet Explorerは未対応。
※ベンダープレフィックスは、Android Browser3~4.4.4に対応する場合、 -webkit-が必要。

下記は、.box1は消失点からの距離を1px、.box2は消失点からの距離を270pxで指定したサンプルです。

box1
box2

<div class="box1">
  <div class="front">box1</div>
  <div class="back"></div>
  <div class="left"></div>
  <div class="right"></div>
  <div class="top"></div>
  <div class="bottom"></div>
</div>

<div class="box2">
  <div class="front">box2</div>
  <div class="back"></div>
  <div class="left"></div>
  <div class="right"></div>
  <div class="top"></div>
  <div class="bottom"></div>
</div>


.box1,
.box2{
  transform-style: preserve-3d;
  position: relative;
  width: 100px;
  height: 100px;
  margin-bottom: 50px;
}
.box1{ perspective: 1px; }
.box2{ perspective: 270px; }
.box1 div,
.box2 div{
  position: absolute;
  top: 0;
  left: 0;
  margin-left: 100px;
  margin-top: 200px;
  width: 100px;
  height: 100px;
  line-height: 100px;
  text-align: center;
}
.front{
  background-color: rgba(236, 236, 53, 0.5);
}
.back{
  transform: translateZ(-100px);
  background-color: rgba(228, 228, 44, 0.5);
}
.left{
  background-color: rgba(214, 122, 157, 0.5);
  transform: translate3d(-50px, 0, -50px) rotateY(90deg);
}
.right{
  transform: translate3d(50px, 0, -50px) rotateY(-90deg);
  background-color: rgba(214, 122, 157, 0.5);
}
.top{
  transform: translate3d(0, -50px, -50px) rotateX(90deg);
  background-color: rgba(124, 114, 214, 0.5);
}
.bottom{
  transform: translate3d(0, 50px, -50px) rotateX(90deg);
  background-color: rgba(245, 238, 174, 0.5);
}

まとめ

  • transformプロパティは、移動、回転、傾斜、伸縮ができる
  • transformプロパティは、2Dと3Dの2種類に分類できる
  • Z軸の指定は、transform-styleプロパティとperspectiveプロパティの指定がないと正しく動作しない