なんか、CSS で色々描いてみた的なやつを見てたら自分も描いてみたくなったので、埼玉県民にはおなじみの鳥さんマスコット 「コバトン」 を HTML5 と CSS で描いてみるテスト。
単純に 空の div 要素を並べて CSS で整形して position: absolute; でもいいんですが、今回は CSS 無しの、HTML としてもある程度意味のわかる文書になるように、元の HTML も書いてみました。
あまり時間をかけずにとりあえずという感じで描いて、細かい検証とか、ソースコードのブラッシュアップとかしていませんので、絵としての再現度やソースコードは微妙なところも多々あります。また主要なブラウザの最新版ならほぼ問題なく表示できると思いますが、Chrome、Safari などでは顔がちょっと崩れていたり、IE は text-shadow が効いてなかったりと一部おかしい部分もありますが、その辺はご愛敬と言うことで。
ちなみにコバトンが浦和レッズバージョンなのは個人的な趣味の問題です…
実際に対応ブラウザ (Firefox 5 を使用) で見た状態がどうなるかというと、下記のようになります。
本当はボールの中の模様も HTML と CSS だけでなんとかしようかなと思ったんですが、面倒っぽいので今回はズルしてここだけ背景画像を使っています。あとはすべて HTML と CSS のみで描写し、画像は使っていません。
で、今回は前述の通り、文書構造もちゃんとしようということで、コバトン HTML のアウトラインを見ると、下記のような感じになります。
- HTML5 + CSS3 でコバトン (浦和レッズバージョン)
- コバトン 浦和レッズバージョン
- コバトンとは
- コバトンの顔
- コバトンの目
- コバトンのくちばし
- コバトンの左手
- コバトンの右手
- コバトンの胴体
- コバトンの上半身
- コバトンの下半身
- コバトンの尾っぽ
- コバトンの足
- サッカーボール
- コバトン 浦和レッズバージョン
デモページの CSS を切って見ていただければ、CSS 無効時でも一応、文書として成り立っているのがおわかりいただけるかと。具体的なソースコードはデモページのソースコードを見てもらうか、上記の zip ファイルの中身で確認できます。興味があればどうぞ。ちなみに、header 要素と footer 要素の使い方は遊びですよ…
と、以上なんですが、これで終わるのもなんですので、一応簡単に解説。
角丸 (border-radius) と変形 (transform)
この手のお絵かきシリーズで最も活用されるのが border-radius プロパティと transform プロパティでしょう。今回書いたソースも含めて、その簡単な解説をしてみようと思います。かいつまんでの解説で、説明を端折っている部分もありますので、詳しくは仕様書などをご参照ください。
border-radius の基本
角丸を表現する 「border-radius」 は CSS3 で新たに追加されたプロパティです。
基本的な記述方法は、4角の各コーナーに適用したい弧を持つ円の半径 (radius) を指定します。margin や padding プロパティなどと同様に、各コーナーごとに個別のプロパティで指定もできますし、まとめて記述するショートハンドも使えます。ショートハンドで指定する場合は、左上角から、時計回りに4箇所指定することになりますが、これは margin プロパティなどと考え方は同じですね。
各コーナー個別に指定する場合の記述は下記のようになります。
div { border-top-left-radius: 10px 15px; border-top-right-radius: 4em; border-bottom-right-radius: 20pt; border-bottom-left-radius: 10% 20%; }
各プロパティと適用場所の対応は下記のようになります。
なお、角に指定する円は真円だけでなく楕円も指定できるように、半径を x軸(水平)方向、y軸(垂直)方向で個別に指定できます。つまり、border-**-**-radius 各プロパティには 2つまで値を指定できます。先に書いた方が x軸方向の半径、後に書いた方が y軸方向の半径になります。1つしか値を書かなければ、xy軸ともにその値と解釈されます。
これをもっと簡単に書くには下記のように border-radius プロパティとショートハンドを使います。
div { border-radius: 2em 1em 4em 3em; border-radius: 20px 10px 30px / 40px 60px; }
「/」 を使う場合、まず x軸方向の半径を左上から時計回りで指定し、「/」 の後に今度は y軸方向の半径を同じく左上から時計回りに指定します。見た目複雑ですが、このルールを覚えてしまえばさほど難しくはないと思います。
上記の例のように、値を 4つ書かずに省略した場合、省略された角の、対角線上の角に指定されている値が適用されます。つまり、右下角の値を省略すれば、左上角と同じと解釈されます。具体的に書くと、
div { border-radius: 10px 15px; }
上記のように書いた場合、左上、右下が 10px、右上、左下が 15px で指定されたことになります。
ちなみに、border-radius プロパティは、現在の主要なブラウザの最新版はすべて正式に対応していますので、ベンダプレフィックス (-webkit- 等) は不要です。
今回のコバトンを描くのでも、ほぼすべての要素にこの border-radius プロパティを使用しています。例えば、顔周り (両目) だと下記のような使い方です。
#leftEye, #rightEye { width: 30px; height: 30px; border-radius: 50%; border: 3px solid #000; background-color: #fff; overflow: hidden; position:absolute; }
まず正方形を作っておいて、border-radius で 4角に 50% を指定すれば真円になります。
transform の基本
transform も border-radius プロパティ同様、CSS3 で新たに追加されたプロパティですが、要素に対して回転、拡大 / 縮小、ゆがみや移動などを指定可能です。(transform は 3D (z軸) も扱えますが今回は 2D で解説します)
transform プロパティには、いくつかの関数(ファンクション) が指定できます。例えば下記のようなファンクションが使えます。
- rotate() : 回転
- scale() : 拡大・縮小
- skew() : ゆがみ
- translate() : 移動
具体的には下記のように指定します。複数のファンクションを指定する場合はスペースで区切ります。下の例だと、div 要素を 「x軸(水平)方向に 80px、y軸(垂直)方向に 20px 移動し、x軸方向に 1.5倍 (拡大)、y軸方向に 0.8倍 (縮小)、さらに、時計回りに 45度回転させる」 という指定になります。
div { transform: translate(80px, 20px) scale(1.5, .8) rotate(45deg); }
なお、各変形の原点 (どこを中心に変形するか) はデフォルトでは要素の中心点になります。この原点は、transform-origin プロパティで指定することもできます。
div { transform: scale(1.5); transform-origin: 0 0; }
transform-origin プロパティがない場合の既定値は 「transform-origin: 50% 50%;」、つまり要素の中心になりますが、上の例のように指定すれば、原点が要素の 「左上端」 に移動し、そこを基準点にして transform プロパティが適用されます。
今回のコバトンだと、回転のみ使用しています。各パーツを水平状態で作っておいて、最後に各場所に合うように回転させ、配置という感じですね。例えば、左手全体は下記のように回転させています。
#kobatonLeftHand { top: 52px; left: 85px; -moz-transform: rotate(-10deg); -webkit-transform: rotate(-10deg); -o-transform: rotate(-10deg); -ms-transform: rotate(-10deg); transform: rotate(-10deg); }
実際には、左手も手羽元と手羽先 (なんか変な感じですが) に分かれていて、それも回転させてくっつけるという感じで肘 (?) が曲がっている状態を作ったりしています。マイナスの値を入れれば、反時計回りに回転します。
なお、transform にはベンダプレフィックスをつけていますが、これは各ブラウザが現時点では正式に対応していないためです。
まとめ
IE9 も text-shadow が未対応で適用されていなかったりするものの、それ以外はきちんと描写されててひと安心。Safari などで顔が崩れる、(というか Firefox 様と IE9 様は border-radius が指定された要素の overflow の処理を仕様書通りにやってくれてる) のは、もう一つ輪郭だけの要素を上に重ねたりすれば解決できそうな気もしますが今回は面倒なのでスルーしました。
たまにはこういうお遊びも面白いですね。