Google のボタンをCSSだけでつくるをDelicious経由で見て、もうちょっと出来るんじゃないかなーと思ったので、background-imageで複数のlinear-gradient()を使ってグラデーションにプラスアルファする方法の啓蒙も兼ねてほぼ完コピするCSSの書き方を解説しようかなとか何とか。このエントリの別名は「CSSグラデーションのちょっとしたテクニック #3」になる。
Demo: Google Style Button
まずはデモを参照。パッと見ではどっちか画像か分からない程度にはコピーできていることと思う。もちろんフォント(というかOS)によっては文字が違く見えることと思うが。CSSは以下のような感じになっている(簡略化するためにベンダー拡張は省略、詳しくはデモのソースを参照)。
button {
padding: 1px 6px;
border-top: 0;
border-right: 1px solid rgb(231, 231, 231);
border-bottom: 1px solid rgb(231, 231, 231);
border-left: 0;
height: 33px;
background-color: rgb(204, 204, 204);
background-image: linear-gradient(
top,
rgb(192, 192, 192) 0px, rgb(192, 192, 192) 1px,
rgb(153, 153, 153) 1px, rgb(153, 153, 153) 31px
),
linear-gradient(
top,
rgb(255, 255, 255) 0px, rgb(255, 255, 255) 1px,
rgb(241, 241, 241) 1px, rgb(223, 223, 223) 29px,
rgb(215, 215, 215) 29px, rgb(215, 215, 215) 30px,
rgb(153, 153, 153) 30px, rgb(153, 153, 153) 31px
);
background-position: right top, 1px 1px;
background-size: 1px 31px, auto;
background-repeat: no-repeat;
font-size: 15px;
font-family: Arial, sans-serif;
}
ポイントとなる点は以下の3つ。
background-*プロパティは複数の値を取ることができる(ただしbackground-colorは除く)linear-gradient()でベタ塗りとグラデーションを任意に組み合わせることができるbackground-sizeでlinear-gradient()のサイズを制御できるbackground-positionでlinear-gradient()の位置(主に開始位置)を制御できるパーツごとに分けて説明していく。
border-topとborder-leftを使っても良いが、背景色をその部分の色(rgb(204, 204, 204))に指定し、background-positionで1px 1pxとすることで、背景画像(ここではグラデーション)を左上から右に1px下に1pxの位置から開始させることができる。もちろんbackground-repeat: no-repeat;として背景画像を繰り返さないようにする必要がある。
これはborder-rightとborder-bottomで普通に線を引けば良い。背景画像でも出来ないことはないが、次に説明する右端から1px手前のボタンの影にあたる部分の位置決めが面倒になるのでborderが良い。
ボタンの影にあたるこの部分は、最初の1pxがrgb(192, 192, 192)で残りがrgb(153, 153, 153)になっている。こういうベタ塗り→ベタ塗りの場合は上記のコードまたは以下の例のように、二点間を同じ色にしてしまえば良い。
linear-gradient(
top,
red 0px, red 3px,
green 3px, green 6px,
blue 6px, blue 9px
)
この例では上から1~3pxまでは赤(red)、4~6pxまでは緑(green)、7~9pxまでは青(blue)でそれぞれベタに塗られることになる。このようにグラデーションの開始と終了を同じ行に書いたりすると少しは見やすく、あとで読んでも分かりやすくなると思う。
またbackground-positionでright top、background-sizeで1px 31pxをそれぞれ指定することによって右端の縦方向に1pxの線を引くような感じにする。
background-image: linear-gradient(
top,
rgb(192, 192, 192) 0px, rgb(192, 192, 192) 1px,
rgb(153, 153, 153) 1px, rgb(153, 153, 153) 31px
);
background-position: right top;
background-size: 1px 31px;
ボタンの影にあたる部分のコードをまとめると以上のようになる。
グラデーションの構成はベタ塗り(rgb(255, 255, 255))→グラデーション(rgb(241, 241, 241) ~ rgb(223, 223, 223))→ベタ塗り(rgb(215, 215, 215))→ベタ塗り(rgb(153, 153, 153))なので、linear-gradient()のコードは以下のようになる。
linear-gradient(
top,
rgb(255, 255, 255) 0px, rgb(255, 255, 255) 1px, /* 1px目(最初)はベタ塗り */
rgb(241, 241, 241) 1px, rgb(223, 223, 223) 29px, /* 2~29pxがグラデーション */
rgb(215, 215, 215) 29px, rgb(215, 215, 215) 30px, /* 30px目はベタ塗り */
rgb(153, 153, 153) 30px, rgb(153, 153, 153) 31px /* 31px目(最後)もベタ塗り */
)
上端と左端で説明済みのように開始位置を左上から右に1px下に1pxにして背景色を一部見えるようにしたいので、
background-position: 1px 1px;
このグラデーションのサイズはボックスのサイズに従ってフレキシブルに変化して欲しいので、
background-size: auto;
これらのプロパティを既にポイントとして説明した複数の値が取れることを利用して、すぐ前の右端から1px手前でまとめたコードのbackground-*プロパティそれぞれに,(カンマ)で区切って追加することになる。
background-image: linear-gradient(
top,
rgb(192, 192, 192) 0px, rgb(192, 192, 192) 1px,
rgb(153, 153, 153) 1px, rgb(153, 153, 153) 31px
),
linear-gradient(
top,
rgb(255, 255, 255) 0px, rgb(255, 255, 255) 1px,
rgb(241, 241, 241) 1px, rgb(223, 223, 223) 29px,
rgb(215, 215, 215) 29px, rgb(215, 215, 215) 30px,
rgb(153, 153, 153) 30px, rgb(153, 153, 153) 31px
);
background-position: right top, 1px 1px;
background-size: 1px 31px, auto;
複数の値を指定した場合に先に書いた方が手前に来るのは覚えていたほうが良い。つまり、
background-image: url("front.png"), url("back.png");
だとfront.pngがback.pngの上になる。
最後に上端と左端のコードや右端と下端のコード、その他paddingやheight、font-*などをGoogleの検索ボタンと同じようにすれば良い。
Safari 5など古いWebKitのブラウザでは-webkit-linear-gradientはないので、-webkit-gradient(linear)を使うことになる。この場合色指定をcolor-stop()で行うのだが、これにはpx単位での位置指定が出来ないので計算機で頑張って計算してください。詳しくはデモのソースを参照。
calc(1/33)とかcalc(100% - 1px)とか早く気軽に使えるようになるといいな。