Asial Blog

Recruit! Asialで一緒に働きませんか?

もうアイコン画像はいらない! Webフォントを使って、iOS風タブバーとアイコンを作成する方法

カテゴリ :
フロントエンド(HTML5)
タグ :
Tech
HTML5
CSS3
iOS
Android
こんにちは、鴨田です。

最近、アイコンがセットされたWebフォントを使うことで、
画像を使わずにアイコンを表示するという手法が流行っていますね。

すごく興味はあったのですが、なかなか使う機会もなく、
便利そうだなと思っていただけで、今まで使ったことがありませんでした。

しかし、先日、とある案件でやっと使う機会に恵まれたので、やり方をご紹介いたします。
(プロトタイプだけ作って、結局プロダクトとしては使いませんでしたが・・・)

1.アイコンWebフォントをダウンロードする



最近話題になっていたこちらのサイトがとても便利です。

Fontello - http://fontello.com/



使いたいフォントを選択します。
ここでは、「Entypo」フォントから5つ選択します。



選択が終わったら、上部のタブから「Edit codes」をクリックします。



アイコン画像の上部のバーをクリックして、アイコンに割り当てる文字列を決めます。
英語で頭文字を取るとか、abc~とかにするとかですかね。



文字列の指定が終わったら、フォントファイルのダウンロードを行います。
サイト右上にある「Download webfont(n)」をクリックしましょう。
「fontello-xxxxxxxx.zip」がダウンロードされます。

解凍して中身を見てみましょう。

fontello
-cssフォルダ
 -icons.css
 -icons-codes.css
 -icons-ie7.css
 -icons-ie7-codes.css
-fontフォルダ
 -icons.eot
 -icons.svg
 -icons.ttf
 -icons.woff
-config.json
-demo.html
-LISENSE.txt
-README.txt

が入っています。

どんな作りになっているのかは割愛します。
重要な箇所に関しては、後で説明しています。
とりあえず中身を知りたい人は、ライセンスとリードミーを読んだ後、
(特にフォントのライセンスについては特に確認した方がいいと思います)
demo.htmlとicons.cssを見てみてください。

それでは、iOS風タブバーを作っていきましょう。

2.HTMLとCSSでRetina対応のiOS風タブバーを作成する



html
-cssフォルダ
 -reset.css
 -style.css
-fontフォルダ
 -icons.eot
 -icons.svg
 -icons.ttf
 -icons.woff
-index.html

reset.cssは、HTML5用の既知のreset.cssであれば何でも構いません。
以前に記事にした「HTML5+CSS3の導入時に役立つ7つの設定」も参考にしてください。

「font」フォルダは、先ほどダウンロードしてきたフォルダをそのままコピーします。

まずは、tab.htmlを書きましょう。

index.html
  1. <!DOCTYPE html>
  2. <html>
  3.  
  4. <head>
  5.   <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  6.   <meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
  7.   <title>iOS風タブバー</title>
  8.   <link rel="stylesheet" media="screen" href="css/reset.css" />
  9.   <link rel="stylesheet" media="screen" href="css/style.css" />
  10. </head>
  11.  
  12. <body>
  13.  
  14.   <!-- header -->
  15.   <header id="header">
  16.     <h1>タイトル</h1>
  17.   </header>
  18.  
  19.   <!-- tab menu -->
  20.   <nav id="tab">
  21.     <ul>
  22.       <li><a href="" class="on"><span><i class="icon-home"></i>HOME</span></a></li>
  23.       <li><a href=""><span><i class="icon-camera"></i>カメラ</span></a></li>
  24.       <li><a href=""><span><i class="icon-picture"></i>アルバム</span></a></li>
  25.       <li><a href=""><span><i class="icon-bookmark-1"></i>お気に入り</span></a></li>
  26.       <li><a href=""><span><i class="icon-info-circle"></i>お知らせ</span></a></li>
  27.     </ul>
  28.   </nav>
  29.  
  30. </body>
  31. </html>

特に何の変哲もないHTMLのソースコードです。
これに関しては、何も言うことがありません。

続いて、style.cssを書きます。

