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

前回のエントリのような応用するための基本というものではなく、CSSグラデーションはこういう使い方もできるよ的なもので3つ。普通のグラデーションの作り方はcss gradients in Firefox 3.6とかで。#3はない。

以下プレビュー画像のリンク先がデモ・ページになっているのでそちらも参照のこと。もちろん対応ブラウザのFirefox 3.6とSafari 4やChrome 4以降でないと動作デモは確認できない。

Vista風のテカってるボタン

テカテカボタン

ありがちだけど作れたらなかなか便利そうなので挑戦してみたら、意外に簡単だった。実はdoubleborderが重要で、これが無いとちょっと間抜けな感じになる。コード的には難しいことはなく、上半分にrgb(138, 138, 138)からrgb(102, 102, 102)、下半分にrgb(36, 36, 36)からrgb(0, 0, 0)と、2つに分けてグラデーションをかけているだけ。

background-color: rgb(102, 102, 102);
background-image: -moz-linear-gradient(
  top,
  rgb(138, 138, 138)    0,
  rgb(102, 102, 102)  50%,
  rgb( 36,  36,  36)  50%,
  rgb(  0,   0,   0) 100%
);
background-image: -webkit-gradient(
  linear,
  left top,
  left bottom,
  color-stop(  0, rgb(138, 138, 138)),
  color-stop(0.5, rgb(102, 102, 102)),
  color-stop(0.5, rgb( 36,  36,  36)),
  color-stop(1.0, rgb(  0,   0,   0))
);

テカりをうまく出すのは結構大変だけど、腐るほどあるPhotoshop向けのチュートリアルとかが大いに参考になるので読みあさると良い。

テカピカボタン

Firefoxでは-moz-radial-gradientを使って:hoverの時に枠の上下がちょっと光るエフェクトも付けてみた。かなりコードはややこしい。上下の光をまとめて作るのはできないことはなさそうだけど面倒なことは間違いないので、それぞれ別々に指定する。以下のコードで下の光が作れる。

background-image: -moz-radial-gradient(
  /* 開始位置を中央下に => 半楕円のグラデーションになる */
  center bottom,
  /* デフォルト値と同じなので未指定でも良い */
  ellipse farthest-side,
  /* rgba()を使って光っぽく */
  rgba(255, 255, 255, 0.8)    0,
  rgba(255, 255, 255,   0) 100%
);
/* 繰り返しはしない */
background-repeat: no-repeat;
/* 位置をボックスの下端中央に */
background-position: center bottom;
/* サイズを横80%・縦2pxに */
-moz-background-size: 80% 2px;

普通に(楕)円状のグラデーションを置いただけでは光っぽくならないので、開始位置をずらしてやることによって半(楕)円状にしてやり光が拡散している感じを出す。上の光もほぼコードは一緒だが、幅を100%にして光を強めてある。SafariやChromeでは楕円のグラデーションを作るのが大変そうだったので諦めた。

doubleborderの隙間を意図した色で塗るためにはbackground-colorが必須。それでもSafariやChromeではborderdoubleの時の隙間が変に塗られるのでちょっと汚い(Firefoxもちょっと変だけど、サンプルでは-moz-border-*-colorsで制御した)。変というか挙動をはっきりと理解していないのでうまく塗れないだけかも。

-moz-border-*-colors

-moz-border-*-colorsは複数の色をボーダーに使用するためのMozillaの独自拡張プロパティ。SafariやChromeには同等のプロパティはない。以下のように空白区切り(カンマ区切りではないので注意)で複数の色を指定する。

-moz-border-top-colors: none rgb(255, 0, 0) rgb(0, 255, 0) rgb(0, 0, 255) transparent;

noneの場合はborder-colorで塗られ、transparentの場合はbackground-colorで塗られる……はずだが挙動不審なので使う場合はきっちり色を指定した方が良さそう。

pre要素で行ごとに色を変える

行ごとに色が違うpre

シンタックス・ハイライトするJavaScriptライブラリに良くあるデザインだが、これもCSSグラデーションでいける。CSSグラデーションは複数の色で単純に塗り分けるというようなことも可能だということは覚えておくと良い。

background-image: -moz-linear-gradient(
  top,
  rgb(255, 255, 255)    0,
  rgb(255, 255, 255) 18px,
  rgb(243, 246, 252) 18px,
  rgb(243, 246, 252) 36px
);
-moz-background-size: 1px 36px;

