

そんな疑問にお答えします。
クロスフェードとはフェードインとフェードアウトを交互に繰り返す状態をいいます。
今回はJavaScript、jQueryを使わずにcssだけでズームしながら表示が切り替わるスライドショーを作ります。
目次
CSSのみで作るスライドショー
以下が完成形です。
See the Pen
CSSのみのクロスフェードスライダー by toshi (@toshi78)
on CodePen.
今回は次の設定でスライドショーを作ります。
- 3枚の画像の再生を繰り返す
- 1秒かけてフェードイン、2秒かけてフェードアウトして画像が切り替わる
- ズームしながら切り替わる
それではコードを書いていきます。
HTML
<div class="slide">
<div class="slide-image"></div>
<div class="slide-image"></div>
<div class="slide-image"></div>
</div>
画像の表示の仕方は
- img タグで表示
- background-imageで表示
の2パターンありますが今回は「background-imageで表示するパターン」で作ります。
よって背景画像を指定するdivタグ(<div class=”slide-image”></div>)を3つ用意しました。
CSS
.slide {
position: relative;
width: 100%;
height: 400px;
overflow: hidden;
}
親要素に対してスライドの幅や高さを設定しています。
ここでのポイントは次の2点です。
- position: relative;の指定
-
overflow: hidden;の指定
「position: relative;」は「position: absolute;」とセットで後で改めて説明します。
「overflow: hidden;」は画像がズームしたときにはみ出た部分を隠すために指定しています。
.slide-image {
background-position: center;
background-repeat: no-repeat;
background-size: cover;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0;
animation: slider-1 24s linear infinite;
}
HTMLには
<div class="slide">
<div class="slide-image"></div>
<div class="slide-image"></div>
<div class="slide-image"></div>
</div>
と記述しました。
ですがこのままだと単に画像が3枚続けて表示されるだけです。
これを1枚1枚順番に表示されるようにしないといけません。
要は紙芝居のようにスライドを切り替えていくイメージです。
そのためには、すべての画像を真ん中に表示しつつ重ね合わせるという作業が必要です。
そしてそれらの画像をアニメーション指定します。
ここでのポイントは3点です。
- background-size: cover;の指定
- 「position: relative;」と「position: absolute;」の指定
-
animationの指定
background-size: cover;の指定
外接リサイズになるように「background-size: cover;」と指定します。
内接リサイズ・外接リサイズとは、画像の縦横比を維持したまま、枠のサイズにフィットするように画像のサイズを変更する描画方法です。
外接リサイズは画像の短辺を枠に合わせてリサイズします。
「position: relative;」と「position: absolute;」の指定
positionプロパティの理解があやふやな方はこちらをご覧ください。
【初心者】position「relative」「absolute」を理解する方法
今回は親要素が「.slide」、子要素が「.slide-image」です。
よって
.slide {
position: relative; /* ⬅指定 */
~以下省略~
}
.slide-image {
background-position: center;
background-repeat: no-repeat;
background-size: cover;
position: absolute; /* ⬅指定 */
~以下省略~
}
とします。
そして「top: 0;」「left: 0;」「width: 100%;」「height: 100%;」と指定することによって親要素に子要素がぴったり重ね合わさることになります。
ここまでの手順で縦横比を維持した画像が紙芝居のように重ねられてセットされることとなります。
さらに初期値を「opacity: 0;」にして表示を隠します。
最後にアニメーションで動きをつけていきます。
animationの指定
animation: slider-1 24s linear infinite;
animationの詳しい解説は以下をご覧ください。
ここでは簡単に説明しておきます。
上記のコードは
- animationにslider-1という名前
- 24秒間かけてアニメーションする
- 一定の速度で始まって終わる
- 無限に再生を繰り返す
という指定です。
スライドショーの設定
animation-delayの指定
.slide-image:nth-child(1) {
background-image: url(画像パス1);
animation-delay: -2s;
}
.slide-image:nth-child(2) {
background-image: url(画像バス2);
animation-delay: 6s;
}
.slide-image:nth-child(3) {
background-image: url(画像パス3);
animation-delay: 14s;
}
「nth-child()」により1番目に出す画像、2番目に出す画像、3番目に出す画像を指定します。
「animation-delay」でアニメーションを開始する時間を指定します。
今回のそれぞれの時間設定は次のとおりです。
- 24秒間かけてアニメーションする
- 1秒かけてフェードイン、2秒かけてフェードアウト
画像は3枚なので8秒ごとに画像が切り替わればいい計算です。
これをそのまま記述するとこうなります。
.slide-image:nth-child(1) {
background-image: url(画像パス);
animation-delay: 0s; /* サイトアクセスと同時に開始 */
}
.slide-image:nth-child(2) {
background-image: url(画像パス);
animation-delay: 8s; /* 8秒後に開始 */
}
.slide-image:nth-child(3) {
background-image: url(画像パス);
animation-delay: 16s; /* 16秒後に開始 */
}
ただこの場合だと最初は非表示から始まります。(初期値「opacity: 0;」のため)
これを避けるために1枚目のスライドのアニメーション開始時間を2秒ほど早めています。
こうすることでサイトアクセス時には2秒後の状態、すなわちフェードインしている状態を表示することができます。
.slide-image:nth-child(1) {
background-image: url(画像パス);
animation-delay: -2s; /* 2秒後から開始 */
}
1枚目のスライドの開始時間を前倒ししたので、それに合わせて2枚目、3枚目のスライド開始時間もそれぞれ2秒早めています。
keyframesの指定
@keyframes slider-1 {
/* 非表示状態からフェードインを開始する */
0% {
opacity: 0;
transform: scale(1); /* ズームのための指定 */
}
/* フェードインを完了し完全表示する */
4.16% {
opacity: 1;
}
/* ここまで完全表示を維持したらフェードアウトを開始する */
33.33% {
opacity: 1;
}
/* フェードアウトを完了し非表示にする */
41.66% {
opacity: 0;
transform: scale(1.2); /* ズームのための指定 */
}
100% {
opacity: 0;
}
}
スライダーのキーフレームは以下がポイントです。
- 最初(0%)は非表示からフェードイン
- 1秒経過するまでにフェードインを完了
- 8秒目に達するまでは表示状態を維持
- 2秒かけてフェードアウトし、10秒時点(8+2秒)で非表示
- その後はアニメーションの最後(100%)まで非表示を維持
キーフレームの時間はアニメーション周期に対する割合(%)で表されるため、該当する秒数をアニメーション周期の秒数で割って計算します。
- 1秒後 = 1秒 ÷ 24秒 = 4.16%
- 8秒後 = 7秒 ÷ 24秒 = 33.33%
- 10秒後 = 7秒 ÷ 24秒 = 41.66%
最後にズームの指定をします。
ズームさせるには「transform: scale();」を使います。
これを
- 最初(0%)にtransform: scale(1);
- 消え終わりの箇所(41.66%)にtransform: scale(1.2);
と指定します。
これで完成です。
最後に全コードを載せておきます。
あと今回は画像の高さを固定で指定していますが、レスポンシブ対応についてはメディアクエリで高さやポジション等を調整してください。
以上です。
<div class="slide">
<div class="slide-image"></div>
<div class="slide-image"></div>
<div class="slide-image"></div>
</div>
.slide {
position: relative;
width: 100%;
height: 400px;
overflow: hidden;
}
.slide-image {
background-position: center;
background-repeat: no-repeat;
background-size: cover;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0;
animation: slider-1 24s linear infinite;
}
.slide-image:nth-child(1) {
background-image: url(../img/husky01.jpg);
animation-delay: -2s;
}
.slide-image:nth-child(2) {
background-image: url(../img/husky05.jpg);
animation-delay: 6s;
}
.slide-image:nth-child(3) {
background-image: url(../img/husky06.jpg);
animation-delay: 14s;
}
@keyframes slider-1 {
0% {
opacity: 0;
transform: scale(1);
}
4.16% {
opacity: 1;
}
33.33% {
opacity: 1;
}
41.66% {
opacity: 0;
transform: scale(1.2);
}
100% {
opacity: 0;
}
}
投稿者 トシ
コメントを残す