CSSで奥行のあるキューブを表現するための手順

<p data-height="265" data-theme-id="0" data-slug-hash="gQQWZg" data-default-tab="html,result" data-user="hamamoto_abc" data-pen-title="CSS- CUBE" class="codepen">See the Pen <a href="https://codepen.io/hamamoto_abc/pen/gQQWZg/">CSS- CUBE</a> by hamamoto_abc (<a href="https://codepen.io/hamamoto_abc">@hamamoto_abc</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
CSSで何かビジュアル的に面白そうな表現のものないかなと探していたのですが、ネット探すと以下のHPがあったので見てみたのですがなかなか凄いです！
　------------------------
　CSS3D！まるでWebGLのような3Dを超気軽に実装するCSS技
　https://dev.oro.com/posts/2017/09/design/css_3d/
　------------------------
コードも参照出来て非常に勉強になったのですが、解説までは書かれてないので私が勉強した内容を纏めてみました。

※ ここで記載するコードは上記HPの「サイコロ」を参考に勉強した内容を元に、私でも理解しやすいように変更してあるので上記HPのオリジナルのものとは違います。
#まずは、キューブの前後の面を用意。
<p data-height="265" data-theme-id="0" data-slug-hash="KrrvqV" data-default-tab="html,result" data-user="hamamoto_abc" data-pen-title="CSS-CUBE-1" class="codepen">See the Pen <a href="https://codepen.io/hamamoto_abc/pen/KrrvqV/">CSS-CUBE-1</a> by hamamoto_abc (<a href="https://codepen.io/hamamoto_abc">@hamamoto_abc</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
```html
<div class="cube">
	<div class="面">
		<div class="前">前</div>
		<div class="後">後</div>
	</div>
</div>
<div id="目印"></div>
<style>
.cube {
	position:absolute; top:100px; left:100px;
	font-size: 70px;
}
.cube>.面>* {
	position:absolute; top:0; left:0; width:100px; height:100px;
	border:10px double silver; border-radius:20px;
	background-color:yellow; opacity:0.3;
}
#目印 { position:absolute; top:0; left:0; width:100px; height:100px; background-color:black; opacity:0.1; }
</style>
```
「cube > 面 > 各面...」という形で用意します。のちにそれぞれ役割が出てきます。
※ x,y が100pxの位置をベースに組み立てるので #目印 はそのための確認用です。

この状態では "各面" は absolute になっているので基点(x,y=100px)に重複して表示されます。
#キューブの中心をイメージして、そこを基準に面を移動する。
<p data-height="265" data-theme-id="0" data-slug-hash="eQbOaQ" data-default-tab="html,result" data-user="hamamoto_abc" data-pen-title="CSS-CUBE2" class="codepen">See the Pen <a href="https://codepen.io/hamamoto_abc/pen/eQbOaQ/">CSS-CUBE2</a> by hamamoto_abc (<a href="https://codepen.io/hamamoto_abc">@hamamoto_abc</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
ここからは、頭の中にイメージを思い描くことが大事になってきます。
キューブを表現したいので、まず「前面」を手前に移動 translateZ(50px) して、「背面(後面)」は後方に移動 translateZ(-50px) してから裏返し180度回転 rotateY(180deg) します。

```css
.cube>.面 { perspective: 400px; }
.cube>.面>.前 { transform: translateZ( 50px);                 }
.cube>.面>.後 { transform: translateZ(-50px) rotateY(180deg); }
```

`perspective`は "視点" らしいです。視点の位置ですかね。離れて見るのか近くで見るのか。
近くで見ると空に伸びる巨大なスカイツリーでも、遠くからみると俯瞰してツリーの全体像が見えるという感じだと思います。

この値を小さくしていくと、どんどん近くから見るような感じで表現されるので見え方は巨大になっていきます。
`.前` は 50px 前方にあるので `perspective` をそれより小さくすると視点が`.前`を追い越してしまうので見えなくなります。
#上、下、左、右 の面を作る。
<p data-height="265" data-theme-id="0" data-slug-hash="yQGBdq" data-default-tab="html,result" data-user="hamamoto_abc" data-pen-title="CSS-CUBE-3" class="codepen">See the Pen <a href="https://codepen.io/hamamoto_abc/pen/yQGBdq/">CSS-CUBE-3</a> by hamamoto_abc (<a href="https://codepen.io/hamamoto_abc">@hamamoto_abc</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
```html
<div class="上">上</div>
<div class="下">下</div>
<div class="左">左</div>
<div class="右">右</div>
```
```css
.cube>.面>.上 { transform: translateY(-50px) rotateX(  90deg); }
.cube>.面>.下 { transform: translateY( 50px) rotateX( 270deg); }
.cube>.面>.左 { transform: translateX(-50px) rotateY( -90deg); }
.cube>.面>.右 { transform: translateX( 50px) rotateY(-270deg); }
```
上 ⇒ 上へ移動 translateY(-50px) して、上を向かせるために90度回転 rotateX(90deg) させる。
下 ⇒ 下へ移動して下向きにするために 270度回転させる。
左 ⇒ (省略)
右 ⇒ (省略)
#キューブを回転させよう！
```css
.cube>.面 {
	perspective: 400px;
	animation : xxx 10000ms linear infinite;
}
@keyframes xxx {
	  0% { transform: rotateX(  0deg) rotateY(  0deg); }
	100% { transform: rotateX(360deg) rotateY(360deg); }
}
```
上記のように追記するとついに動き出します！
基点(x,y=100px) から X軸中心に360度、Y軸中心にも360度回転しているので基点を中心に回転している感じです。

ただ、まぁヘンですよね。まだ 2D です。
※Edgeだともうこの時点でなぜか 3D みたいです。
<p data-height="265" data-theme-id="0" data-slug-hash="bQObXo" data-default-tab="html,result" data-user="hamamoto_abc" data-pen-title="CSS-CUBE-4" class="codepen">See the Pen <a href="https://codepen.io/hamamoto_abc/pen/bQObXo/">CSS-CUBE-4</a> by hamamoto_abc (<a href="https://codepen.io/hamamoto_abc">@hamamoto_abc</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
#3D にしよう！
<p data-height="265" data-theme-id="0" data-slug-hash="PxXobK" data-default-tab="html,result" data-user="hamamoto_abc" data-pen-title="CSS-CUBE-4.5" class="codepen">See the Pen <a href="https://codepen.io/hamamoto_abc/pen/PxXobK/">CSS-CUBE-4.5</a> by hamamoto_abc (<a href="https://codepen.io/hamamoto_abc">@hamamoto_abc</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
```css
.cube>.面 {
	perspective: 400px;
	transform-style: preserve-3d; /* <= これを追加 ★ */
	animation : xxx 10000ms linear infinite;
}
```
これでやっと奥行が出てきていい感じです。
でも、よく見ると微妙に変に歪んでますよね。

視点 `perspective` を一つ上にしてみましょう。

```css
.cube {
	position:absolute; top:100px; left:100px;
	font-size: 70px;
	perspective: 400px; /* <= をここに移動 ★ */
}
.cube>.面 {
	transform-style: preserve-3d;
	animation : xxx 10000ms linear infinite;
}
```
これでちゃんといい感じになりました。

なぜこれでうまくいくのかは、きちんと私が理解できていないのでうまく説明できないのですが、変更前の記述では animation でぐるぐる回る箇所が視点になっているので一緒に回って歪むのかな～？と思います。
<p data-height="265" data-theme-id="0" data-slug-hash="VVqwZv" data-default-tab="html,result" data-user="hamamoto_abc" data-pen-title="CSS-CUBE-5" class="codepen">See the Pen <a href="https://codepen.io/hamamoto_abc/pen/VVqwZv/">CSS-CUBE-5</a> by hamamoto_abc (<a href="https://codepen.io/hamamoto_abc">@hamamoto_abc</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
#回転の基点をキューブの中心に持ってくる。
基点(x,y=100px)を中心に回るので、現状ではキューブの左上を中心に回っています。
これをキューブの中心にしたいので、キューブ自体の位置を移動します。

```css
.cube>.面>* {
	position:absolute; top:-60px; left:-60px; /* <= -60px 移動 ★*/
	width:100px; height:100px;
	・・・
```
キューブの半径とborder-radiusの幅分で 50px+10px だけ移動して中央に持っていきます。
<p data-height="265" data-theme-id="0" data-slug-hash="gQQWZg" data-default-tab="html,result" data-user="hamamoto_abc" data-pen-title="CSS- CUBE" class="codepen">See the Pen <a href="https://codepen.io/hamamoto_abc/pen/gQQWZg/">CSS- CUBE</a> by hamamoto_abc (<a href="https://codepen.io/hamamoto_abc">@hamamoto_abc</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
#完成です！
どうでしょうか？
CSSだけでここまでできるというのは素晴らしいです。
CSSだしCPU負荷も低いし。

なーんて思ってたらそこまで低くはまだないようです。
ただ、一昨年に買った非力なKindle Fire 7インチ(2015年、第5世代)でも一応スムーズにくるくる回ってくれてますので素晴らしいですよね。

けっこう勉強になったし、面白かったです。