上端から18pxまではrgb(255, 255, 255)で塗り、18pxから36pxまではrgb(243, 246, 252)で塗るように指定する。あとはこれが並ぶはず……と思いきや並ばず、pre要素の下端までrgb(243, 246, 252)で塗られてしまう。Firefoxでbackground-repeatを有効にするためにはbackground-sizeで明示的に背景画像のサイズをしてやる必要がある。本来は-moz-repeating-linear-gradientを使うべきなのかもしれないがSafariやChromeには無いので、同じようなアプローチで記述できるbackground-repeat-moz-background-sizeで書いた方が混乱しない。

background-image: -webkit-gradient(
  linear,
  left top,
  left bottom,
  color-stop(  0, rgb(255, 255, 255)),
  color-stop(0.5, rgb(255, 255, 255)),
  color-stop(0.5, rgb(243, 246, 252)),
  color-stop(1.0, rgb(243, 246, 252))
);
-webkit-background-size: 1px 36px;

一方SafariやChromeではピクセル単位でグラデーションを制御することはできないので一見無理そうだが、こちらもbackground-sizeを明示的にしてやれば計算でピクセル単位で制御できるようになる。#1の最後でちょっと触れてたが、このアプローチで問題なく上手くいく。整数にならない場合の丸め方が一定ではないので、確実に整数値になるように計算できるサイズと割合に調節した方が良い。

ここではわかりやすくpxでゴリゴリ指定したが、それぞれの単位はemでも良いのでフォントサイズに合わせて柔軟に変化するようにも書くことができる。今時のブラウザならpxで良さそうではあるけど、emとかを使った方がメンテナンス性が高い。

テーブルクロスっぽいチェックの背景

赤いチェック模様

もはやCSSを読んでも何をやっているのか解らない……。書いた自分ですらもう一度書けといわれても難しい感じ。こんなこともできるよということで。

background-color: rgb(180, 30, 30);
background-image:
  -moz-linear-gradient(
    top,
    rgba(  0,   0,   0, 0.2)  0px,
    rgba(  0,   0,   0, 0.2)  4px,
    rgba(255, 255, 255, 0.5)  4px,
    rgba(255, 255, 255, 0.5)  8px,
    transparent               8px,
    transparent              28px,
    rgba(255, 255, 255, 0.5) 28px,
    rgba(255, 255, 255, 0.5) 32px
  ),
  -moz-linear-gradient(
    left,
    rgba(  0,   0,   0, 0.2)  0px,
    rgba(  0,   0,   0, 0.2)  4px,
    rgba(255, 255, 255, 0.5)  4px,
    rgba(255, 255, 255, 0.5)  8px,
    transparent               8px,
    transparent              28px,
    rgba(255, 255, 255, 0.5) 28px,
    rgba(255, 255, 255, 0.5) 32px
  )
;

複数の背景画像を使って格子を形成する。1つ目が横方向の縞で、2つ目が縦方向の縞。普通に四角を並べる感じで作れそうな気がするが(多分)無理で、rgba()をうまく使って濃淡をつけるしか方法を思いつかなかった。ベースとなる部分はtransparentで塗っておいて、background-colorでそのベースの色を指定。WebKit向けのコードも似たような感じで、読みづらい以外は特に変わったところも無いため割愛。斜めのチェック模様とかもFireとSafariやChromeと挙動を合わせるための計算が面倒なだけで、それほど難しくはないと思う。

本当はもっとタータンチェックっぽくドットを組み合わせたものにしようと思ってたけど面倒すぎる(無理かも)ので簡単に作った。-moz-diamond-gradientとかがあればタータンチェックも簡単に出来そう。


linearなグラデーションを書く場合は-webkit-gradientの方がPhotoshopとかのグラデーション製作フローをそのままコードにした感じでまだ読みやすい。Firefoxの開始位置と方向の角度でグラデーションの向きを決めるってあんまり直感的ではない気がする。デフォルトでそんな操作させるペイント・ソフトとか触ったことないし。

一方、radialなグラデーションの場合は-webkit-gradientはもはや人間には読めない。その分-moz-radial-gradientよりも複雑(怪奇)なことができるけど。-moz-radial-gradientでは単純な(楕)円状グラデーションしか作れない反面、お馴染みのワードで指定できる開始位置と単純な2つの形状・直感的な呼称の終了位置の3つを指定して作成するのでイメージしやすく、ペイント・ソフトの挙動と似ていて馴染みやすい。

Mozillaの……というかCSS3の文法の方がまだマシな感じではあるので、WebKitが合わせてくれると良いな。-webkit-gradientはそのまま残せば良いわけだし。

それぞれエントリにすれば良かった……。