CSSでアイコンをデザイン

CSSでアレンジしたアイコン

ものすごく大雑把に言うと今まで画像編集ソフトでやっていた、角を丸くするとか背景をグラデーションにするなどという作業をCSSでやってしまおうというお話。もちろんCSSでできないことは多くあるので万能というわけではないが、できることに限って言えば数行のCSSコードでスクリーンショットのような効果を柔軟に適用することができる。

View Demo: Design icon with CSS

ul li a {
  display: block;
  width: 32px;
  height: 32px;
  background-image: url("icons-w.png");
  background-repeat: no-repeat;
  text-indent: -10000px;
}
アイコンのベース

各アイコンになるa要素へのスタイルは以上のような単純なものがベースになる。icons-w.pngがアイコンの前景をつなげたスプライト画像(パブリック・ドメイン)。これにさまざまなエフェクトをCSSでかけていく。

背景色をつける

塗り塗り

テーマカラーで塗るだけ。

ul .twitter a {
  background-color: rgb(51, 204, 255);
}

このデモでは前景が白の普通にコントラストが高いアイコンを作るので塗るだけだが、ダークなアイコンを作る場合は前景を黒にしてopacityで混ぜるなどとしてコントラストを下げる工夫が必要になる。

グラデーションにする

グラグラ

普通にテーマカラーからグラデーションをちゃんと考えてもいいし、その方が綺麗だが面倒。こういう場合は白の半透明のグラデーションを重ねてやるのが一番手っ取り早い。

#example2 li a {
  background-image:
    url("icons-w.png"),
    linear-gradient(
      rgba(255, 255, 255, 0.5) 0%,
      rgba(255, 255, 255, 0) 100%
    )
  ;
  background-repeat: no-repeat, repeat;
}

背景画像を重ねる方法はいくつかあるが、複数の背景画像を使うのが将来的には安定だと思う。複数の背景画像を使った場合、あとに先に書いた方が手前に来ることには注意が必要。

反射させる(Aero風)

グラピカ

白の半透明のグラデーションをアレンジするだけ。

#example3 li a {
  background-image:
    url("icons-w.png"),
    linear-gradient(
      rgba(255, 255, 255, 0.6)   0%,
      rgba(255, 255, 255, 0.4)  50%,
      rgba(255, 255, 255, 0.2)  50%,
      rgba(255, 255, 255,   0) 100%
    )
  ;
}

中央でグラデーションを一気に切り替える。

角を丸くする

丸丸

普通にborder-radiusを使う。

#example4 li a {
  border-radius: 4px;
}

角丸のサイズはもちろん自由。たった数文字の変更でもっと控えめにも派手にもできる。

真円にする

〇〇

ベースが正方形なので、

#example5 li a {
  border-radius: 50%;
}

とすると真円になる。

枠線をつける

ワクワク

もちろんborder

#example6 li a {
  border: 1px solid rgba(0, 0, 0, 0.2);
}

rgba()を使えば背景色といい感じにブレンド(もちろんグラデーションも考慮される)された枠線をつけることができる。

#example6 li a {
  border: 1px solid rgb(255, 255, 255);
}

などとして暗い背景で埋もれないようにアウトラインを引くのにも使える。

影を付ける

モヤモヤ

box-shadowを使う。

#example7 li a {
  border-radius: 4px;
  box-shadow: 0 0 4px rgba(0, 0, 0, 0.5);
}

予め角丸に加工済みの画像に対して使った場合はその画像の角丸を考慮して影を作ってはくれないが、borde-radiusで角丸にすれば綺麗な影を作ってくれる。

内側に影を付ける

ボヤボヤ

box-shadowinsetを利用する。

#example8 li a {
  box-shadow: inset 0 0 4px rgba(0, 0, 0, 0.5);
}

このデモのようなカラフルなアイコンではあまり効果的ではないが、ダークなアイコンの場合はソリッドな枠線よりも効果的だと思う。

ダークなアイコンにグラデーションで枠線を付ける

背景のテクスチャを工夫すれば木に焼き印を押したような感じとかも簡単に出せるはず。

凹ませる

ベコベコ

box-shadowも複数の値を取ることができるので適切に組み合わせればエンボス効果を出せる。

#example9 li a {
  box-shadow:
    inset 1px 1px 2px rgba(0, 0, 0, 0.25),
    inset -1px -1px 2px rgba(255, 255, 255, 0.5)
  ;
}

内側の明るい影(=ハイライト)を右下方向にずらし、暗い影を左上方向にずらすことによって凹んだような効果になる。オフセットを逆にすれば飛び出す。影の濃さは要調整。


これらには更にtransform変形させることも出来る。またオンマウスをトリガーにしてtransitionによるアニメーションをさせることももちろん出来る。つまりオンマウスで四角から丸に滑らかに変形させるとかも非常に簡単(Operaではborder-radiusがアニメーションできないので滑らかにならないけど追記参照)。

Webフォントを駆使すれば前景として作成した画像すら要らなくなるかもしれないし、その場合は完全にスケーラブルなアイコンをCSSだけでデザインすることが出来ると思う。

CSSだけでデザインすることの最大の利点は、多くの場合制作者側とユーザー側双方のリソースの節約につながるということだと思う。ただし、CSSが巨大になることと、数行の変更でその巨大なCSSの読み直しになるというデメリットがあることも念頭に入れる必要がある。またCSSのイケてる文法と格闘することになるのも見逃せない。

追記

対応ブラウザについて書いてなかったけど察してくれ……というのもアレなので大雑把に書いておく。Chrome 10 beta以降とFirefox 4 beta以降での表示が意図したもの。

  • Internet Explorer 8
    • 知らない書きたくない
  • Internet Explorer 9
    • filterプロパティのDXImageTransform.Microsoft.gradient()で二点間のグラデーションしかサポートしていない
    • border-radiustransition対応プロパティに含まれていない(多分)
  • Google Chrome 9
    • 特になし
  • Google Chrome 11 dev
    • 特になし
  • Safari 5
    • border-radius%指定が効かないのでpx指定で代用している
  • Firefox 3.6.14
    • transition未実装
  • Firefox 4 beta
    • 特になし
  • Opera 11
    • グラデーション未実装
    • border-radiustransition対応プロパティに含まれていない

WebKitでのCSSグラデーションの古い文法やfilterプロパティにも対応させ、IE9やChrome 9、Safari 5でもグラデーションかかるようにしておいた。IE9のグラデーションは二点間のグラデーションのみのサポートなので、Aero風は実現出来ていない。OperaのグラデーションはあとでSVG書くかも(書かないかも)。