News

Home News スライドショー

スライドショー

画像数枚がフェードで切り替わるだけの、操作とかできない、超シンプルな観賞用スライドショー。

基本構造

クラスc-slideshowを付与した要素の中に、クラスitem要素で括ったimg要素を並べる。

<div class="c-slideshow"> <figure class="item"><img src="../../assets/img/visual_1.webp" alt="" width="2400" height="1200"></figure> <figure class="item"><img src="../../assets/img/visual_2.webp" alt="" width="2400" height="1200" loading="lazy"></figure> </div>

基本CSSは以下の通り。スライドショーする画像はすべて同じサイズ推奨。サイズが違う場合は一枚めの画像サイズ・アスペクト比でトリミングされる。

.c-slideshow { --interval: 8s; position: relative; overflow: hidden; } .c-slideshow .item:not(:first-child) { position: absolute; inset: 0; } .c-slideshow .item img { width: 100%; height: 100%; object-fit: cover; }

画像切り替えは@keyframes規則で定義したキーフレームアニメーション。同じアニメーションを、画像ごとに開始位置(animation-delay)をズラして適用している。

.c-slideshow .item { animation: slideshow_fade linear infinite, slideshow_zoom linear infinite; animation-duration: calc(var(--interval) * 2); } @keyframes slideshow_fade { from, 22.5%, 77.5%, to { opacity: 0; } 27.5%, 72.5% { opacity: 1; } } @keyframes slideshow_zoom { from, 22.5%, to { transform: scale(1.1); } 77.5% { transform: none; } } .c-slideshow .item:nth-child(1) { animation-delay: calc(var(--interval) * -.5); } .c-slideshow .item:nth-child(2) { animation-delay: calc(var(--interval) * .5); } /* 3枚め以降 */ .c-slideshow .item:nth-child(3) { animation-delay: calc(var(--interval) * 1.5); } .c-slideshow .item:nth-child(4) { animation-delay: calc(var(--interval) * 2.5); } .c-slideshow .item:nth-child(5) { animation-delay: calc(var(--interval) * 3.5); } .c-slideshow .item:nth-child(6) { animation-delay: calc(var(--interval) * 4.5); }

仕組み

キーフレームは、フェード用ズーム用の2種類。下図は画像が2枚の時用のキーフレーム。
なので、1枚あたりの表示時間(※以下、インターバルという)はキーフレーム全体の二分の一(50%)

最初にフェードインする猶予を設けるため、インターバルの半分(25%)、透明の期間を空けておく。
フェードにかける時間は、インターバルの十分の一(5%)で、フェードの中間が切り替わり地点を跨ぐようにフェードする。(※フェードインの時でいうと、25%の2.5%手前(22.5%)からフェードインし出して、2.5%先(77.5%)でフェードインし切る、という具合。)

ズームは、フェードインし出す地点(22.5%)から、フェードアウトし終える地点(77.5%)にかけてズームアウトしていく。

animationプロパティに、上で用意したキーフレームを、画像ごとにインターバル分ずつズラして適用している。
1枚めは25%進んだところから開始スタートし、2枚めはそこから50%待ってから開始する。ここではインターバルを8秒に設定しているので、1枚めはキーフレームの4秒先から開始し、2枚めはそこ(-4秒)から8秒後に開始される。
※インターバルは、CSS変数「--interval」で設定している。

画像の枚数によってキーフレームを変える

デフォルトは画像2枚用。画像の枚数ごとに、バリエーションクラス-item3-item4…)を付与する(6枚まで用意してある)

<div class="c-slideshow -item3"> <figure class="item"><img src="../../assets/img/visual_1.webp" alt="" width="2400" height="1200"></figure> <figure class="item"><img src="../../assets/img/visual_2.webp" alt="" width="2400" height="1200" loading="lazy"></figure> <figure class="item"><img src="../../assets/img/visual_3.webp" alt="" width="2400" height="1200" loading="lazy"></figure> </div>

バリエーションクラスにより、animation-nameプロパティ(アニメーション名)と、animation-durationプロパティ(アニメーションする長さ)が変わる。

.c-slideshow.-item3 .item { animation-name: slideshow_fade3, slideshow_zoom3; animation-duration: calc(var(--interval) * 3); } @keyframes slideshow_fade3 { from, 15%, 51.67%, to { opacity: 0; } 18.33%, 48.33% { opacity: 1; } } @keyframes slideshow_zoom3 { from, 15%, to { transform: scale(1.1); } 51.67% { transform: none; } }

画像が3枚の時も、キーフレームの仕組みは2枚の時と同じ。
インターバルはキーフレーム全体の三分の一(33.33%)になり、フェードにかける時間はインターバルの十分の一(3.33%)と、どちらも半端な数値なので計算がちょっとややこやしいけど、仕組みは同じ。

上のキーフレームを、インターバル分ズラして適用する。アニメーション全体の長さも、画像3枚分にする(インターバル8秒なら24秒)
1枚めは0.5インターバル分進んだところから開始し、2枚め以降は、そこから1インターバル分ずつ遅れて開始される。

キーフレーム例

画像が4枚(1インターバル25%

.c-slideshow.-item4 .item { animation-name: slideshow_fade4, slideshow_zoom4; animation-duration: calc(var(--interval) * 4); } @keyframes slideshow_fade4 { from, 11.25%, 38.75%, to { opacity: 0; } 13.75%, 36.25% { opacity: 1; } } @keyframes slideshow_zoom4 { from, 11.25%, to { transform: scale(1.1); } 38.75% { transform: none; } }

画像が5枚(1インターバル20%

.c-slideshow.-item5 .item { animation-name: slideshow_fade5, slideshow_zoom5; animation-duration: calc(var(--interval) * 5); } @keyframes slideshow_fade5 { from, 9%, 31%, to { opacity: 0; } 11%, 29% { opacity: 1; } } @keyframes slideshow_zoom5 { from, 9%, to { transform: scale(1.1); } 31% { transform: none; } }

画像が6枚(1インターバル16.66%

.c-slideshow.-item6 .item { animation-name: slideshow_fade6, slideshow_zoom6; animation-duration: calc(var(--interval) * 6); } @keyframes slideshow_fade6 { from, 7.5%, 25.82%, to { opacity: 0; } 9.16%, 24.16% { opacity: 1; } } @keyframes slideshow_zoom6 { from, 7.5%, to { transform: scale(1.1); } 25.82% { transform: none; } }

レスポンシブ

picture要素を使って、ビューポート幅をブレークポイントに画像を出し分ける。

<div class="c-slideshow -item4"> <figure class="item"><picture> <source srcset="../../assets/img/visual_1.webp" width="2400" height="1200" media="(min-width:768px)"> <source srcset="../../assets/img/visual_1_mb.webp" width="1200" height="800" media="(max-width:767px)"> <img src="../../assets/img/visual_1.webp" alt="" width="2400" height="1200"> </picture></figure> ︙ <figure class="item"><picture> <source srcset="../../assets/img/visual_4.webp" width="2400" height="1200" media="(min-width:768px)"> <source srcset="../../assets/img/visual_4_mb.webp" width="1200" height="800" media="(max-width:767px)"> <img src="../../assets/img/visual_4.webp" alt="" width="2400" height="1200" loading="lazy"> </picture></figure> </div>