【JSは使わない】HTMLとCSSのみで動く変身ベルトを作る【画像も使わない】

## 成果物

[こちら](https://bu-kurokky.github.io/belt/)です。  
(クリックすると風車が回って再度クリックすると止まります&音は鳴りません。)

## きっかけ
「最近css書いてないなぁ…ブラウザも**IEがなくなって変数が使えるようになったり便利なの沢山増えたし**リハビリに何か作ってみるかぁ…」と、いつもの衝動があってなんとなしに作った感じです。

簡単に言うとscssじゃなくpureなcssで変数を使ってみたいと思っちゃったのがきっかけです。

## 無駄なこだわり&捨てたもの

cssのリハビリなので、以下の縛りプレーです。

- sass(scss)じゃなくcssで書く
- jsは使わない
- 画像(SVG)を使わない
- icon的なfontも使わない
- もちろん画像をbase64化したものも使わない
- cssの変数を使う
- 変数以外でも今まで使ったことのないものを使ってみる
- ブラウザの互換性は無視
- レスポンシブも考慮しない
- chromeでネスト使えるようになったけど今回は使わない(だったらscssでいい気がする)

## 説明1 マークアップ部分

まず、マークアップ部分ですが

```html
<body>
<label>
	<input type="checkbox" name="checkbox" value="1">
	<div id="belt"></div>
	<div id="base"></div>
	<div id="frames"><div id="typhoon"><div id="wings"></div></div></div>
	<div id="pins"></div>
	<div id="cover"></div>
	<div id="lights">
		<ul>
			<li></li><li></li><li></li><li></li><li></li><li></li><li></li>
		</ul>
	</div>
</label>
</body>
```

という、div厨(死語)全開のタグです。  
別にheaderとかmain、footerとか使ってそれっぽくしてもいいんですが、そもそもタグに対しての意味づけが不必要なので『ここは分割してまっせー』という意味でのdivでいいかなと。

ulタグは光のエフェクトの部分がリストじゃないは重々承知ですが、もう考えるのが面倒になり**速度重視とはいえdivにid書いていくのにいい加減飽きた**のと、そもそも「**空タグに何を求めてるんだ？**」という心のツッコミからどうでもよくなってきてました。


## 説明2 checkboxで擬似onclick

有名どころのtipsの1つですが、cssの「input:checked」を使えばcheckされた時だけcssを効かせることができるのでcheckedの時だけcssアニメーションするようにしています。
これによりJavascriptのonclickを使わなくてもインタラクティブにアニメーションを動かすことができるようになるわけです。[^1]
[^1]: できるとは言え本来であればform用のUI/UXとしての効果のためなので今回の使い方はよくないと思います。

```css
input:checked ~ * #typhoon{
	animation:henshin .5s ease-in 0s 1;
	animation:henshin .5s linear .5s infinite;
}

@keyframes henshin {
	0%   { transform: rotate(0deg); }
	100% { transform: rotate(360deg); }
}
```

## 説明3 土台(銀色)のところ

この部分が一番迷いました。 
clip-pathも考えたのですが**transformで縦横を引き伸ばしたものを45度回転させて、角丸を使って表現**しました。  
(何かもっといい実装方法あったと思いますが、ほぼ脳を通さず書いてるので最初に思いついた方法でやりました)

```css
#base{
	display:flex;
	height:var(--belt-height);
	width:var(--belt-height);
	transform:scale(1.2, 1) rotate(45deg) ;
	background-image: linear-gradient(90deg, rgba(233, 233, 233, 1), rgba(172, 172, 172, 1));
	border-radius:500px 90px;
	box-shadow: 10px 3px 0 1px rgba(0, 0, 0, 0.15);
	position:absolute;
}
```

ただ、この**transformのせいでabsoluteを使うことになってしまった**[^2]のでもっと考えてやればよかったと後悔しています。  
(今回のネタのようなのは別としてabsoluteを使いまくるのは忌避感が半端なく本当はbaseと並列ではなく中に入れていくようにしたかった…)

[^2]: transformを使うとその内部のものも全て影響を受けるので今回の場合はscaleとrotateしてしまうのです。


## 説明4 風車のところ

[conic-gradient](https://developer.mozilla.org/ja/docs/Web/CSS/gradient/conic-gradient)を初めて使いました。
以前に「円グラフで使えそうだな」とは思っていましたが、個人的にはsvgの方が好きなので「使うことないだろう…」と思っていたものです。

ただ、conic-gradientのおかげで**10年くらい前に流行したborderで三角を作る方法やclip-pathとpolygonを使わずに表現できた**[^3]ので今回一番恩恵を受けた箇所はここだと思っています。

[^3]: その割に銀色の部分の実装が前世代的+absolute使ってるのでどうなんだ？とは自分でも思います。

```css
#wings{
	background:repeating-conic-gradient(from 0deg, red 0deg 35deg, transparent 35deg 45deg);
	width:var(--typhoon-size);
	height:var(--typhoon-size);
	border-radius:50%;
	display:flex;
	align-items: center;
	justify-content:center;
}
```

## 説明5 光るエフェクト

[radial-gradient](https://developer.mozilla.org/ja/docs/Web/CSS/gradient/radial-gradient)で実装するか本当に迷いました。  
角丸の線が流れるようなエフェクトにしたかったので苦肉の策でlistで個別に表現することとなりました。
マークアップ部分の削減のためにbeforeやafterなどを使ってもいいかなぁとは思いましたが「**何個目がどんな感じのだっけ？**」みたいになるのが面倒だったのでそのままliを使いました。

## 説明6 ちょっとしたこだわり

風車の周りの黒い縁をbox-shadowのinsetと並列で使うことで奥行き感がでるようにしました。(微妙だけど)

```css
#frames:after{
	content:"";
	position:absolute;
	width:calc(var(--frames-size) - 85px);
	height:calc(var(--frames-size) - 85px);
	background:var(--frames-bg);
	border:1px solid #000;
	border-radius:50%;
	display:flex;
	align-items: center;
	justify-content:center;
	box-shadow:1px 1px 0 1px rgba(0, 0, 0, 0.4), inset 3px 3px rgba(0,0,0,0.8);
}
```

## まとめ
全体を通して、もっとちゃんと再現すべきだったとは思います…

cssに限らず私の場合「**ある程度使えていたのに暫く触ってないと1%ぐらいしか残ってない**」状態に陥るのでリハビリとしてやったのですが、**今回のは何のトレーニングにもなってない**ので「もっとちゃんとしたcssを書けるようにしておかなきゃなぁ」と反省し
ました
てません。
  
もちろん今回のようなネタは古くはtableタグを使ってファミコンのドット絵を表現したり、[cssでドラえもん](https://shopdd.jp/blog-entry-932.html)を作るみたいなネタも沢山ありましたが、個人的にはいつものように『作りたいもの?をリハビリ気分で作れた』のでよかったです。

「**HTMLとcssなんて簡単すぎる**」
「**時代はReactだ！vueだ！**」
「**まずは、yarnやnpmで環境構築してVSCで入力補完使って…**」

という方も多いと思いますが**環境構築も便利なIDE、JSも画像も必要のないpureなHTML1枚でなんちゃってインタラクティブな遊べるものが作れる**という話でした。