CSSだけで作るクロスフェードスライダー
先日JQueryを3.5.1にアップデートしたら、愛用していたスライダーのプラグインResponsiveSlidesが動かなくなってしまった。別のプラグインで差し替えても今後また同じようなことになるかなと思ったので、この機会に思い切ってスタイルシートだけで動くスライダーに差し替えた。パターンの違うクロスフェードスライダーを3つほど作ってみたので備忘録を兼ねつつ、作り方をご紹介。
一つ目のスライダーが基本のタイプで、それを少し応用したのが二つ目、それをさらに応用したのが三つ目となっています。そのため1のスライダーを使って基本構造を解説し、2と3については応用箇所だけポイントで解説しています。
実際のソースはこちらからダウンロード(HTML/CSS/画像)することができます。
1.二枚の写真が交互にフェードイン・フェードアウト
二枚の写真が7秒ずつ交互にフェードアウト・フェードインするシンプルなスライダー。リストタグの中に画像を配置し、画像の透明度を互い違いに切り替えることにより、フェードイン・フェードアウトを表現している。ソースは以下の通り。
HTMLコード
HTMLコードはとてもシンプル。<div>タグ内にリストタグ<ul>を配置し、そのli要素の中にスライドさせたい画像を配置する。
<div class="slider_1">
<ul>
<li><img src="img/01.jpg"></li>
<li><img src="img/02.jpg"></li>
</ul>
</div>
CSS
スタイルシートでは1.スライダーのスタイル設定、2.アニメーションの開始時間の設定、3.フェードイン・フェードアウトの設定を行っている。設定内容の詳細については以下に続くポイント解説に記載。
/* スライダーのスタイル設定 */
.slider_1{ position:relative;
height:500px;
margin:0 auto;
padding:0 auto;
text-align: center;
}
.slider_1 ul{
margin:0; padding:0; list-style:none;
}
.slider_1 ul img{
width:80%;
margin:0 auto 0;
padding:0 auto;
}
.slider_1 ul li{
width:100%;
height:100%;
position:absolute;
top:0;
left:0;
animation-iteration-count:infinite;
animation-duration:14s;
}
/* アニメーション開始時間の設定 */
.slider_1 ul li:nth-child(1){
animation-name:slider_1;
animation-delay:-2s;
}
.slider_1 ul li:nth-child(2){
animation-name:slider_1;
animation-delay:5s; opacity:0;
}
/* フェードイン・フェードアウトの設定 */
@keyframes slider_1{
0%{ opacity:0; }
50%{ opacity:1; }
100%{ opacity:0;}
}
/* MEDIA QUERIES */
@media screen and (max-width: 640px) {
.slider_1{ height:330px;}
}
@media screen and (max-width: 414px) {
.slider_1{ height:260px;}
}
@media screen and (max-width: 360px) {
.slider_1{ height:230px;}
}
@media screen and (max-width: 320px) {
.slider_1{ height:200px;
}
}
ポイント解説:スライダーのスタイル設定
まずリストを格納する<div>タグのスタイル設定を行う。ここでの一番重要なポイントは高さ(height)の設定だ。
このスライダーでは、画像を配置するli要素を絶対位置(absolute)で配置する。絶対位置で配置された要素は、その要素のためのスペースが確保されない。つまりli要素が存在しない=<div>タグ内は空っぽであるとしてレイアウトが行われてしまうため、続けて配置した他のコンテンツが、スライダーの下に隠れてしまう。そのため、親要素になるこの<div>タグに高さを設定し、スライダーのためのスペースを確保する必要がある。
.slider_1{
position:relative;
height:500px;/* 表示するスライダーの高さを設定 */
margin:0 auto;
padding:0 auto;
text-align: center;
}
続いて<ul>タグのスタイル設定を行う。list-styleはnoneに設定。中に配置する画像の横幅(width)は80%と、相対的な値で設定する。こうすることで、親要素のdivの幅に連動してスライダーの画像の幅がレスポンシブに変動するようになる。
.slider_1 ul{
margin:0;
padding:0;
list-style:none;
}
.slider_1 ul img{
width:80%;/* スライドさせる画像の幅を相対値で設定 */
margin:0 auto 0;
padding:0 auto;
}
次に<li>タグのスタイル設定を行う。二つのリスト項目を同じ位置に重ねて表示させるため、リストの項目要素は絶対位置(absolute)に指定する。そしてそれぞれのリスト項目に「アニメーションの繰り返し」設定と「アニメーションの周期」を設定する。ここでは繰り返しは無限(infinite)、アニメーションの周期は14秒(7秒×2枚)に設定している。これでスタイルの設定は完了。
.slider_1 ul li{
width:100%;
height:100%;
position:absolute;/* リスト項目を絶対位置に配置 */
top:0;
left:0;
animation-iteration-count:infinite;/* アニメーションを無限に繰り返す */
animation-duration:14s; /* アニメーションの周期は14秒 */
}
ポイント解説:アニメーション開始時間の設定
スタイルの設定ができたら、それぞれのリスト項目にアニメーションの設定をしていく。
7秒ずつ二枚の画像を違い違いにフェードイン・フェードアウトさせるためには、アニメーションが始まるタイミングを7秒ずらしてやればよい。
一枚目:最初の7秒間でフェードイン、残りの7秒間でフェードアウト
二枚目:一枚目がフェードアウトし始めるタイミング(=7秒後)からフェードインを始める
これをCCSで表すと以下のような記述になる。
.slider_1 ul li:nth-child(1){
animation-name:slider_1;
animation-delay:0s;/* サイトアクセスと同時にスタート */
}
.slider_1 ul li:nth-child(2){
animation-name:slider_1;
animation-delay:7s;/* 7秒後からスタート */ opacity:0;
}
ただ、これでは画像が何も表示されていない状態からフェードインを始めるので画像が非表示になる瞬間が生じる。これを避けるために、一枚目のスライドのアニメーション開始時間を2秒前ほど前倒しに設定しておく。こうすることでサイトアクセス時に2秒後の状態=(一枚目の画像がフェードインし始めている状態)を表示することができる。
.slider_1 ul li:nth-child(1){
animation-name:slider_1;
animation-delay:-2s;/* 2秒前からスタート */
}
1枚目のスタート時間を前倒しした分、2枚目も2秒前倒しして5秒後(7秒-2秒)からのスタートに設定する。
.slider_1 ul li:nth-child(2){
animation-name:slider_1;
animation-delay:5s; /* 5秒後(7秒-2秒)からスタート */
opacity:0;
}
これで各スライダーに対するアニメーション開始時間の設定は完了。
ポイント解説:フェードイン・フェードアウトの設定
最後に実行するアニメーションの内容をキーフレーム(@keyframes)に記述していく。このスライダーではコンテンツの不透明度(opacity)を時間で変化させることにより、フェードイン・フェードアウトを表現している。
キーフレーム内の時間はアニメーション開始時が「0%」、アニメーション終了時が「100%」という風に、周期に対する割合割合(%)で示す。アニメーションの開始時に写真を非表示(不透明度0%)にするためには以下のように記述する。
0%{ opacity:0;}
続いてアニメーションの半分(7秒)までにフェードインを完了し、完全表示(不透明度100%)するので以下のように記述。
50%{ opacity:1;}
最後にアニメーションの最後(100%)までにフェードアウトを完了し、非表示(不透明度0%)に戻したいので以下のように記述。
100%{ opacity:0;}
これで7秒間かけてフェードイン、7秒間かけてフェードアウトするアニメーションが完成。
ポイント解説:レスポンシブのための設定
必要があれば最後にレスポンシブのための設定を行う。スライダーの幅は常に画面の80%になるよう設定しているのでフレキシブルに変化するが、スライダーの高さはheight:500pxと設定しているため、変化しない。このままでは小さな端末で表示した時に下のスペースがやたら広いスライダーになってしまうので、端末サイズに合わせて好みの高さを指定する。どこまで細かく端末に合わせて設定するかはお好みで。
/*===============================================
画面の横幅が640pxまで
===============================================*/
@media screen and (max-width: 640px) {
.slider_1{
height:330px;
}
}
/*===============================================
画面の横幅が414pxまで(iPhone/Pixel)
===============================================*/
@media screen and (max-width: 414px) {
.slider_1{
height:260px;
}
}
/*===============================================
画面の横幅が360pxまで(Galaxy)
===============================================*/
@media screen and (max-width: 360px) {
.slider_1{
height:230px;
}
}
/*===============================================
画面の横幅が320pxまで(iPhone5/SE)
===============================================*/
@media screen and (max-width: 320px) {
.slider_1{
height:200px;
}
}
2.切り替えの時だけフェードイン・フェードアウト
写真の切り替えのタイミングのみ、ふわっとフェードイン・フェードアウトをするスライダー。最初のスライダーは二枚の写真がゆっくり交互に変化していくが、こちらは写真が切り替わる前後2秒間だけフェードイン・フェードアウトする。
HTMLコード
最初のスライダーと区別するために名前はslider_2としているが、HTMLコードの内容は同じ。
<div class="slider_2">
<ul>
<li><img src="img/01.jpg"></li>
<li><img src="img/02.jpg"></li>
</ul>
</div>
CSS
基本的なスタイル設定は最初のスライダーと同じだが、キーフレームの設定が少し異なる。詳細についてはポイント解説:キーフレームの区分にて後述。尚、メディアクエリの記述は長くなるためここでは割愛している。(必要な方は1のスライダーを参考にclass名をslider_2にして追記してください。)
/* スライダーのスタイル設定 */
.slider_2{
position:relative;
height: 500px;
margin:0 auto;
padding:0 auto;
text-align: center;
}
.slider_2 ul{
margin:0;
padding:0;
list-style:none;
}
.slider_2 ul img{
width:80%;
margin:0 auto 0;
padding:0 auto;
}
.slider_2 ul li{
width:100%;
height:100%;
position:absolute;
top:0;
left:0;
animation-iteration-count:infinite;
animation-duration:14s;
}
/* アニメーション開始時間の設定 */
.slider_2 ul li:nth-child(1){
animation-name:slider_2;
animation-delay:-2s;
}
.slider_2 ul li:nth-child(2){
animation-name:slider_2;
animation-delay:5s; opacity:0;
}
/* フェードイン・フェードアウトの設定 */
@keyframes slider_2{
0%{ opacity:0; }
14.28%{ opacity:1; }
50%{ opacity:1; }
64.28%{ opacity:0; }
100%{ opacity:0; }
}
ポイント解説:キーフレームの区分
最初のスライダーのキーフレームは
- 最初(0%)は非表示からフェードイン
- アニメーションの半分(50%)まできたら完全表示
- 最後(100%)までにフェードアウトして非表示にする
という3つの区分になっていたが、ここに「完全表示を状態で維持する」、「完全非表示の状態を維持する」という2つの区分を追加し、以下のような5つの区分にする。
- 最初(0%)は非表示からフェードイン
- 2秒経過するまでにフェードインを完了する
- 7秒目(50%)に達するまでは表示状態を維持
- 2秒かけてフェードアウトし、9秒時点(7+2秒)で非表示にする
- その後は最後(100%)まで非表示状態を維持する
アニメーションのフレームはアニメーション周期に対する割合(%)で表記するため、該当する秒数をアニメーションの周期の秒数(ここでは14秒)で割って計算する。
- 2秒後=2秒÷14秒=14.28%
- 9秒後=9秒÷14秒=64.28%
計算した割合をキーフレームのプロパティと共にスタイルシートに記述していく。
@keyframes slider_2{
/* 非表示(不透明度0%)状態からフェードインを始める */
0%{ opacity:0; }
/* 2秒目までにフェードインを完了し、完全表示(不透明度100%)にする */ 1
4.28%{ opacity:1; }
/* 7秒目まで完全表示(不透明度100%)の状態を維持したらフェードアウトを始める */
50%{ opacity:1; }
/* 9秒目までにフェードアウトを完了し、非表示(不透明度0%)にする */
64.28%{ opacity:0; }
/* 非表示(不透明度0%)状態を維持したまま終わる */
100%{ opacity:0; }
}
3.三枚の写真をフェードイン・フェードアウト
2のスライダーの応用篇。1秒かけてでフェードイン、2秒掛けてフェードアウトしながら3枚の写真が切り替わる。
HTMLコード
写真を三枚使うのでli要素も3つにし、それぞれの中に画像を配置する。
<div class="slider_3">
<ul>
<li><img src="img/03.jpg"></li>
<li><img src="img/04.jpg"></li>
<li><img src="img/05.jpg"></li>
</ul>
</div>
CSS
基本的な設定は2と同じだが、アニメーション開始時間の設定を3枚分行う点う必要がある。また、3枚の写真を7秒ごとに切り替えるのでアニメーションの周期は7秒×3枚=21秒となる。キーフレームの区分の仕方が少し複雑になるので、詳細はポイント解説にて後述する。尚、メディアクエリの記述は長くなるためここでは割愛している。(必要な方は1のスライダーを参考にclass名をslider_3にして追記してください。)
/* スライダーのスタイル設定 */
.slider_3{
position:relative;
height: 500px;
margin:0 auto;
padding:0 auto;
text-align: center;
}
.slider_3 ul{
margin:0;
padding:0;
list-style:none;
}
.slider_3 ul img{
width:80%;
margin:0 auto;
padding:0 auto;
}
.slider_3 ul li{
width:100%;
height:100%;
position:absolute;
top:0;
left:0;
animation-iteration-count:infinite;
animation-duration:21s; }
/* アニメーション開始時間の設定 */
.slider_3 ul li:nth-child(1){
animation-name:slider_3;
animation-delay:-1s;
}
.slider_3 ul li:nth-child(2){
animation-name:slider_3;
animation-delay:6s; opacity:0;
}
.slider_3 ul li:nth-child(3){
animation-name:slider_3;
animation-delay:13s; opacity:0;
}
/* フェードイン・フェードアウトの設定 */
@keyframes slider_3{ 0%{ opacity:0; }
4.76%{ opacity:1; }
33.33%{ opacity:1; }
42.85%{ opacity:0; }
100%{ opacity:0; }
}
ポイント解説:アニメーション開始時間の設定(3枚用)
スライダーが3つになるので、スライダーのスタイル設定も3つ分行う。それぞれ前のスライダーから7秒ずつ遅れて開始するように設定する。今回最初のスライダーを1秒前倒しにするので、二枚目は6秒(7秒-1秒)後から、三枚目は13秒(14秒-1秒)後からスタートするよう設定。
/* アニメーション開始時間の設定 */
.slider_3 ul li:nth-child(1){
animation-name:slider_3;
animation-delay:-1s;/* 1秒前からスタート */
}
.slider_3 ul li:nth-child(2){
animation-name:slider_3;
animation-delay:6s;/* 6秒後(7秒-1秒)からスタート */
opacity:0;
}
.slider_3 ul li:nth-child(3){
animation-name:slider_3;
animation-delay:13s;/* 13秒後(14秒-1秒)からスタート */
opacity:0;
}
ポイント解説:キーフレームの区分
スライダーのキーフレームはスライダー2と同じく以下の5つに区分される。
- 最初(0%)は非表示からフェードイン
- 1秒経過するまでにフェードインを完了する
- 7秒目に達するまでは表示状態を維持
- 2秒かけてフェードアウトし、9秒時点(7+2秒)で非表示にする
- その後はアニメーションの最後(100%)まで非表示状態を維持する
キーフレームの時間はアニメーション周期に対する割合(%)で表記するため、該当する秒数をアニメーションの周期の秒数(ここでは21秒)で割って計算する。
- 1秒後=1秒÷21秒=4.76%
- 7秒後=7秒÷21秒=33.33%
- 9秒後=7秒÷21秒=42.85%
計算した割合をキーフレームのプロパティと共にスタイルシートに記述していく。
@keyframes slider_3{
/* 非表示(不透明度0%)状態からフェードインを始める */
0%{ opacity:0; }
/* ここまでにフェードインを完了し、完全表示(不透明度100%)にする */
4.76%{ opacity:1; }
/* ここまで完全表示(不透明度100%)の状態を維持したらフェードアウトを始める */
33.33%{ opacity:1; }
/* ここまでにフェードアウトを完了し、非表示(不透明度0%)にする */
42.85%{ opacity:0; }
/* 非表示(不透明度0%)状態を維持したまま終わる
*/ 100%{ opacity:0; }
}
キーフレーム部分の設定のコツさえつかんでしまえば、簡単&汎用性高く使えるスライダーだと思うので、ぜひ色々カスタマイズしてみてください。
Web制作関連
2021.2.4投稿