CSSグラデーションのちょっとしたテクニック #1

リリースを間近にひかえたFirefox 3.6で対応されるので、そこかしこで取り上げられているCSSによるグラデーション。基本的な書き方はIntroducing CSS Gradientscss gradients in Firefox 3.6を始めとして腐る程あるのですっ飛ばすとして、実際にボタン等で利用する時にどうすれば簡単に書けそうかということをちょっと考えてみようとかいう話。勢いで#1とかつけてしまった……。

button要素にCSSによるグラデーションをかけるには以下のように書くことになる。

button {
  background-image: linear-gradient(top, rgb(204, 204, 204), rgb(102, 102, 102));
  background-image: -moz-linear-gradient(top, rgb(204, 204, 204), rgb(102, 102, 102));
  background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, rgb(204, 204, 204)), color-stop(1, rgb(102, 102, 102)));
  filter: progid:DXImageTransform.Microsoft.Gradient(StartColorStr="#CCCCCC", EndColorStr="#666666");
}

上から下にrgb(204, 204, 204)からrgb(102, 102, 102)へのグレーのグラデーションをかける例。ブラウザによって書き方がかなり違うのでちょっと読みづらいが、単純なグラデーションなのでさほど難しくはない。-webkit-gradient()ではfrom()to()でグラデーションの開始色と終了色を指定した例を良く見かけるが、CSS3のlinear-gradient()(や-moz-linear-gradient())と書き方を似せるためにcolor-stop()を使った方が良さそう。特に複数の色停止位置を使った少し複雑なグラデーションをかけたりする場合color-stop()の方が相互に変換しやすい。なおbutton要素によるサンプルは以下の対応ブラウザでしか意図したとおりに表示されない。

このボタンにカーソルを合わせた時にrgb(187, 204, 221)からrgb(51, 102, 153)というブルーグレーのグラデーションに変えるためには、単純にグラデーションの色を変えて書くとすると以下のように書くことになる。

button:hover {
  background-image: linear-gradient(top, rgb(187, 204, 221), rgb(51, 102, 153));
  background-image: -moz-linear-gradient(top, rgb(187, 204, 221), rgb(51, 102, 153));
  background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, rgb(187, 204, 221)), color-stop(1, rgb(51, 102, 153)));
  filter: progid:DXImageTransform.Microsoft.Gradient(StartColorStr="#BBCCDD", EndColorStr="#336699");
}

色をちょっとだけ変えたいだけなのに、コピペしてから6ヶ所も変更しなければならなかったりと、変更や修正をするのが大変そうでちょっとアレ。

そこでベースになるグラデーションをこれまた最近クローズアップされることが多いrgba()を利用して以下のように変更する。

button {
  background-color: rgb(102, 102, 102);
  background-image: linear-gradient(top, rgba(255, 255, 255, 0.7), rgba(255, 255, 255, 0));
  background-image: -moz-linear-gradient(top, rgba(255, 255, 255, 0.7), rgba(255, 255, 255, 0));
  background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, rgba(255, 255, 255, 0.7)), color-stop(1, rgba(255, 255, 255, 0)));
  filter: progid:DXImageTransform.Microsoft.Gradient(StartColorStr="#B2ffffff", EndColorStr="#00ffffff");
}

ベースの背景色をrgb(102, 102, 102)にし、それに半透明からだんだん透明に近づくアルファ付きのグラデーションを重ねてやるというもの。IEでは色の指定にrgba()は利用できないが、#AARRGGBBという形でアルファ付きで指定できるので、FirefoxやSafariと同じようにグラデーションをかけることができる。これだとマウス・オーバーでのブルーグレーへのグラデーションへの変更は背景色の変更だけで済む。

button:hover {
  background-color: rgb(51, 102, 153);
}

直感的でわかりやすく、なおかつ短く書きやすい。グラデーションの色や滑らかさの修正や変更も背景色の調整と透明度の修正だけで済むので比較的簡単だと思う。OperaやFx3.5以下等のCSSによるグラデーションをサポートしていないブラウザでも、:hoverをサポートしていれば背景色が切り替わる効果だけは有効になるのもメリット(サンプル #1でも背景色も指定すれば切り替わるが更に修正・変更箇所が増えることになる)。

同系色のグラデーションにしか利用できないテクニックではあるが、ボタンやナビゲーションの背景にちょっとグラデーションをかけたいとかいう場合にはコピペしてbackground-colorをちょこちょこっと変えるだけで完成なので便利。


CSS Gradient Header(Firefox 3.6 Beta 4でのスクリーンショット)

手習いに今は画像で作っているこのサイトのヘッダをCSSグラデーションで作ってみた(Fx 3.6b3+のみ)。色停止位置を工夫すればグラデーション→単色塗りつぶし→グラデーション→単色塗りつぶし……などということもちゃんとできる。

body {
  background-image: -moz-linear-gradient(
    top,
    rgb(249, 246, 240) 0,
    rgb(249, 246, 240) 16px,
    rgb(102, 170,  17) 16px,
    rgb(102, 170,  17) 18px,
    rgb(105, 102,  96) 18px,
    rgb(58,   55,  49) 54px,
    rgb(102, 170,  17) 54px,
    rgb(102, 170,  17) 56px,
    rgb(249, 246, 240) 56px
  );
}

:active:hover時のグラデーションの変更は透明に近づくグラデーションを重ねるというこのエントリで書いたテクニックを利用した。なので現在の画像によるグラデーションとは色がちょっと違う。

div#header ul#navigation li.active a {
  background-color: #66aa11;
  background-image: -moz-linear-gradient(
    top,
    rgba(255, 255, 255, 0),
    rgba(255, 255, 255, 0.25)
  );
}

Safariではcolor-stop()の長さに割合指定しかできないようなので、ピクセル単位でグラデーションをかけたりするのは大変そう……。background-sizeでグラデーションのサイズを指定した上で計算機で割合を計算する必要があるんだと思う(面倒になったのでまだ作ってない)。