「スマイルください」
笑顔を求めるその脅威は、突然私たちに襲い掛かる。
次の脅威はいつ、だれを襲うのか。予告なしに襲い掛かるその脅威から身を守り、被害を最小限に抑えるために、日頃から正しいスマイルの出し方を見につけておくことが重要である。
今回のスマイル
今回作るスマイルはこのようなスマイル で、原材料は CSS を使う。
また、本家スマイル1が極めて安価( 0 円)で、提供までの時間が短いことをリスペクトして、スマイルを作るにあたり、以下の規則を設け、遵守した。
- 使用する要素は 1 つまで
- 擬似要素は利用しないことが好ましい
- 所要時間は 1 時間以内
スマイル の作り方
HTML を書く
HTML は、上記の規則からnico-chan
クラスを付与したdiv
要素 1 つとした。
<div class="nico-chan"></div>
CSS を書く
まず、スマイル をパーツごとに分割すると、円と楕円のみで構成されていることがわかる。円や楕円は、radial-gradient
関数を使えば、描くことができる。
顔を描く
radial-gradient
関数を使って、顔の輪郭を作っていく(動作例)。良い感じ。
:root {
--canvas-size: 300px;
--face-inside-color: #ffcc4d;
--face-outline-color: #ffcc4d;
--face: radial-gradient(
circle,
var(--face-inside-color) 140px,
var(--face-outline-color) 141px,
var(--face-outline-color) 149px,
transparent 150px
)
no-repeat;
}
.nico-chan {
width: var(--canvas-size);
height: var(--canvas-size);
background: var(--face);
}
目を描く
次に、目を作っていく(動作例)。
:root {
--canvas-size: 300px;
--eye-size: 17px;
--eye: radial-gradient(
11px 15px,
#664500 calc(var(--eye-size) - 2px),
transparent var(--eye-size)
);
--left-eye-position: 50px -50px;
--right-eye-position: -50px -50px;
--left-eye: var(--eye) var(--left-eye-position) no-repeat;
--right-eye: var(--eye) var(--right-eye-position) no-repeat;
--eyes: var(--left-eye), var(--right-eye);
}
.nico-chan {
width: var(--canvas-size);
height: var(--canvas-size);
background: var(--eyes);
}
口を描く
次に、口を描く。これは、円の上に楕円を重ねれば良い感じに作れると思う(動作例)。
:root {
--canvas-size: 300px;
--face-inner-color: #ffcc4d;
--mouth-size: 35px;
--mouth-color: #664500;
--mouth-overlay: radial-gradient(
2px 1px,
var(--face-inner-color) 111px,
transparent 113px
)
0 -50px no-repeat;
--mouth: radial-gradient(var(--mouth-color) 90px, transparent 91px) 0 10px
no-repeat;
--teeth-size: 35px;
--teeth-color: #fff;
--teeth-overlay: radial-gradient(
350px 100px,
var(--mouth-color) 85px,
transparent 87px
)
0 -10px no-repeat;
--teeth: var(--teeth-overlay),
radial-gradient(80px 60px, var(--teeth-color) 80px, transparent 81px) 0 -15px
no-repeat;
}
.nico-chan {
width: var(--canvas-size);
height: var(--canvas-size);
background: var(--mouth-overlay), var(--teeth), var(--mouth);
}
作ったパーツを組み合わせる
上で作ったパーツを適当に組み合わせる。すると、 CSS は全体でこんな感じになる。ごちゃごちゃしていて読みにくいが、やっていることは円、楕円の作成と配置だけなので、それほど難しいことはしていない。
また、background-image
プロパティをコンマ区切りで適用するとき、最初に適用した値の結果が常に最前面に表示される2、という動作に注意しなければならない。
:root {
--canvas-size: 300px;
--face-inner-color: #ffcc4d;
--face-outline-color: #ffcc4d;
--face: radial-gradient(
circle,
var(--face-inner-color) 140px,
var(--face-outline-color) 141px,
var(--face-outline-color) 149px,
transparent 150px
)
no-repeat;
--eye-size: 17px;
--circle-eye: radial-gradient(
11px 15px,
#664500 calc(var(--eye-size) - 2px),
transparent var(--eye-size)
);
--left-eye-position: 50px -50px;
--right-eye-position: -50px -50px;
--left-eye: var(--circle-eye) var(--left-eye-position) no-repeat;
--right-eye: var(--circle-eye) var(--right-eye-position) no-repeat;
--eyes: var(--left-eye), var(--right-eye);
--mouth-size: 35px;
--mouth-color: #664500;
--mouth-overlay: radial-gradient(
2px 1px,
var(--face-inner-color) 111px,
transparent 113px
)
0 -50px no-repeat;
--mouth: radial-gradient(var(--mouth-color) 90px, transparent 91px) 0 10px
no-repeat;
--teeth-size: 35px;
--teeth-color: #fff;
--teeth-overlay: radial-gradient(
350px 100px,
var(--mouth-color) 85px,
transparent 87px
)
0 -10px no-repeat;
--teeth: var(--teeth-overlay),
radial-gradient(80px 60px, var(--teeth-color) 80px, transparent 81px) 0 -15px
no-repeat;
}
.nico-chan {
width: var(--canvas-size);
height: var(--canvas-size);
background: var(--eyes), var(--mouth-overlay), var(--teeth), var(--mouth),
var(--face);
}
完成
というわけで、完成したスマイルがこちら!
See the Pen Pure CSS Smiley Face by Hakaato (@hakaato) on CodePen.
まとめ
このスマイルを作るうえで使用したプロパティは、実質 3 つだけ(カスタムプロパティを除く)になった。このことからも、連続的な色の変化を様々な形状で表現できることは強力で、スタイルをより柔軟に適用できることがわかる。
また、CSS グラデーションはブラウザによって生成されるので、ズーム表示された場合も割りと綺麗に表示されるのも Good ポイント。
CSS の場合、グラデーションさえあれば、スマイルは作れるのだ。もし道端で、突然スマイルを求められても、慌てず冷静にグラデーションを駆使すれば良い。グッドラック。