style.css
  1. /* font */
  2. @font-face {
  3.   font-family: 'icons';
  4.   src: url("../font/icons.eot");
  5.   src: url("../font/icons.eot?#iefix") format('embedded-opentype'), url("../font/icons.woff") format('woff'), url("../font/icons.ttf") format('truetype'), url("../font/icons.svg#icons") format('svg');
  6.   font-weight: normal;
  7.   font-style: normal;
  8. }
  9. .icon-home:before { content: '\68'; } /* 'h' */
  10. .icon-info-circle:before { content: '\69'; } /* 'i' */
  11. .icon-picture:before { content: '\70'; } /* 'p' */
  12. .icon-camera:before { content: '\63'; } /* 'c' */
  13. .icon-bookmark-1:before { content: '\66'; } /* 'f' */
  14. /* common */
  15. #header {
  16.   position: fixed;
  17.   z-index: 2;
  18.   width: 100%;
  19.   height: 44px;
  20.   top: 0;
  21.   left: 0;
  22.   background: #eee;
  23.   background: -o-linear-gradient(top, #fff, #fff 50%, #ddd 50%, #ddd);
  24.   background: -moz-linear-gradient(top, #fff, #fff 50%, #ddd 50%, #ddd);
  25.   background: -webkit-gradient(linear,left top,left bottom, color-stop(0.5, #fff),color-stop(0.5, #ddd));
  26.   border-top: 1px solid #666;
  27.   border-bottom: 1px solid #444;
  28.   text-align: center;
  29.   overflow: hidden;
  30. }
  31. #tab {
  32.   position: fixed;
  33.   z-index: 2;
  34.   width: 100%;
  35.   height: 49px;
  36.   bottom: 0;
  37.   left: 0;
  38.   border-top: 1px solid #444;
  39.   background: #ccc;
  40.   background: -o-linear-gradient(top, #fff, #ccc);
  41.   background: -moz-linear-gradient(top, #fff, #ccc);
  42.   background: -webkit-gradient(linear,left top,left bottom, color-stop(0, #fff),color-stop(1, #ccc));
  43.   float: left;
  44.   overflow: hidden;
  45. }
  46. /* header */
  47. #header h1 {
  48.   line-height: 44px;
  49.   display: block;
  50.   font-size: 20px;
  51. }
  52. /* footer */
  53. #tab ul {
  54.   width: 100%;
  55.   height: 49px;
  56.   float: left;
  57. }
  58. #tab li {
  59.   width: 20%;
  60.   height: 100%;
  61.   text-align: center;
  62.   display: block;
  63.   float: left;
  64. }
  65. #tab li a {
  66.   width: 100%;
  67.   height: 100%;
  68.   display: block;
  69.   color: #777;
  70.   text-decoration: none;
  71.   font-size: 8px;
  72. }
  73. #tab li a.on, #tab li a:hover {
  74.   color: #09c;
  75. }
  76. #tab li a span {
  77.   margin: 3px 6px;
  78.   padding: 0 0 2px;
  79.   display: block;
  80. }
  81. #tab li a.on span {
  82.   margin: 2px 5px;
  83.   background: rgba(255,255,255,0.2);
  84.   border: 1px solid rgba(0,0,0,0.2);
  85.   border-radius: 4px;
  86. }
  87. #tab li a i {
  88.   font-family: 'icons';
  89.   font-size: 30px;
  90.   font-style: normal;
  91.   display: block;
  92.   padding: 0 0 2px 0;
  93. }
  94. #tab li a.on i, #tab li a:hover i {
  95.   text-shadow: 0px 1px 0 rgba(0, 0, 0, 0.6);
  96. }

注目するところは、以下ですね。

  1. @font-face {
  2.   font-family: 'icons';
  3.   src: url("../font/icons.eot");
  4.   src: url("../font/icons.eot?#iefix") format('embedded-opentype'), url("../font/icons.woff") format('woff'), url("../font/icons.ttf") format('truetype'), url("../font/icons.svg#icons") 
  5. format('svg');
  6.   font-weight: normal;
  7.   font-style: normal;
  8. }

まずは、Webフォントの読み込みを行います。

  1. .icon-home:before { content: '\68'; } /* 'h' */
  2. .icon-info-circle:before { content: '\69'; } /* 'i' */
  3. .icon-picture:before { content: '\70'; } /* 'p' */
  4. .icon-camera:before { content: '\63'; } /* 'c' */
  5. .icon-bookmark-1:before { content: '\66'; } /* 'f' */

:beforeセレクタとcontentプロパティを使うことで、
HTML自体に余計な文字列が紛れ込むのを防いでいます。
SEOやユニバーサルデザイン的にもあまりよろしくないですからね。

そして、最終的に重要なところはここです。

  1. #tab li a i {
  2.   font-family: 'icons';
  3.   font-size: 30px;
  4.   font-style: normal;
  5.   display: block;
  6.   padding: 0 0 2px 0;
  7. }

アイコンを表示させるべき箇所で、font-familyプロパティに、さきほどセットした"icons"を使用します。
displayプロパティはblockにしてください、地味に重要です。
後は、アイコンの大きさとちょっとしたパディング設定とイタリック体の解除を行っています。

これだけです。これだけでこうなります。
デモなので、ロールオーバーとかします。



なんて便利!
もういちいち画像を使って、タブバーを作るのが面倒くさくなってしまいます。

動作確認は、iOS5.0ではSafari、Chrome、Android4.0および2.3では標準ブラウザで行っています。
PCブラウザであれば、各最新版のSafari、Chrome、Firefox、Operaで問題ありません。
IEは9以降で、グラデーション等が使えないですが、Webフォント自体は使えるようですね。

