成果物
こちらです。
(クリックすると風車が回って再度クリックすると止まります&音は鳴りません。)
きっかけ
「最近css書いてないなぁ…ブラウザもIEがなくなって変数が使えるようになったり便利なの沢山増えたしリハビリに何か作ってみるかぁ…」と、いつもの衝動があってなんとなしに作った感じです。
簡単に言うとscssじゃなくpureなcssで変数を使ってみたいと思っちゃったのがきっかけです。
無駄なこだわり&捨てたもの
cssのリハビリなので、以下の縛りプレーです。
- sass(scss)じゃなくcssで書く
- jsは使わない
- 画像(SVG)を使わない
- icon的なfontも使わない
- もちろん画像をbase64化したものも使わない
- cssの変数を使う
- 変数以外でも今まで使ったことのないものを使ってみる
- ブラウザの互換性は無視
- レスポンシブも考慮しない
- chromeでネスト使えるようになったけど今回は使わない(だったらscssでいい気がする)
説明1 マークアップ部分
まず、マークアップ部分ですが
<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
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度回転させて、角丸を使って表現しました。
(何かもっといい実装方法あったと思いますが、ほぼ脳を通さず書いてるので最初に思いついた方法でやりました)
#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と並列ではなく中に入れていくようにしたかった…)
説明4 風車のところ
conic-gradientを初めて使いました。
以前に「円グラフで使えそうだな」とは思っていましたが、個人的にはsvgの方が好きなので「使うことないだろう…」と思っていたものです。
ただ、conic-gradientのおかげで10年くらい前に流行したborderで三角を作る方法やclip-pathとpolygonを使わずに表現できた3ので今回一番恩恵を受けた箇所はここだと思っています。
#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で実装するか本当に迷いました。
角丸の線が流れるようなエフェクトにしたかったので苦肉の策でlistで個別に表現することとなりました。
マークアップ部分の削減のためにbeforeやafterなどを使ってもいいかなぁとは思いましたが「何個目がどんな感じのだっけ?」みたいになるのが面倒だったのでそのままliを使いました。
説明6 ちょっとしたこだわり
風車の周りの黒い縁をbox-shadowのinsetと並列で使うことで奥行き感がでるようにしました。(微妙だけど)
#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でドラえもんを作るみたいなネタも沢山ありましたが、個人的にはいつものように『作りたいもの?をリハビリ気分で作れた』のでよかったです。
「HTMLとcssなんて簡単すぎる」
「時代はReactだ!vueだ!」
「まずは、yarnやnpmで環境構築してVSCで入力補完使って…」
という方も多いと思いますが環境構築も便利なIDE、JSも画像も必要のないpureなHTML1枚でなんちゃってインタラクティブな遊べるものが作れるという話でした。