CSS3のプロパティtransformやtransitionを用いると、要素をアニメーションさせたり変形することができます。Lopan.jp「動くCSSのためのメモ。」はさまざまな作例で、CSS3の効果を解説しています。それらを参考に、イメージとテキストが組合わったサンプルを3つつくりました。いずれも、マウスポインタを画像に重ねると、それを説明するテキストが表れます(サンプル001)。JavaScriptコードは書いていません。
サンプル001■CSS3: Showing texts over images on rollover
*デフォルトの画面は少し狭いので、フルスクリーンにすると全体が見えます。
01 画像の上にテキストが広がる
初めのサンプルは、画像にマウスポインタを重ねたら、テキストが真ん中から広がって表れるようにします。画面に置く画像とテキストの要素は、つぎのようにリストで組立てます。li要素にはclass属性(type1)を定めました。テキストはさらに説明リスト要素(dl要素)として加えています。
<ul>
<li class="type1">
<img src="images/ActionScript_30_Performance_Tuning.jpg">
<dl>
<dt>ActionScript 3.0<br>
パフォーマンス<br>
チューニング</dt>
<dd>3Dグラフィックス・Flashゲームから最大限のパフォーマンスを引き出せ!</dd>
<dd><a href="http://fumiononaka.com/Books/ActionScript_30_Performance_Tuning.html" target="_blank">More info</a></dd>
</dl>
</li>
</ul>
|
アニメーションなどの手を加える前に、以下のCSSで静的にテキスト(dl要素)をリストの画像と同じ大きさに定めました(図001)。なお、行頭の番号は後にCSSの定めをまとめたコード001にもとづきます。
図001■CSSで定めた画像とテキストの静的なレイアウト
- body {
- background: #deddcd;
- font-family: "ヒラギノ角ゴ Pro W3", "Hiragino Kaku Gothic Pro", "メイリオ", Meiryo, Osaka, "MS Pゴシック", "MS PGothic", sans-serif;
- }
- a {
- color: whitesmoke;
- }
- a:hover {
- color: yellow;
- text-decoration: none;
- }
- ul {
- list-style: none;
- top: 0;
- height: 200px;
- margin: 50px 0px;
- padding: 0;
- text-align: center;
- }
- ul li,
- ul li dl {
- width: 160px;
- height: 200px;
- }
- ul li {
- display: inline-block;
- position: relative;
- margin: 0 5px;
- }
- ul dl {
- margin: 0;
- padding: 20px 10px;
- color: white;
- background: rgba(205,92,92, 0.75);
- }
- ul dl dt {
- margin-bottom: 0.5em;
- }
- ul dl dd {
- margin: 0;
- font-size: 10px;
- line-height: 1.6em;
- text-align: justify;
- word-break: break-all;
- }
- ul dl dd:last-of-type {
- margin-top: 10px;
- text-align: right;
- }
- ul a {
- padding: 0.3em 0.5em;
- background-color: #7a3f3a;
- }
|
さて、テキストをリストの画像と重ねましょう(図002)。そのためには、以下のようにCSSでdl要素のpositionプロパティをabsoluteとし、topプロパティの値は0に定めます(第32〜33行目)。
図002■CSSで画像にテキストの領域が重ねられた
- ul dl {
- box-sizing: border-box;
- position: absolute;
- top: 0;
- }
|
要素の大きさを揃えるには、box-sizingプロパティを使うと便利です(「レスポンシブデザインに便利!今さらCSS3のbox-sizingについて話してみます」参照)[*1]。CSSのボックスにはいくつかの領域があります(「Box model」参照)。box-sizingプロパティにより、ボックスサイズを定めるwidthおよびheightプロパティに含める領域が選べます(表001)。ここではborder-boxとしました(第31行目)。
box-sizing: ボックスサイズの計算方法
表001■ボックスサイズの計算に含まれる領域
ボックスサイズの計算方法
|
padding
|
border
|
margin
|
content-box(デフォルト)
|
×
|
×
|
×
|
padding-box
|
○
|
×
|
×
|
border-box
|
○
|
○
|
×
|
inherit
|
親要素を継承
|
いよいよ、画像にマウスポインタを重ねたら、テキストが真ん中から広がって表れるようにします。transformプロパティは、2次元または3次元の空間で座標を変換します(MDN「CSS transforms の利用」参照)。プロパティには、つぎのようにtransform-function(変換関数)を定めます(表002)。伸縮に用いるのは、scale()関数です。
transform: 変換関数
表002■おもな2次元のCSS変換関数
変換関数
|
変換
|
rotate(angle) |
時計回りに引数の角度回す。
|
scale(sx[, sy]) |
引数の比率だけ水平および垂直に伸縮する。引数がひとつのときは、水平と垂直は同じ比率とされる。
|
translate(tx[, ty]) |
引数の値だけ水平および垂直に移動する。引数がひとつのときは、垂直の移動値は0とされる。
|
そして、アニメーションはtransitionプロパティで与えます。アニメーションの仕方は、いくつかのプロパティで変えられます(MDN「CSS transition の使用」)。もっとも、それぞれにデフォルト値が与えられていますので、アニメーションにかける時間だけ定めれば済む場合が多いでしょう。
transition: 時間
このお題では以下のCSSのように、dl要素(クラスtype1)に不透明度と変形のアニメーションを加えました(図003)。テキストのdl要素は、初めopacityプロパティが0で透明、transformプロパティではscale()関数で伸縮率が水平0.75で垂直0につぶされています(第58〜59行目)。そして、transitionプロパティでアニメーションを0.5秒間にしました(第60行目)。マウスポインタを重ねると:hover疑似クラスの定めにより、テキストのdl要素は真ん中から広がりながら(伸縮率水平1・垂直1)透明から不透明(opacity値1)に変わってゆきます(第63〜64行目)。
図003■画像にマウスポインタを重ねるとテキストが不透明度を増しながら真ん中から広がる
|
→ |
|
- .type1 dl {
- opacity: 0;
- transform: scale(0.75, 0);
- transition: 0.5s;
- }
- .type1:hover dl {
- opacity: 1;
- transform: scale(1, 1);
- }
|
ここまでのCSSの定めをまとめたのが、つぎのコード1です。画像の領域にマウスポインタを重ねると、その真ん中からテキストが広がり、透明度を増して表れます(前掲図003)。
コード001■画像にロールオーバーすると真ん中からテキストが広がって表れる
- body {
- background: #deddcd;
- font-family: "ヒラギノ角ゴ Pro W3", "Hiragino Kaku Gothic Pro", "メイリオ", Meiryo, Osaka, "MS Pゴシック", "MS PGothic", sans-serif;
- }
- a {
- color: whitesmoke;
- }
- a:hover {
- color: yellow;
- text-decoration: none;
- }
- ul {
- list-style: none;
- top: 0;
- height: 200px;
- margin: 50px 0px;
- padding: 0;
- text-align: center;
- }
- ul li,
- ul li dl {
- width: 160px;
- height: 200px;
- }
- ul li {
- display: inline-block;
- position: relative;
- margin: 0 5px;
- }
- ul dl {
- box-sizing: border-box;
- position: absolute;
- top: 0;
- margin: 0;
- padding: 20px 10px;
- color: white;
- background: rgba(205,92,92, 0.75);
- }
- ul dl dt {
- margin-bottom: 0.5em;
- }
- ul dl dd {
- margin: 0;
- font-size: 10px;
- line-height: 1.6em;
- text-align: justify;
- word-break: break-all;
- }
- ul dl dd:last-of-type {
- margin-top: 10px;
- text-align: right;
- }
- ul a {
- padding: 0.3em 0.5em;
- background-color: #7a3f3a;
- }
- .type1 dl {
- opacity: 0;
- transform: scale(0.75, 0);
- transition: 0.5s;
- }
- .type1:hover dl {
- opacity: 1;
- transform: scale(1, 1);
- }
|
[*1] CSS3の機能は、ブラウザとそのバージョンによってはベンダー接頭辞を加えなければなりません。たとえば、WebKit系なら-webkit-、Mozilla系は-moz-などです。本稿では、JavaScriptライブラリ「Prefix free」を用いることにより、ベンダー接頭辞は省きました(図004)。ベンダー接頭辞は、Prefix freeが自動的につけてくれるのです(「CSS3: 3次元空間に立方体をつくって回す ー transformプロパティ」02「CSSプロパティのベンダー接頭辞と『Prefix free』」参照)。
<script src="lib/prefixfree.min.js"></script>
|
図004■Prefix freeサイト
|
02 背中合わせの画像とテキストを水平に回す
つぎのサンプルは、画像の後ろにテキストを背中合わせに隠し、マウスポインタが重なったら水平に裏返してテキストを示します。HTMLのリストに加える画像とテキストの要素は、つぎのように前述01「画像のうえにテキストが広がる」と同じ組立てです。li要素には新たなclass属性(type2)を定めました。
<ul>
<li class="type1">
<!-- [中略] -->
</li>
<li class="type2">
<img src="images/CreateJS_Style_Book_157x200.png">
<dl>
<dt>Webクリエイター<br>
のためのCreateJS<br>
スタイルブック</dt>
<dd>JavaScript + HTML5で作るアニメーション/インタラクティブコンテンツ</dd>
<dd><a href="http://fumiononaka.com/Books/CreateJS_Style_Book.html" target="_blank">More info</a></dd>
</dl>
</li>
</ul>
|
要素をy軸で水平に回すには、transformプロパティにrotateY()関数で角度を与えます(表003)。ただし、transformプロパティを定めただけでは、水平に伸び縮みしているようにしか見えません(図005左)。以下のCSSのように、perspectiveプロパティで遠近感を与えなければならないのです(第68行目)。なお、行番号は後にまとめて掲げるコード002にもとづきます。
表003■おもな3次元のCSS変換関数
変換関数
|
変換
|
rotateX(angle)
rotateY(angle)
rotateZ(angle)
|
xyz各軸を中心に引数の角度回す。
|
scaleX(scale)
scaleY(scale)
scaleZ(scale)
|
xyz各軸の方向に引数の比率伸縮する。
|
translateX(length)
translateY(length)
translateZ(length)
|
xyz各軸の方向に引数の値移動する。
|
図005■perspectiveプロパティで遠近感が加わる
perspectiveプロパティに定める数値は、カメラのレンズの焦点距離に当たります。値が小さいほど、遠近の差が際立ちます(ニコンイメージング「遠近感(パースペクティブ)」参照)。また、transform-styleプロパティをpreserve-3dとして、3次元座標空間の扱いであることを示します(第69行目)。これで、遠近感の加わった3次元表現になりました(図005右)。
- .type2 {
- overflow: visible;
- perspective: 400px;
- transform-style: preserve-3d;
- }
- .type2 img,
- .type2 dl {
- transition: 0.8s;
- }
- .type2:hover img {
- transform: rotateY(180deg);
- }
- .type2 dl {
- background-color: #cd5c5c;
- transform: rotateY(-180deg);
- }
- .type2:hover dl {
- transform: rotateY(0);
- }
|
3次元の表現でふたつのものが重なるときは、気をつけなければならないことがあります。どちらを手前にすればよいのか、さらにそれをどうやって決めるかです。ふたつの背中合わせの要素を水平に回したときは、90度ごとに前後が入れ替わります。回転角を考えなければならないとなると厄介です。けれど実は、便利なプロパティがあります。
backface-visibilityプロパティは要素が裏返ったとき、見せる(visible)か隠す(hidden)かを定めます。以下のCSSのようにbackface-visibilityプロパティにhiddenを与えれば、裏返った要素は見えなくなります(第74行目)。つまり、ふたつの要素が回ったとき、ひとつが裏返った瞬間に消え、表になったもうひとつが表れます。このお題のCSSは、以下のコード002にまとめました。
- .type2 img,
- .type2 dl {
- backface-visibility: hidden;
- }
|
コード002■画像にロールオーバーすると水平に回って背中合わせのテキストが表れる
- body {
- background: #deddcd;
- font-family: "ヒラギノ角ゴ Pro W3", "Hiragino Kaku Gothic Pro", "メイリオ", Meiryo, Osaka, "MS Pゴシック", "MS PGothic", sans-serif;
- }
- a {
- color: whitesmoke;
- }
- a:hover {
- color: yellow;
- text-decoration: none;
- }
- ul {
- list-style: none;
- top: 0;
- height: 200px;
- margin: 50px 0px;
- padding: 0;
- text-align: center;
- }
- ul li,
- ul li dl {
- width: 160px;
- height: 200px;
- }
- ul li {
- display: inline-block;
- position: relative;
- margin: 0 5px;
- }
- ul dl {
- box-sizing: border-box;
- position: absolute;
- top: 0;
- margin: 0;
- padding: 20px 10px;
- color: white;
- background: rgba(205,92,92, 0.75);
- }
- ul dl dt {
- margin-bottom: 0.5em;
- }
- ul dl dd {
- margin: 0;
- font-size: 10px;
- line-height: 1.6em;
- text-align: justify;
- word-break: break-all;
- }
- ul dl dd:last-of-type {
- margin-top: 10px;
- text-align: right;
- }
- ul a {
- padding: 0.3em 0.5em;
- background-color: #7a3f3a;
- }
- .type1 dl {
- opacity: 0;
- transform: scale(0.75, 0);
- transition: 0.5s;
- }
- .type1:hover dl {
- opacity: 1;
- transform: scale(1, 1);
- }
- .type2 {
- overflow: visible;
- perspective: 400px;
- transform-style: preserve-3d;
- }
- .type2 img,
- .type2 dl {
- transition: 0.8s;
- backface-visibility: hidden;
- }
- .type2:hover img {
- transform: rotateY(180deg);
- }
- .type2 dl {
- background-color: #cd5c5c;
- transform: rotateY(-180deg);
- }
- .type2:hover dl {
- transform: rotateY(0);
- }
|
03 画像の両外から幕が開閉するようにテキストの表示を切替える
3つ目のサンプルは、ポインタを重ねると画像の左右から幕が閉じるようにしてテキストが表れ、外すと開いて消えます。HTMLのリストに加える画像とテキストの要素は、つぎのように前のふたつと同じ組立てです。li要素にはまた新たなclass属性(type3)を定めました。
<ul>
<li class="type1">
<!-- [中略] -->
</li>
<li class="type2">
<!-- [中略] -->
</li>
<li class="type3">
<img src="images/ActionScript30for3D.png">
<dl>
<dt>ActionScript 3.0<br>
による三次元表現<br>
ガイドブック</dt>
<dd>Flashコンテンツに3次元空間の表現力を加えるためのテクニックを完全解説</dd>
<dd><a href="http://fumiononaka.com/Books/ActionScript30for3D.html" target="_blank">More info</a></dd>
</dl>
</li>
</ul>
|
画像の左右から閉じる幕は、疑似要素::beforeと::afterでつくります[*2]。これらの疑似要素は、選ばれた要素の子要素として前(::before)後(::after)に加えられます。かたちとして使いたい要素を定めるのに便利です。
初めに幕は開いておきます(図006)。以下のCSSのように幕の幅は画像の半分、高さは同じに揃えます(第109〜110行目)。そして、transformプロパティでは、skewX()関数で水平に傾けたうえ、translateX()関数を用いて画像の外側に開きます(第121および第124行目)。
図006■幕の疑似要素を水平に傾けて外側に開く
- .type3 dl {
- background-color: transparent;
- }
- .type3 dl::before,
- .type3 dl::after {
- content: "";
- display: block;
- position: absolute;
- top: 0;
- left: 0;
- width: 80px;
- height: 200px;
- background: indianred;
- opacity: 0.75;
- }
- .type3 dl::before {
- transform: translateX(-135px) skewX(-30deg);
- }
- .type3 dl::after {
- transform: translateX(215px) skewX(-30deg);
- }
|
画像にマウスポインタを重ねたら幕が閉じ、その前にテキストが表れるようにします(図007)。CSSは以下のように:hover疑似クラスで、ふたつの疑似要素(::beforeと::after)の傾き(skewX()関数)をまっすぐに戻して、画像が覆われるように水平位置(translateX()関数)を定めます(第127および第130行目)。
図007■閉じた幕の前にテキストが表れる
- .type3:hover dl::before {
- transform: translateX(0) skewX(0);
- }
- .type3:hover dl::after {
- transform: translateX(80px) skewX(0);
- }
|
もっとも、これだけではテキスト(要素dtとdd)がふたつの疑似要素の手前に出てきません。要素の重ね順はz-indexプロパティに整数値を与えて定めます。ただし、このときpositionプロパティは、デフォルトのstatic以外にしなければならないことに気をつけましょう(スタイルシートリファレンス「z-index」参照)。以下のCSSは、positionプロパティをrelativeとし、z-indexには整数1を与えました(第92〜93行目)。
もうひとつ、画像の外側に出た幕の疑似要素は隠しましょう。要素のoverflowプロパティをhiddenに定めると、外にはみ出したコンテンツは見えなくなります(第28行目)。
- ul li {
- overflow: hidden;
- }
- .type3 dl dt,
- .type3 dl dd {
- position: relative;
- z-index: 1;
- }
|
幕の開け閉めはできましたので、transitionプロパティで動きをアニメーションにします。以下のCSSは前述の幕の疑似要素の動きに加えて、テキストは透明から不透明に変えました(第94および第99行目)。幕も初めは透明にしておきます(第112行目)。
このお題では、アニメーションを少し細かく変えてみました。transitionプロパティには、つぎの4つの値が与えられます。そして、それぞれについて別に定められたプロパティで値を変えることもできます(表004)。
transition 対象プロパティ 時間 タイミング関数 開始待ち時間
表004■transitionの仕方を個別に定めるプロパティ
transitionを定めるプロパティ
|
定める値
|
デフォルト値
|
transition-property
|
アニメーションさせる対象のプロパティ。
|
all
|
padding-box
|
アニメーションにかける時間。
|
0s
|
transition-timing-function
|
値の変わり方を定めるタイミング関数。 |
ease
|
transition-delay
|
アニメーションを始めるまでに待つ時間。
|
0s
|
透明のテキスト(要素dtとdd)が表れるアニメーションには、transition-delayプロパティで少しタメを入れました(第100行目)。また、マウスポインタを重ねた:hover疑似クラスで、幕(疑似要素::beforeと::after)のアニメーションはtransition-durationプロパティで少し時間を縮めました(第118行目)。したがって、幕は閉じる方が開くときより速くなります。
- .type3 dl dt,
- .type3 dl dd {
- opacity: 0;
- transition: 0.8s;
- }
- .type3:hover dl dt,
- .type3:hover dl dd {
- opacity: 1;
- transition-delay: 0.3s;
- }
- .type3 dl::before,
- .type3 dl::after {
- opacity: 0; /* 0.75; */
- transition: 0.8s;
- }
- .type3:hover dl::before,
- .type3:hover dl::after {
- opacity: 0.75;
- transition-duration: 0.5s;
- }
|
これで、画像にマウスポインタを重ねると両側から閉じる幕の上にテキストが表れ、ポインタを外せば幕が開いてテキストは消えます。ここまでのすべてのCSSをまとめたのが、つぎのコード003です。初めに掲げたサンプル001にはこのCSSが定められています。
コード003■画像にロールオーバーすると両側から閉じる幕の上にテキストが表れる
- body {
- background: #deddcd;
- font-family: "ヒラギノ角ゴ Pro W3", "Hiragino Kaku Gothic Pro", "メイリオ", Meiryo, Osaka, "MS Pゴシック", "MS PGothic", sans-serif;
- }
- a {
- color: whitesmoke;
- }
- a:hover {
- color: yellow;
- text-decoration: none;
- }
- ul {
- list-style: none;
- top: 0;
- height: 200px;
- margin: 50px 0px;
- padding: 0;
- text-align: center;
- }
- ul li,
- ul li dl {
- width: 160px;
- height: 200px;
- }
- ul li {
- display: inline-block;
- position: relative;
- overflow: hidden;
- margin: 0 5px;
- }
- ul dl {
- box-sizing: border-box;
- position: absolute;
- top: 0;
- margin: 0;
- padding: 20px 10px;
- color: white;
- background: rgba(205,92,92, 0.75);
- }
- ul dl dt {
- margin-bottom: 0.5em;
- }
- ul dl dd {
- margin: 0;
- font-size: 10px;
- line-height: 1.6em;
- text-align: justify;
- word-break: break-all;
- }
- ul dl dd:last-of-type {
- margin-top: 10px;
- text-align: right;
- }
- ul a {
- padding: 0.3em 0.5em;
- background-color: #7a3f3a;
- }
- .type1 dl {
- opacity: 0;
- transform: scale(0.75, 0);
- transition: 0.5s;
- }
- .type1:hover dl {
- opacity: 1;
- transform: scale(1, 1);
- }
- .type2 {
- overflow: visible;
- perspective: 400px;
- transform-style: preserve-3d;
- }
- .type2 img,
- .type2 dl {
- transition: 0.8s;
- backface-visibility: hidden;
- }
- .type2:hover img {
- transform: rotateY(180deg);
- }
- .type2 dl {
- background-color: #cd5c5c;
- transform: rotateY(-180deg);
- }
- .type2:hover dl {
- transform: rotateY(0);
- }
- .type3 dl {
- background-color: transparent;
- }
- .type3 dl dt,
- .type3 dl dd {
- position: relative;
- z-index: 1;
- opacity: 0;
- transition: 0.8s;
- }
- .type3:hover dl dt,
- .type3:hover dl dd {
- opacity: 1;
- transition-delay: 0.3s;
- }
- .type3 dl::before,
- .type3 dl::after {
- content: "";
- display: block;
- position: absolute;
- top: 0;
- left: 0;
- width: 80px;
- height: 200px;
- background: indianred;
- opacity: 0;
- transition: 0.8s;
- }
- .type3:hover dl::before,
- .type3:hover dl::after {
- opacity: 0.75;
- transition-duration: 0.5s;
- }
- .type3 dl::before {
- transform: translateX(-135px) skewX(-30deg);
- }
- .type3 dl::after {
- transform: translateX(215px) skewX(-30deg);
- }
- .type3:hover dl::before {
- transform: translateX(0) skewX(0);
- }
- .type3:hover dl::after {
- transform: translateX(80px) skewX(0);
- }
|
[*2] 疑似要素::beforeと::afterは、:beforeおよび:afterと書くこともできます。2コロン(::)の書き方は、疑似クラスと見分けがつきやすいように、CSS3から定められました。
|
作成者: 野中文雄
作成日: 2015年3月31日