こんにちは。 Tokyo Otaku ModeのUXデザイナーおよびフロントエンドエンジニアの吉見です。
みなさんCSSは好きですか? 先日弊社のロゴを眺めているとCSSだけでも表現できそうだなと思い、実装してみた話をしたいと思います。
HTMLの準備 描画のためだけのDIVを大量生産して実装していくだけではおもしろくないので、ある程度制約を設けたいと思います。 Tokyo Otaku Modeという1字1字をそれぞれ i
タグにし、 T
は data-tom="t"
、O
は data-tom="o"
といった具合に独自data-属性を持ったDOMで構成してみます。 出来上がったソースが下記のようなHTMLです。※ 一部Safariではデモが動作しない可能性があります。ChromeまたはFirefoxでご覧ください。
index.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <div id="tokyootakumode"> <i data-tom="t"></i> <i data-tom="o"></i> <i data-tom="k"></i> <i data-tom="y"></i> <i data-tom="o"></i> <i data-tom="o"></i> <i data-tom="t"></i> <i data-tom="a"></i> <i data-tom="k"></i> <i data-tom="u"></i> <i data-tom="m"></i> <i data-tom="o"></i> <i data-tom="d"></i> <i data-tom="e"></i> </div>
このHTMLにスタイルシートを適用してTokyo Otaku Modeロゴを仕上げていきます。 そこで出来たのが下記です。
できました! 、、、が! E
の最後の一本が1つのDOMだけでは擬似要素を使っても1本付け足すことができず残念な結果に。。
というわけで、残念ですが E
にだけ子要素を加えて再挑戦しますよ。
index.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <div id="tokyootakumode"> <i data-tom="t"></i> <i data-tom="o"></i> <i data-tom="k"></i> <i data-tom="y"></i> <i data-tom="o"></i> <i data-tom="o"></i> <i data-tom="t"></i> <i data-tom="a"></i> <i data-tom="k"></i> <i data-tom="u"></i> <i data-tom="m"></i> <i data-tom="o"></i> <i data-tom="d"></i> <i data-tom="e"><span></span></i> </div>
完成しました。 ちょっとこれだけではわかりにくいですが、上記のHTMLソースにCSSだけで弊社のロゴを再現しています。 CSSは少し長いですが、下記のようなスタイルを施しています。
tokyootakumode.css
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 #tokyootakumode { position: relative; width: 100%; height: 100%; box-sizing: border-box; color: #000;} #tokyootakumode:before, #tokyootakumode:after { color: #000;} #tokyootakumode > * { position: absolute; box-sizing: border-box; z-index: 2;} #tokyootakumode [data-tom="t"] { background-color: #000; width: 1.3rem; height: 3.6rem;} #tokyootakumode [data-tom="t"]:before { position: absolute; content: ''; background-color: #000; width: 4.2rem; height: 1.3rem; left: -1.9rem; top: -1.2rem; transform: skew(-45deg);} #tokyootakumode [data-tom="t"]:nth-child(1) { left: calc(50% - 10.3rem); top: calc(50% - 8.8rem);} #tokyootakumode [data-tom="t"]:nth-child(7) { left: calc(50% - 4.7rem); top: calc(50% - 2.4rem);} #tokyootakumode [data-tom="t"]:nth-child(7):before { left: -0.8rem; top: -1.2rem;} #tokyootakumode [data-tom="o"] { border-style: solid; border-width: 1.9rem; border-radius: 50%; z-index: 1;} #tokyootakumode [data-tom="o"]:nth-child(2) { border-color: #09a1e5; width: 7.2rem; height: 7.2rem; left: calc(50% - 9.2rem); top: calc(50% - 11.2rem);} #tokyootakumode [data-tom="o"]:nth-child(5) { border-color: #e22422; border-width: 1.9rem; width: 7.5rem; height: 7.5rem; left: calc(50% + 2.6rem); top: calc(50% - 10.1rem);} #tokyootakumode [data-tom="o"]:nth-child(6) { border-color: #90c132; border-width: 1.5rem; width: 6rem; height: 6rem; left: calc(50% - 11.1rem); top: calc(50% - 4.2rem);} #tokyootakumode [data-tom="o"]:nth-child(12) { border-color: #fbce2c; width: 7.4rem; height: 7.4rem; left: calc(50% - 7.1rem); top: calc(50% + 0.1rem);} #tokyootakumode [data-tom="k"] { border-right: 1.3rem solid #000; border-top: 1.3rem solid transparent; width: 0; height: 4.8rem;} #tokyootakumode [data-tom="k"]:before { position: absolute; content: ''; border-right: 1.3rem solid #000; border-top: 1.3rem solid transparent; width: 0; height: 4rem; left: 1.7rem; top: -2.5rem; transform: rotate(45deg);} #tokyootakumode [data-tom="k"]:after { position: absolute; content: ''; border-bottom: 1.3rem solid #000; border-right: 1.3rem solid transparent; width: 2rem; height: 0; left: 1.5rem; top: 1.5rem; transform: rotate(45deg);} #tokyootakumode [data-tom="k"]:nth-child(3) { left: calc(50% - 3rem); top: calc(50% - 10rem);} #tokyootakumode [data-tom="k"]:nth-child(9) { left: calc(50% + 1.9rem); top: calc(50% - 3.6rem);} #tokyootakumode [data-tom="y"] { border-right: 1.3rem solid #000; border-top: 1.3rem solid transparent; width: 0; height: 3.3rem; left: calc(50% + 1rem); top: calc(50% - 10rem);} #tokyootakumode [data-tom="y"]:before { position: absolute; content: ''; border-bottom: 1.3rem solid #000; border-right: 1.3rem solid transparent; width: 9.1rem; height: 0; left: -4.4rem; top: 1.3rem; transform: rotate(-44deg);} #tokyootakumode [data-tom="a"] { background-color: #000; width: 1.3rem; height: 4.9rem; left: calc(50% + 0.1rem); top: calc(50% - 3.6rem);} #tokyootakumode [data-tom="a"]:before { position: absolute; content: ''; border-bottom: 1.3rem solid #000; border-left: 1.3rem solid transparent; width: 4.4rem; height: 0; left: -4.5rem; top: 1.8rem; transform: rotate(-45deg);} #tokyootakumode [data-tom="a"]:after { position: absolute; content: ''; border-bottom: 1.3rem solid #000; border-left: 1.3rem solid transparent; width: 1.5rem; height: 0; left: -2.3rem; top: 3rem;} #tokyootakumode [data-tom="u"] { border: 1.3rem solid #000; border-top: none; border-radius: 0 0 5rem 5rem; width: 4rem; height: 3.6rem; left: calc(50% + 6rem); top: calc(50% - 2.2rem);} #tokyootakumode [data-tom="u"]:before { position: absolute; content: ''; width: 0; height: 0.2rem; left: -1.3rem; top: -1.3rem; border-right: 1.3rem solid #000; border-top: 1.3rem solid transparent;} #tokyootakumode [data-tom="u"]:after { position: absolute; content: ''; background-color: #000; width: 1.3rem; height: 1.3rem; left: 1.4rem; top: -1.3rem;} #tokyootakumode [data-tom="m"] { border-right: 1.3rem solid #000; border-top: 1.3rem solid transparent; width: 0; height: 4.4rem; left: calc(50% - 7.5rem); top: calc(50% + 1.8rem);} #tokyootakumode [data-tom="m"]:before { position: absolute; content: ''; border-bottom: 1.7rem solid #000; width: 4.7rem; height: 0; left: -5.5rem; top: 0.9rem; transform: skewY(-45deg);} #tokyootakumode [data-tom="m"]:after { position: absolute; content: ''; border-left: 1.1rem solid #000; border-bottom: 1.3rem solid #000; width: 2rem; height: 2.2rem; left: -1.8rem; top: -2rem; transform: skewY(-45deg);} #tokyootakumode [data-tom="d"] { border-right: 1.3rem solid #000; border-top: 1.3rem solid transparent; width: 0; height: 4.6rem; left: calc(50% - 1.1rem); top: calc(50% + 1.6rem);} #tokyootakumode [data-tom="d"]:before { position: absolute; content: ''; background-color: #000; width: 0.4rem; height: 1.3rem; left: 1.2rem; top: -1.2rem;} #tokyootakumode [data-tom="d"]:after { position: absolute; content: ''; border: 1.3rem solid #000; border-left: none; border-radius: 0 5rem 5rem 0; width: 1.3rem; height: 1.9rem; left: 1.5rem; top: -1.2rem;} #tokyootakumode [data-tom="e"] { border-right: 1.3rem solid #000; border-top: 1.3rem solid transparent; width: 0; height: 4.6rem; left: calc(50% + 3.1rem); top: calc(50% + 1.6rem);} #tokyootakumode [data-tom="e"]:before { position: absolute; content: ''; border-top: 1.2rem solid #000; border-right: 1.2rem solid transparent; width: 7.3rem; height: 0; left: 1.2rem; top: -1.2rem;} #tokyootakumode [data-tom="e"]:after { position: absolute; content: ''; border-top: 1.2rem solid #000; border-right: 1.2rem solid transparent; width: 4.6rem; height: 0; left: 1.2rem; top: 0.4rem;} #tokyootakumode [data-tom="e"] span { position: absolute; border-top: 1.2rem solid #000; border-right: 1.2rem solid transparent; width: 2.4rem; height: 0; left: 1.2rem; top: 2.1rem;} #tokyootakumode:after { position: absolute; content: '®'; font-size: 2.2rem; left: calc(50% + 7.8rem); top: calc(50% + 4.1rem);}
ロゴの中に重複して出現する O
や T
などは共通する箇所はスタイルを継承する形で、 :nth-child
セレクタを用い何番目に出現する文字かを判別して個々のスタイルを適用させています。
これだけではおもしろみもないので、出来上がったこのロゴを使ってHTMLソースはそのままで、CSSだけを追加していろいろ遊んでみます。
1. CSSアニメーション このロゴにCSSアニメーションを加えてダイナミックにしてみます。 2011 年 6 月に Firefox 5 が CSS アニメーションに対応してから、いまやほとんどのモダンブラウザで自由度の高い動きを表現できるようになりました。(IEは10以上) スマートフォンでも対応しており、JavaScriptを使用するよりもなめらかに動作することがメリットですね。
CSSアニメーションを適応させてみたのが下記です。 停止している場合は 「Reload」ボタンをクリック するか、ロゴをクリック してみてください。
新しいウィンドウで開く
bounce
と定義した手前から現れて所定位置で跳ねるというアニメーションをロゴ内のすべてのテキストに適応し、1文字1文字 animation-delay
を使用して0.1秒ずつ遅らせて適応させることで実現しています。
1 2 3 4 5 6 7 8 9 10 @keyframes bounce { 0% { transform: scale(22); } 50% { opacity: 1; } 70% { transform: scale(0.74); } 80% { transform: scale(1.2); } 95% { transform: scale(0.85); } 98% { transform: scale(1.1); } 99% { transform: scale(0.95); } 100% { opacity: 1; transform: scale(1); } }
2. CSS Transform 3D 先ほどは2Dの拡大縮小を使いましたが、3Dのようなパースをつけた奥行きのある表現もCSSだけで実現可能となりました。 下記の画面内でマウスを動かしてみてください。
新しいウィンドウで開く
マウスの位置取得にJavaScriptを利用していますが、それ以外は基本CSSのみで表現しています。 遠近法における消失点というユーザーの見ている位置(焦点距離)による、いわゆる物体のゆがみもCSSで調整することができます。 例ではダイナミックにするため焦点距離を短く設定しています。
3. ブレンドモード Adobe PhotoShopやAdobe Illustratorなどを触ったことのある方はご存じの方も多いとおもいますが、ブレンドモード(描画モード)というDOM要素を重ねた際の効果をCSSから指定できるようになりました。 ブレンドモードとはレイヤーを重ねたときに、下にあるレイヤーに対して上のレイヤーをどのように合成するかを指定することができます。 CSS3のプロパティ mix-blend-mode
を指定するだけで、ブレンドモードの効果を表現することができます。
単純な背景色がアニメーションする背景にロゴを重ねたサンプルを作成しました。 左のメニューブレンドモードの値(mix-blend-mode
)を変更することができますので、値を変更して試してみてください。 「オーバーレイ」や「除外」などが効果がわかりやすいと思います。
新しいウィンドウで開く
上記は単純にベタ塗りの背景ですが、背景に写真を配置してみたり、上位のレイヤーを繊細な画像にすることでも多彩な表現が加えられます。 もっと顕著に表現できるのは動画に重ねた場合です。下記動画を再生してみてください。
新しいウィンドウで開く Big Buck Bunny from Blender Foundation on Vimeo “.
それぞれのフレームでブレンドモードに応じた合成が行われますので、多彩な表現が可能になりますね。(※ 上記動画ではオーバーレイで重ねています) 動的にコンテンツを生成できるWebだからこそ実現可能な、一風変わった表現も行えると思います。
先日Internet Explorer 10以前のサポートが終了したことで、いままでIEでのみ未対応だったため泣く泣く使用を断念していたCSSプロパティもどんどん使っていこうという方も多いのではないでしょうか。 これからはデザインする側も表現の幅が増え、マークアップエンジニアの方にとっては乗算をかけられたPSDレイヤーを見て、愕然としつつデザイナーの元へ駆けつけるなんて苦労も少しは解決できればいいですね!