前回のおさらい
前回は、お手本のPure CSS3 Cycle Sliderを参考に、以下の状態まで行いました。
.slide ul{ list-style:none; } .slide ul li{ float:left; width:100px; height:50px; position:relative; overflow:hidden; } .slide ul li h2{ position:absolute; padding:0.5em 1em; background:rgba(0,0,0,0.5); color:#fff; top:0; left:-110%; /* %指定に変更しました */ } .slide ul li:hover h2 { left:0; } .slide.transit ul li h2{ -moz-transition:0.5s; -webkit-transition:0.5s; transition:0.5s; opacity:0; } .slide.transit:hover ul li h2 { left:0px; opacity:1; }
引き続き、以下の通り進めます。
- 各<li>にCSS3のanimationを設定する
- 各<li>にhoverしたらanimationを一時停止させるanimation-play-stateを追加する
- div.progress-barにもanimationを設定する
- 表示させるエリアだけを見せて、他を隠す
各<li>にCSS3のanimationを設定する
transitionとanimationは似ていますが、いくつかの点で大きく異なります。整理してみましょう。
注目ポイント | transition | animation |
---|---|---|
再生秒数の設定 | transition-duration | animation-duration(CSSのショートハンドで指定する場合は先に書かれた秒数)。デフォルトは0秒なので何らかの時間を指定することになる。 |
開始時間を遅らせる | transition-delay | animation-delay(ショートハンドで指定する場合は後に書かれた秒数) |
イージングの使用 | transition-timing-function | animation-timing-function |
変化させるcssプロパティの選択 | transition-property | キーフレームの中で指定する。 |
キーフレームの使用 | できない | animation-nameで指定する。必須。 |
繰り返しの回数の指定 | できない | animation-iteration-count(0以上の整数か、infiniteで永久にループを指定できる) |
繰り返しの方向指定 | できない | animation-direction(normalで毎回0→100%で動く。alternateで、偶数回は100→0%へと逆方向に動く。) |
一時停止 | できない | animation-play-state(runningで動く。pausedで一時停止) |
アニメーションの実行前や実行後のスタイル指定 | できない | animation-fill-mode(none , forwards , backwards , both が指定可能。) |
スライドショーの場合は、ループさせ続ける必要があるので、animationを使用する訳です。div#sampleAnimeをanimationさせてみましょう。
CSS3のanimationの指定は以下の様に行います。
- 動かしたい要素のセレクターにanimationプロパティを指定します。ショートハンドで書くと「キーフレーム名 アニメーションにかかる時間 イージング 遅延時間 繰り返しの回数 再生方向」となります。「キーフレーム名」は必須ですし、再生秒数も書かないと0秒になるので指定します。div#sampleAnimeの設定は以下の通りです(分かり易くする為に、繰り返しの回数をinfiniteにしました)。
#sampleAnime { /* この記事を書いている時点ではベンダープレフィックスが必要 */ -moz-animation:hogehoge 5s infinite; -webkit-animation:hogehoge 5s infinite; animation:hogehoge 5s infinite; }
- キーフレームの書式は以下の通り。一つのkeyframesの中カッコの中に、各タイミングを現す n% をセレクタにした中カッコが入れ子になる構造です。
@keyframes hogehoge { /*@keyframes + 半角スペース + キーフレーム名 として中カッコを開ける*/ 0% { /*開始時の状態を0%で指定して中カッコを開ける*/ margin-left: 10px; /*そのタイミングのcssを指定*/ background-color: #f00; /*複数指定できる。書き方は通常のcssと同じ*/ } /*中カッコを閉じる*/ 20% { /*任意のタイミングを%で指定して中カッコを開ける*/ margin-left: 50px; /*そのタイミングのcssを指定*/ } /*中カッコを閉じる*/ 100% { /*終了時の状態は100%で指定。*/ margin-left: 50px; background-color: #ff0; } } /*@keyframesの中カッコを閉じる*/
@keyframesで、注意すべき事が3つあります。- 各タイミングで指定しなかったプロパティは、変化が継続します。div#sampleAnimeでは、margin-leftは0→20%で10pxから100pxへとアニメーションし、20%→100%では変化しません。20%の時にbackground-colorを書いていないので、background-colorは0→100%にかけて色が変化します。
- この記事を書いている時点では、@keyframesにもベンダープレフィックスをつけたものを用意する必要があります。@-moz-keyframes hogehoge{}、@keyframes hogehoge{}、@keyframes hogehoge{}を用意すれば良いでしょう。animation-nameは同じで大丈夫です。
- この記事を書いている時点では、linear-gradientをanimationすることはできません。また、:afterや:beforeで作った疑似要素はFirefoxならanimationできますが、SafariやChromeではanimationできません。
スライドショーの@keyframes
各スライドの共通の動作は以下の順で行うことにします。
- 右からフレームイン
- ちょっと止まる
- 左へフレームアウト
お手本の@keyframesでは、各スライド毎に別のルールを設定していますが、工夫すれば1つの@keyframesで実装できます。
動作が分かりやすい様に、完成時に表示したいエリアのdiv.maskを追加して、赤いボーダーをつけた状態でアニメーションを表示してみます。
/*ベンダープレフィックスは省略しています。*/ .anime.loop .mask li { position:absolute; top:0; left:100%; /*フレーム「イン」させたいので、left:100%で右側の外に待機*/ animation:slide 12s 0s infinite; /*まず、各スライドに同じ@keyframesで動く様に指示*/ animation-play-state:running; /*webkitの動作が怪しいので追加。*/ } .anime.loop .mask li:nth-of-type(1) { animation-delay:0s;/* 1番目のスライドはすぐにスタート */ } .anime.loop .mask li:nth-of-type(2) { animation-delay:4s;/* 2番目のスライドは4秒後にスタート */ } .anime.loop .mask li:nth-of-type(3) { animation-delay:8s;/* 3番目のスライドは8秒後にスタート */ } /*以下が@keyframes*/ @keyframes slide { 0% {left:100%;opacity:0.5;z-index:10;} /*フレームイン開始*/ 10% {left:0%;opacity:1;} /*(a)全体の1/10秒でフレームイン終了*/ 33.3% {left:0%;opacity:1;z-index:-10;} /*(b)ここまで停止して、フレームアウト開始(b = 100 / スライド数) */ 43.3% {left:-100%;top:0%;opacity:0.5;} /*(c)フレームアウト終了(c = a) */ 50% {left:-100%;top:100%;} /* 分かりやすい様に、見えないエリアで迂回させています */ 70% {left:100%;top:100%;} 80% {left:100%;top:0%;} }
- まず、各スライドに同じ@keyframesで動く様に指定
- その後で遅延時間のanimation-delayだけを個別に変更
一つの@keyframesと、スライド毎のdelayで、全てのスライドの動きを処理しているのが、この設定のミソです。
-moz-と-webkit-のベンダープレフィックス付き@keyframesを用意しても3つで済みます。
以下の計算式で任意のスライド枚数のanimation-delayを求めることができます。
- S(秒) = animation-duration
- N(個)= スライドの総数(2以上の自然数)
- n(番目)= スライドの出現順
- x(秒)= n番目に出現するスライドのanimation-delay
12秒で3個のスライドをループさせる場合の各スライドのanimation-delay
- 1つ目:
- 2つ目:
- 3つ目:
hoverしたらanimationを一時停止させる
animation-play-stateを各<li>のhoverに設定すると、そのスライドのアニメは止まりますが、他のスライドは動き続けます。
/*SAMPLE LI:hover*/ /*これではアニメーションがずれてしまう...*/ .anime.loop.sample6 .mask li:hover{ animation-play-state:paused; }
これでは、hoverの後でアニメがずれてしまうので、どのスライドにhoverしても、全てのアニメーションが止まる様にしなければなりません。そこで、セレクターにちょっとした工夫をします。SAMPLE LI:hoverと以下のSAMPPLE MASK:hoverにマウスをのせて、動作を比較しましょう。
/*SAMPLE MASK:hoverの工夫*/ /*セレクターを「liの親のhoverの子のli」にするのがポイント*/ .anime.loop.paused .mask:hover li{ animation-play-state:paused; }
div.progress-barにもanimationを設定する
.progress .progress-bar { background:rgba(0,0,0,1); height:5px; width:100%; position:absolute; z-index:100; bottom:0; left:0; -moz-animation:bar 12s linear infinite; -webkit-animation:bar 12s linear infinite; animation:bar 12s linear infinite; } @keyframes bar { 0%,43.3%,76.6% {width:0;opacity:0;} /*スライドのフレームイン中は表示しない */ 10%,53.3%,86.6% {width:10%;opacity:0.5;} /*フレームイン終了。ここからbarがのびる */ 30%,63.3%,96.6% {opacity:1;} /*barがのびきる前にopacityを1にするとおしゃれ */ 33.3%,66.6%,99.9% {width:100%;opacity:0.1;} /*ここまではbarがのびる */ 34%,67%,100% {width:100%;opacity:0;} /*barを消す */ } .progress .mask:hover .progress-bar{ animation-play-state:paused; bottom:-10px; }
.progress-bar の@keyframesでは、お手本の@keyframesに習って、keyframeの%を、列挙する形でセレクタ指定してみました。スマートなやり方ですね。
また、hover時に、.progress-barもスライドと同様に一時停止しておきます。
表示させるエリアだけを見せて、他を隠す
#complete .mask { margin:0 auto; border:2px solid red; position:relative; cursor:pointer; overflow:hidden; } #complete ul{ list-style:none; height:50px; width:100px; margin: 0; padding: 0; position:relative; } #complete li { margin:0; padding: 0; height:50px; width:100px; top:0; left:100%; position:absolute; overflow:hidden; -moz-animation:slide 12s 0s infinite; -webkit-animation:slide 12s 0s infinite; animation:slide 12s 0s infinite; -moz-animation-play-state:running; -webkit-animation-play-state:running; animation-play-state:running; } #complete li:nth-of-type(1) { -moz-animation-delay:0s; -webkit-animation-delay:0s; animation-delay:0s; } #complete li:nth-of-type(2) { -moz-animation-delay:4s; -webkit-animation-delay:4s; animation-delay:4s; } #complete li:nth-of-type(3) { -moz-animation-delay:8s; -webkit-animation-delay:8s; animation-delay:8s; } #complete a { height:50px; width:100px; display:block; } #complete h2 { position:absolute; padding:0.5em 1em; background:rgba(0,0,0,0.5); color:#fff; top:0; left:-110%; opacity:0; -moz-transition:0.5s; -webkit-transition:0.5s; transition:0.5s; } #complete .mask:hover h2 { left:0; opacity:1; } #complete .mask:hover .progress-bar, #complete .mask:hover li{ -moz-animation-play-state:paused; -webkit-animation-play-state:paused; animation-play-state:paused; } #complete .progress-bar { background:rgba(0,0,0,1); height:5px; width:100%; position:absolute; z-index:100; bottom:0; left:0; -moz-animation:bar 12s linear infinite; -webkit-animation:bar 12s linear infinite; animation:bar 12s linear infinite; } /* keyframes for slide */ @-moz-keyframes slide { 0% {left:100%;opacity:0.5;z-index:10;} /*フレームイン開始*/ 10% {left:0%;opacity:1;} /*(a)全体の1/10秒でフレームイン終了*/ 33.3% {left:0%;opacity:1;z-index:-10;} /*(b)ここまで停止して、フレームアウト開始(b = 100 / スライド数) */ 43.3% {left:-100%;top:0%;opacity:0.5;} /*(c)フレームアウト終了(c = a) */ 50% {left:-100%;top:100%;} /* 分かりやすい様に、見えないエリアで迂回させた */ 70% {left:100%;top:100%;} 80% {left:100%;top:0%;} } @-webkit-keyframes slide { 0% {left:100%;opacity:0.5;z-index:10;} /*フレームイン開始*/ 10% {left:0%;opacity:1;} /*(a)全体の1/10秒でフレームイン終了*/ 33.3% {left:0%;opacity:1;z-index:-10;} /*(b)ここまで停止して、フレームアウト開始(b = 100 / スライド数) */ 43.3% {left:-100%;top:0%;opacity:0.5;} /*(c)フレームアウト終了(c = a) */ 50% {left:-100%;top:100%;} /* 分かりやすい様に、見えないエリアで迂回させた */ 70% {left:100%;top:100%;} 80% {left:100%;top:0%;} } @keyframes slide { 0% {left:100%;opacity:0.5;z-index:10;} /*フレームイン開始*/ 10% {left:0%;opacity:1;} /*(a)全体の1/10秒でフレームイン終了*/ 33.3% {left:0%;opacity:1;z-index:-10;} /*(b)ここまで停止して、フレームアウト開始(b = 100 / スライド数) */ 43.3% {left:-100%;top:0%;opacity:0.5;} /*(c)フレームアウト終了(c = a) */ 50% {left:-100%;top:100%;} /* 分かりやすい様に、見えないエリアで迂回させた */ 70% {left:100%;top:100%;} 80% {left:100%;top:0%;} } /* keyframes for progress-bar */ @-moz-keyframes bar { 0%,43.3%,76.6% {width:0;opacity:0;} 10%,53.3%,86.6% {width:10%;opacity:0.5;} 30%,63.3%,96.6% {opacity:1;} 33.3%,66.6%,99.9% {width:100%;opacity:0.1;} 34%,67%,100% {width:100%;opacity:0;} } @-webkit-keyframes bar { 0%,43.3%,76.6% {width:0;opacity:0;} 10%,53.3%,86.6% {width:10%;opacity:0.5;} 30%,63.3%,96.6% {opacity:1;} 33.3%,66.6%,99.9% {width:100%;opacity:0.1;} 34%,67%,100% {width:100%;opacity:0;} } @keyframes bar { 0%,43.3%,76.6% {width:0;opacity:0;} /*スライドのフレームイン中は表示しない */ 10%,53.3%,86.6% {width:10%;opacity:0.5;} /*フレームイン終了。ここからbarがのびる */ 30%,63.3%,96.6% {opacity:1;} /*barがのびきる前にopacityを1にするとおしゃれ */ 33.3%,66.6%,99.9% {width:100%;opacity:0.1;} /*ここまではbarがのびる */ 34%,67%,100% {width:100%;opacity:0;} /*barを消す */ }
仕上げに、.maskのoverflowをhiddenして完成です。
ここまで説明の為にclassを追加しながらcssを足し込んでいて、ちょっと判りづらい所もあったので、id=complete として整理し直したhtmlとcssにしました。ベンダープレフィックスも書いてあります。
まとめ
ちょっと疲れました
思った以上にボリュームのある内容になりました。しかし、ベンダープレフィックスがある為に記述量が増えてしまいがちな@keyframesについて、スライド個別に作成しないで良い事に気付けたのは収穫でした。
スライドショーの使い道
Web表現としては手垢がついた感もあるスライドショーですが、TOPページでお為ごかしに使っているだけでは勿体ないです。
画面上で動いている物に目がいくのは人間の性なので、注目を引く効果があるのはもちろんです。が、それだけではありません。
スライドショーは、ほんの少しのアイデアと工夫で、様々なバリエーションへ発展できる表現です。例えば...
- 最新情報をNews Ticker風に表示
- Twitterのつぶやきを電光掲示板風に表示
- CSS3のtransformでアニメーションさせてサイバー空間風に表現
- レトロな額縁の中で動かして懐かしの紙芝居を再現
- 高速にスライドを切り替えてパラパラ漫画風に
- ウィンドウ全体の背景画像かと思わせて、実は画面一杯の大きなスライドショー!
- etc...
仕上げの細部にこだわろう
動きの細部(スピード・イージング・フェード)の演出しだいで、がらりと印象が変わるのもスライドショーの面白さです。どんな演出がしたいのか、よく考えましょう。
- ゆっくりと大きな画像を動かしたり、クロスフェードさせれば、優雅な表現に。
- フレームインとフレームアウトをキビキビと動かして、力強いプレゼン的な説得力を持たせた表現に。
- 少しだけ行き過ぎたスライドをバウンドさせて戻したりして、人間臭さを出した表現に。
- 画面を分割して、別々のタイミングでスライドさせることで、海外ドラマ 24風の緊迫感を。
CSSスライドショーはスマートフォンに最適!(かな?)
スマートフォンやタブレット端末のブラウザは、CSS3に対応している前提で作成できるので、こうしたCSSでの演出に向いていると言えます。Flash非対応のデバイスだからjQueryで!と短絡する前に、CSSでも出来るようにしておく事で、選択肢が広がります。
興味とチャレンジ精神のある人は、是非、自分でCSSスライドショーを作ってみて下さい。3パターンくらいを作り終える頃には、css animationを自在に操れるようになるはずです。