CSSでアイコンつきのおしゃれなボタンを作る

新規にWebページを作る時に、見た目の印象をよくしようとして、いつも苦戦するのが入力フォーム、テーブル、ボタンの3つ。

Twitter Bootstrapという選択肢

入力フォーム、テーブル、ボタンをはじめ、WebページのUIについてはTwitter Bootstrapを使うことでだいぶ改善できるとは思うのだけど、ボタンに関しては、ちょっとばかり心許ない。

まずは、ボタンにアイコンをはりつけるために、

<i class="icon-search icon-white"></i>

みたいな形で専用に<i>タグの挿入がhtmlに必要な点。ここらはcssのクラスの指定だけでできるようにしたい。

そして、用意されているアイコンが白ベースと黒ベースの2セットしかない点。自由なアイコンを使いたい。とはいえ、Twitter Bootstrapみたいに、1枚のスプライトの読み込みで色々なアイコンが表現できるのは理想的なんだけどね。

Pixify: Google+ to Improve Your UI

というわけで、別の手段として、Google+風のボタンを実現できるものを見つけた。

Use Google+ to Improve Your UI (pixify)

これを使うと、例えばclass="button add"とするだけで、追加用のアイコンをつけたボタンを作ることができる。

カスタマイズ

試してみたところ、概ね満足(スプライト用の画像を作るのが面倒だったので、1アイコン1画像ファイルにしてしまったけど…)。

ただし、横並びにくっついたボタンを表現するのに、

<a href="#" class="button left">Left</a><a href="#" class="button middle">Middle</a><a href="#" class="button middle">Middle</a><a href="#" class="button right">Right</a>

みたいな形で書く必要があり、

  • 左のボタン要素にclass="left"、真ん中のボタン要素にclass="middle"、右のボタン要素にclass="right"をそれぞれつけないといけない。
  • ボタンをくっつけるためには、それぞれの要素の間に空白を入れてはいけない。1行で書く必要がある(エディタのフォーマットが使えない)。
といった所がまだ不満だったので、修正してみた。

見た目は変化ないけど、htmlとcssを変えている。

HTML

リストで書く。

<ul class="button-list">
    <li><a href="#" class="button">Left</a></li>
    <li><a href="#" class="button">Middle</a></li>
    <li><a href="#" class="button">Middle</a></li>
    <li><a href="#" class="button">Right</a></li>
</ul>

ボタンが増えてもその分<li>要素を追加するだけでOK。先頭要素や最終要素をhtml側で意識する必要はない。

CSS

該当する部分を抜粋。

ul.button-list {
    padding: 0;
    list-style: none;
    clear: both;
}

ul.button-list:after { /* clearfix */
    content: ".";
    clear: both;
    height: 0;
    display: block;
    visibility: hidden;
}

ul.button-list li {
    margin: 0;
    padding: 0;
    float: left;
    line-height: 3;
}

ul.button-list li a.button {
    margin: 0;
    padding: 7px 12px;
    text-shadow: 0 1px 0 #fff;
    -webkit-transition: border-color .218s;
    -moz-transition: border .218s;
    -o-transition: border-color .218s;
    transition: border-color .218s;
    background: #f3f3f3;
    background: -webkit-gradient(linear,0% 40%,0% 70%,from(#F5F5F5),to(#F1F1F1));
    background: -moz-linear-gradient(linear,0% 40%,0% 70%,from(#F5F5F5),to(#F1F1F1));
    border: solid 1px #dcdcdc;
    border-right: solid 1px #f3f3f3;
    border-radius: 0;
    -webkit-border-radius: 0;
    -moz-border-radius: 0;
}

ul.button-list li:first-child a.button {
    -webkit-border-top-left-radius: 2px;
    -moz-border-radius-topleft: 2px;
    border-top-left-radius: 2px;
    -webkit-border-bottom-left-radius: 2px;
    -moz-border-radius-bottomleft: 2px;
    border-bottom-left-radius: 2px;
    border-left: solid 1px #dcdcdc;
}

ul.button-list li:last-child a.button {
    -webkit-border-top-right-radius: 2px;
    -moz-border-radius-topright: 2px;
    border-top-right-radius: 2px;
    -webkit-border-bottom-right-radius: 2px;
    -moz-border-radius-bottomright: 2px;
    border-bottom-right-radius: 2px;
    
    border-right: solid 1px #dcdcdc;
}
  • 先頭や最後の要素の場合は、CSSの擬似クラスで定義。先頭要素は左側を角丸に、最後の要素は右側を角丸にするように定義している。
  • 流しこみ(float)の解消にclearfixってのがあるのを知ったので、使ってみた。便利。

注意点

  • IE8まではlast-child擬似クラスが使えないので、IE8以前のIEだと、最後の要素の右側がボーダーなしになる。
  • 定義が重複するためか、横並びにしたボタンにアイコンをつけようとしても(class="button add"みたいに)、アイコンが表示されない。
a.add {
    background: url(sprite.png)  10px -27px no-repeat #f3f3f3;
    padding-left: 30px;
}

これを、

a.add {
    background: url(sprite.png)  10px -27px no-repeat #f3f3f3 !important;
    padding-left: 30px !important;
}

のように、!importantをいちいち付けないとならないかも。