一応、横幅はどんなサイズであろうとも、対応しています。
ただし、もろもろの事情により、先日書いた「CSS3だけで作るレスポンシブデザイン対応ナビゲーションバーの作り方」とは違い、古風な手段で対応しています。

※Opera対応しようと思っただけなのですが、Operaはbox-flex使えないので・・・
 多分、スマホサイトでしか使わないと思うので、
 OperaとIEを気にしないのであれば、上記記事と組み合わせて、モダンなCSSでいけるはずです。

是非、一度試してもらえたらと思います。

GitHubにソースコード一式を公開したので、煮るなり焼くなり、
自由にダウンロードやフォークしてみてください。

jsdo.itにも公開しておきます。ただし、SVGファイルしか置けなかったので、
ChromeかSafariでしか、ちゃんと表示されません。

コメント

  • シマダ

    アイコンのような装飾以外に意味を持たない要素はspan要素として表現すべきだと思うのですが、i要素を使うのはなぜでしょうか。
    span要素にすれば、「イタリック体の解除」をすることもないはずです。

  • 鴨田

    こんにちは、シマダさん。
    仰るとおりなので、いざ自分で書くときはいろいろカスタマイズしてもらえたらと思います。

    それで、なぜi要素になっているのかというと、fontelloからダウンロードしてきたデフォルトの
    demo.htmlとicons.cssがそのような造りになっていたから、そのまま使っています。

    とはいえ、あまりよろしくないので、もう少し手を入れるべきでしたね。
    ご指摘、ありがとうございます。

  • ひろし

    横から失礼します。
    i要素を使ってるのはHTML5の他のテキストと区別する、というところを意識してのことではないでしょうか。
    Twitter Bootstrapのアイコンのマークアップも同様にi要素を使用していました。(あちらは画像ですが。)

    間違っていたら申し訳ありません。

  • 鴨田

    こんにちは、ひろしさん。

    言われて、はじめてちゃんと調べたのですが、
    どうも、i要素の定義がHTML4/XHTML1から変わっているようですね。
    単なる斜体テキストを表すわけではないようです。

    以下、引用です。
    (引用元:http://www.marguerite.jp/Nihongo/WWW/RefHTML5/i.html)

    ----------

    HTML 5 に於ける<i>要素は、特別なスタイルの語句となります。
    HTML 4/XHTML 1 では、<i>要素は斜体テキストと定義されておりましたが、HTML 5 では表示方法を問わない定義に変更されました。
    具体的には、

    ・専門用語(文章中で定義の説明がないもの)
    ・外来語(主に英語文書などで)
    ・船舶などの名前
    ・思考或いは他者が発言しそうな文章

    など、表示の際に特別なスタイルを用い得る語句で、フレージング内容要素としての定義がない場合に用います。

    ----------

    なので、HTML5であれば、この記事のようにi要素を使うのは特に間違っていなさそうです。
    有意義なコメントありがとうございます。

  • シマダ

    > それで、なぜi要素になっているのかというと、fontelloからダウンロードしてきたデフォルトの
    > demo.htmlとicons.cssがそのような造りになっていたから、そのまま使っています。

    そうでしたか。

    確かにHTML5ではi要素の意味が変わりました。
    仕様書による定義はこうです。

    http://www.w3.org/TR/html5/the-i-element.html#the-i-element
    > The i element represents a span of text in an alternate voice or mood, or otherwise offset from the normal prose in a manner indicating a different quality of text, such as a taxonomic designation, a technical term, an idiomatic phrase from another language, a thought, or a ship name in Western texts.

    果たしてアイコンは「text」でしょうか。

    アイコンをi要素で表す流儀はある程度広まっているようですが、広まっているものが正しいとは限りません。

    実際のところ、
    http://stackoverflow.com/questions/11135261/i-tag-for-icons
    の回答にあるように、

    ・短い
    ・iconのi

    というのがi要素を使う理由でしょう。
    私は「Awful practise」という意見に同感です。

  • 鴨田

    こんにちは、シマダさん。

    > ・短い
    >・iconのi

    というのは、自分も感じていました。

    HTMLの定義として、
    どの要素を使うのがより正しいというのはあると思いますが、
    場面によって、いろいろと都合はあると思うので、
    こういうことをきっかけに理解を深められたらいいなと思っています。

    ご意見、御指南ありがとうございます。

コメントフォーム




captcha_key

アシアルの会社情報

アシアル株式会社はPHP、HTML5、JavaScriptに特化したWebエンジニアリング企業です。ユーザーエクスペリエンス設計から大規模システム構築まで、アシアルメンバーが各々の専門性を通じてインターネットの進化に貢献します。

会社情報詳細

最近の記事