トップページのCSS3効果②
内容
CSS3効果
さて、ここからが本題のCSS3効果です。CSS3のスタイル指定は、a要素にのみ行っています。
ノーマル時のスタイル
ナビゲーションボタンには、マウスがボタンに乗った時に見た目が変化する、いわゆるロールオーバー効果を適用しています。ですから、スタイル指定は、ノーマル時とオーバー時の指定に分かれます。では、ノーマル時の指定から見ていきましょう。
#top_topnav li a {
border-radius:64px;
color:rgba(240,240,240,0.6);
background-color:rgba(0,0,0,0.1);
text-shadow:0px 0px 6px rgba(0,0,0,0.7);
box-shadow:0px 0px 12px 1px rgba(255,255,255,0.5), inset 0px 0px 8px 1px rgba(0,0,0,0.4), inset 0px 8px 12px rgba(255,255,255,0);
}
border-radius
まずborder-radiusプロパティで、ボタンの左右が半円状になるように、角丸を指定しています。横長のボックスの場合、角を半円にするには高さの1/2サイズを、角丸半径として指定します。
しかし、ボタンの高さは、文字サイズ+上下のpaddingで決まっていますが、それらはすべてem値を使っているため、指定からは正確なサイズは分かりません。IE開発者ツールで実サイズを計測することも可能ですが、半円の場合、1/2よりも大きな数を指定しても、形が崩れることはありません。ですので、ほぼ確実に1/2を超える64ピクセルという数値を指定しています。
透明カラー
colorプロパティは文字色の指定ですが、ここでは透明色にするため、rgba関数を使っています。同様に、backgroud-colorによる背景色も、rgba関数による透明色です。
text-shadow
その文字を少し浮き立たせるため、周囲にtext-shadowプロパティでドロップシャドウを適用しています。初めの2つの値は、影の左右、上下のオフセットを表します。ともに0にし、3つ目の値でぼかしをかけることで、周囲に影(明るい色であれば光彩)が広がるグロウ効果を得ています。最後の値は色指定で、ここでもrgba関数による透明色を使っています。
これらの値の役割は、box-shadowプロパティと同じですが、text-shadowには影の拡張(スプレッド)を指定する値は存在しません。
box-shadow
最後に、ボックスの輪郭を際立たせているのが、box-shadowプロパティです。ここでは、外側に1つ、内側に2つの指定を行っています。
ひとつ目の「0px 0px 12px 1px rgba(255,255,255,0.5)」が、外側に白いグロウ効果をかけている指定です。4つ目の値で、影を外側に1ピクセル拡張し、そのうえで12ピクセルのぼかしをかけています。色は白の半透明色ですから、しろくぼやけた“影”が周囲に付くことで、ボタンの縁を、背景の画像の白っぽさに加味して、浮き上がらせています。
あとは、内側に黒いグロウ効果を付けることで、ボタンがへこんでいるように演出していますが、その指定が「inset 0px 0px 8px 1px rgba(0,0,0,0.4)」です。
では、3つ目の「inset 0px 8px 12px rgba(255,255,255,0)」は何でしょう? これは、ボタン上辺から内側に8ピクセル下へ伸びる、白い“影”です。しかし、不透明度で0を指定してあるため完全に透明になり、当然、見えません。なんだか、無駄な指定のようです。が、しかし、この指定もきちんと役立っているのです。その理由は後のお楽しみにしておきましょう。
オーバー時のスタイル
オーバー時を、擬似クラスhoverを使ったセレクターで特定するのは、CSS2と3に違いはありません。
なお、キーボード(tabキー)で選択した時も同じ設定にするため、active、focusの擬似クラスも実際には指定していますが、ソースコードをわかりやすくするため、以下の例示では省いてあります。
#top_topnav li a:hover {
color:rgba(0,0,0,0.6);
box-shadow:0px 0px 12px 1px rgba(255,255,255,0.4), inset 0px 0px 8px 1px rgba(0,0,0,0.9), inset 0px 8px 12px rgba(255,255,255,0.6);
-webkit-transform:scale(1.15);
transform:scale(1.15);
}
colorの変化
まず、文字の色(color)は、黒の透明色に変わるようにしてあります。
box-shadowの変化
次いで、ドロップシャドウ(box-shadow)は、外側の白いぼかしを不透明度0.4に下げることで、その効果を抑制しています。逆に、内側の黒い影は、不透明度を0.9に上げ、強調しています。そして、3つ目の白い影も、不透明度を0から0.6に上げることで、見えるようにしてあります。この白い影が、ボタン上部にかかることによって、へこんでいたものが、逆に浮き出ているように見えるはずです。
こうした効果は、上部が白(明るい)色で、下部が濃い(暗い)色になるグラデーションで、表現することができます。もちろん、CSS3ではグラデーションによる背景色(background-image)が指定できるので、それを使うこともできます。ただし、IE9はグラデーションに対応していないので、IE9が対応しているドロップシャドウを利用して、こうしたグラデーションに相当する効果を得たわけです。
transform
さらに、オーバー時にはボタンのサイズを拡大しています。それには、幅や高さを指定するのではなく(そもそも、今回のボタンには幅や高さを指定していません)、transformプロパティのscale関数を使って、1.15倍に拡大しています。transformプロパティは、対象要素の拡大/縮小(scale)、回転(rotate)、斜変形(skew)、移動(translate)といった変形を指定可能です。
移動(2D) | |
---|---|
translate(x, y) | 対象を移動。引数はX、Y方向の移動距離 |
translateX(距離) | 対象をX方向に移動。引数は移動距離 |
translateY(距離) | 対象をY方向に移動。引数は移動距離 |
移動(3D) | |
translateZ(距離) | 対象をZ方向に移動。引数は移動距離 |
translate3d (x, y, z) |
対象を3次元で移動。引数はX、Y、Z方向の移動距離 |
回転(2D) | |
rotate(角度) | 対象を回転。引数は回転角度 |
回転(3D) | |
rotateX(角度) | 対象をX軸で回転。引数は回転角度 |
rotateY(角度) | 対象をY軸で回転。引数は回転角度 |
rotateZ(角度) | 対象をZ軸で回転。引数は回転角度 |
rotate3d (番号x, 番号y, 番号z, 角度) |
対象を3D回転。引数は各軸につき番号0で不使用、1で使用、そして共通の回転角度を指定する |
拡大縮小(2D) | |
scale(x, y) | 対象を拡大・縮小。引数はXおよびY方向の倍率を0~1で指定 |
scaleX(倍率) | 対象をX方向に拡大・縮小。引数倍率を0~1で指定 |
scaleY(倍率) | 対象をY方向に拡大・縮小。引数倍率を0~1で指定 |
拡大縮小(3D) | |
scaleZ(倍率) | 対象をZ方向に拡大・縮小。引数倍率を0~1で指定 |
scale3d(x, y, z) | 対象をX、Y、Z方向に拡大・縮小。引数倍率を0~1で指定 |
斜変形(2Dのみ) | |
skew(x, y) | 対象を斜変形。引数はX、Y軸で傾ける角度 |
skewX(角度) | 対象をX軸で斜変形。引数は傾ける角度 |
skewY(角度) | 対象をY軸で斜変形。引数は傾ける角度 |
また、変形の原点は、デフォルトで対象要素の中心点に設定されています。ですから、ボタンを中心から上下左右に拡大させることが、できているのです。なお、変形の原点はtransform-originで変更可能です。デフォルトで中心点になっているのは、transform-origin:center centerという指定になっているということです。
オーバー時の背景色
nth-of-type
さて、各ボタンは、オーバー時に背景色も変わるようになっています。そして、3つの色が使われています。この3色を交互に指定するため、以下のようなセレクターを使っています。
#top_topnav li:nth-of-type(odd) a:hover {
background-color:hsla(280,100%,70%,0.2);
}
#top_topnav li:nth-of-type(even) a:hover {
background-color:hsla(240,90%,70%,0.2);
}
#top_topnav li:nth-of-type(3n+0) a:hover {
background-color:hsla(320,80%,70%,0.2);
}
この、nth-of-typeという擬似クラスは、同じ親要素を持つ、兄弟要素をまず特定します。この例では、親要素top_topnavの中に入っている、li要素ということになります。それだけなら、#top_topnav liでも特定できますが、nth-of-typeの特徴は、その後ろの()の中にあります。最初のセレクターでは、oddと記述されていますが、これは奇数を意味します。ですから、top_topnavの中のli要素のうち、奇数個目のli要素だけを特定できます。同様にevenは、偶数を意味します。
そして、最後の3n+0は、「an+b」式と呼ばれるものです。このうち、nは0から1ずつ増えていく、決められた値です。いわゆる、インクリメントです。あとは、aとbに任意の数値を指定できるのですが、ここではaが3、bが0です。すると、以下のような計算が繰り返されることになります。
3×0+0=0(該当無し)
3×1+0=3
3×2+0=6
つまり、0から始まって、3つおきのli要素を特定できるわけです。aは幾つおきか、bは何個目から始めるのか、を意味しています。
今回のボタンは、全部で7つありますから、1個目と5個目と7個目(odd)、2個目と4個目(even)、3個目と6個目(3n+0)に、それぞれ異なる背景色を指定したことになります。
HSLカラーモード
その背景色ですが、もちろんbackground-colorで指定していますが、値の関数はrgbaではなく、hslaです。aは、どちらも不透明度を表しますが、HSLは色彩理論の色相(Hue)・彩度(Saturation)・明度(Lightness)に基づく色指定です。
色相は、色の種類を意味し、RYGCBMRの色変化を時計回りで円周上にならべた色相環で表します。ですから、色は0~360度の角度で指定することになります。
彩度は、色の鮮やかさで、100%で最も鮮やかになり、それが色相の色(純色)になります。0%では色が無くなり、白、グレー、もしくは黒(無彩色)になります。
明度は、色の明るさで、100%で白、50%で純色、0%で黒になります。つまり、彩度が0%の場合、明度によってグレーのレベルが決まるのです。また、彩度100%かつ明度50%のときに、純色になります。たとえば赤の純色(rgb255,0,0)はhsl(0,100%,50%)で表されます。
ちなみにCorelDRAWでは、HSLをHLSの順で表していますが、各値をCSS上では入れ替えて指定すればOKです。
似たようなカラーモデルとしてHSBがありますが、Bは輝度(Brightness)になります。同様に明るさを定義するものですが、輝度は100%で純色を表すため、その数値を明度に直接置き換えることはできません。たとえば、Illustrator CS5(CS6のとこは知りません)は、偉そうなくせに、HSLもしくはHLSには非対応で、HSBしか使えません。情けないですね。
transition
以上が、CSS3の視覚効果なのですが、ナビゲーションボタンはマウスオーバー時に、若干の時間をかけて色やサイズの変化を行っています。IE9は、そうした効果に対応していないので、パッと変化するだけですが、IE10や他の最新ブラウザーの場合、変化には0.8秒かかっています。マウスが離れ、元の状態に戻る時も同様です。これが、transitionという効果です。
transitionの指定方法
transitionは、以下のように、ノーマル状態を定義した要素の側に指定します。
#top_topnav li a {
-webkit-transition-property:color, background-color, box-shadow, -webkit-transform;
transition-property:color, background-color, box-shadow, transform;
transition-duration:0.8s;
}
指定は簡単で、まずtransition-propertyプロパティで、変化させるスタイルのプロパティ名を値に記述します。ここでは、以下の4つを指定しています。
- color
- background-color
- box-shadow
- transform
複数のプロパティを列挙する場合は、カンマ(,)で区切ります。
そして、transition-durationプロパティで、変化にかける時間を指定しています。単位sは「秒」で、0.8秒かけて各プロパティを、ノーマル時の値からオーバー時の値へ変化させることになります。時間の単位には、千分の1秒を表すミリ秒(ms)も使用できます。
ですから、各値は、数値的に連続した変化を持たせられるものでなければなりません。たとえば内側の白いドロップシャドウの場合、ノーマル時がinset 0px 8px 12px rgba(255,255,255,0)、オーバー時がinset 0px 8px 12px rgba(255,255,255,0.6)ですが、色の不透明度が0から0.6へ徐々に変化することになります。
実はこれが、ノーマル時に、不透明度0の見えもしない白い影を指定した理由です。変化後の値には、それと対になる変化前の値が必要だったのです。
こうした変化ですから、たとえばdiplay:none(非表示)とdisplay:block(ブロックレベル表示)の間で、値を遷移させることはできません。これらの値は二者択一であり、連続した中間状態は存在しないからです。非表示と表示を遷移させるなら、opacityプロパティで不透明度を0~1へ変化させることになります。
その他のtransition関連プロパティ
transitionには、この他、以下のプロパティがあります。
- transition
- 関連プロパティの一括指定用
- transition-delay
- 開始の遅延時間をミリ秒(ms)もしくは秒(s)で指定
- transition-timing-function
- 変化に対するイージング効果を指定。値は以下の表と図を参照
ease | 減速→等速→減速(デフォルト値) |
---|---|
linear | 等速 |
ease-in | 減速→等速 |
ease-out | 等速→減速 |
ease-in-out | 減速→等速(持続時間なし)→減速 |
cubic-bezier (始点制御点X座標, 始点制御点Y座標,終点制御点X座標, 終点制御点Y座標) |
cubic-bezier関数。トーンカーブと似たグラフのベジェ曲線の形状で速度変化を指定。下図参照 |
step-start | steps(1, start)と同等 |
---|---|
step-end | steps(1, end)と同等 |
steps (数値, start/end) |
steps関数。第一引数で1以上の数値、第二引数でstarもしくはendを指定。再生開始後(start)もしくは終了前(end)のタイミングで、再生が第一引数の数値でコマ送りになる。 |
ベンダー接頭辞の必要性
ところで、transition-durationプロパティではベンダー接頭辞を使っていないのに、なぜtransition-propertyではChrome用に-webkit-を付けているのでしょう。Chrome 26は、実際にはtransitionの各プロパティに、ベンダー接頭辞無しで対応しています。
しかし、transition-propertyに使った値のうち、transformにはベンダー接頭辞が必要なのです。これを、ベンダー接頭辞無しのtransition-propertyに入れた場合、なおかつその後ろにtransformがあると、-webkit-transformは打ち消されてしまうのか、Chromeでは動作しなくなります。
transition-property:color, background-color, box-shadow, -webkit-transform, transform;
これらの順序を逆にすれば、実際にはChromeでも他のブラウザーでも問題なく動作しますが、接頭辞無しの次に接頭辞付のものが読み込まれるというのは、ベンダー接頭辞の使い方としては間違っているように思えます。
transition-property:color, background-color, box-shadow, transform, -webkit-transform;
このため、transition-propertyについては、-webkit-付きのものも、現状では併記しているわけです。面倒な話ですね。
まとめ
以上が、トップページのナビゲーションボタンに与えた、CSS3効果の全貌です。基本的な配置やサイズはCSS2の既存のプロパティで行い、視覚的に強調する効果を、主としてCSS3のbox-shadowと透明色で適用しています。角丸を含め、こうした見栄えであれば、画像で表現する必要はほとんどなくなりました。
そして、ロールオーバー時にtransitionプロパティで、一種のアニメーション効果も付与しました。transitionは、事実上、hover“イベント”でのみ有効ですが、JavaScriptに頼らなくても、それよりも簡単に、動的変化を表すことができるのです。