Webサイトのトップページなどでよく見かける「スライドショー」。
動きがあるだけで、サイトがぐっと魅力的になるものです。
「実装が難しそう・・・」と感じるかもしれませんが、実はHTMLとCSSだけで、コピペで使えるほど簡単に作成できるのです。
この記事では、JavaScriptを使わずにHTMLとCSSだけで実装できる、軽量でシンプルなスライドショーの作り方を解説していきます。
横に無限スクロールするものから、ふわりと画像が切り替わるフェード式のものまで、具体的なソースコードとともに紹介します。
【本記事の信頼性】
- 執筆者は元エンジニア
- 大手プログラミングスクールのWebディレクター兼ライターを経験
- 自らも地元密着型のプログラミングスクールを運営
受講生から評判の良いプログラミングスクール
スクール |
特徴 |
受講料金 |
大手比較サイトで4年連続人気NO.1!受講生からの評判も非常に高く、Web系のエンジニアを目指すならRUNTEQ一択。 | 657,000円 (最大約53万円の給付金が適用される) |
|
月単価80万円以上の現役エンジニア講師による指導!一度入会すればサポートは半永久的。 | 498,000円 |
|
格安で質の高いWeb制作スキルを習得したい人におすすめ!業界最安級の料金でありながら、コミュニティやサポートが充実。 | 129,800円~ |
|
完全無料でプログラミングが学べる貴重なスクール!最短1ヶ月で卒業可能。ゼロスク運営会社への就職もできる。 | 完全無料 |
|
長期間に渡って学習し、希少人材を目指す人に最適なスクール!受講料は高いものの、高収入を得られる人材を目指せる。 | 96~132万円 |
HTMLとCSSでスライドショーが動く基本の仕組み
コードを見る前に、まずは「なぜCSSだけでスライドショーが動くのか」という基本的な仕組みを理解しておきましょう。
ポイントとなるのは、CSSのanimation
プロパティと@keyframes
というルールです。
animation
:要素にアニメーションを適用するためのプロパティです。アニメーションの名前、時間、速度、繰り返し回数などを一括で指定できます。@keyframes
:アニメーションの具体的な動きを定義します。例えば「0%(開始時)はこの位置」で「100%(終了時)はこの位置」というように、時間の経過とともにスタイルをどう変化させるかを指定します。
この2つを組み合わせることで、画像をパラパラ漫画のように動かし、スライドショーとして見せることができるのです。
JavaScriptを使わないため、ページの読み込み速度への影響が少なく、軽量なのが大きなメリットとなります。
【コピペOK】横スクロールするスライドショーの作り方
最も一般的でよく使われる、画像が左から右へ無限に流れ続ける横スクロールのスライドショーを作成してみましょう。
ここでは、5枚の画像がループし続けるサンプルを紹介します。
HTMLのコード
HTMLは、スライドショー全体を囲むコンテナと、その中に画像のリストを配置するシンプルな構造です。
今回はアクセシビリティを考慮し、装飾的な画像であることをスクリーンリーダーに伝えるため、li
要素にaria-hidden="true"
を追加しています。
<div class="slideshow-wrapper">
<ul class="slideshow-container">
<li class="slide" aria-hidden="true"><img src="
https://placehold.co/600x400/E57373/ffffff?text=Image1(https://placehold.co/600x400/E57373/ffffff?text=Image1)" alt=""></li>
<li class="slide" aria-hidden="true"><img src="
https://placehold.co/600x400/81C784/ffffff?text=Image2(https://placehold.co/600x400/81C784/ffffff?text=Image2)" alt=""></li>
<li class="slide" aria-hidden="true"><img src="
https://placehold.co/600x400/64B5F6/ffffff?text=Image3(https://placehold.co/600x400/64B5F6/ffffff?text=Image3)" alt=""></li>
<li class="slide" aria-hidden="true"><img src="
https://placehold.co/600x400/FFD54F/ffffff?text=Image4(https://placehold.co/600x400/FFD54F/ffffff?text=Image4)" alt=""></li>
<li class="slide" aria-hidden="true"><img src="
https://placehold.co/600x400/9575CD/ffffff?text=Image5(https://placehold.co/600x400/9575CD/ffffff?text=Image5)" alt=""></li>
<!-- 無限ループのために画像を複製 -->
<li class="slide" aria-hidden="true"><img src="
https://placehold.co/600x400/E57373/ffffff?text=Image1(https://placehold.co/600x400/E57373/ffffff?text=Image1)" alt=""></li>
<li class="slide" aria-hidden="true"><img src="
https://placehold.co/600x400/81C784/ffffff?text=Image2(https://placehold.co/600x400/81C784/ffffff?text=Image2)" alt=""></li>
<li class="slide" aria-hidden="true"><img src="
https://placehold.co/600x400/64B5F6/ffffff?text=Image3(https://placehold.co/600x400/64B5F6/ffffff?text=Image3)" alt=""></li>
<li class="slide" aria-hidden="true"><img src="
https://placehold.co/600x400/FFD54F/ffffff?text=Image4(https://placehold.co/600x400/FFD54F/ffffff?text=Image4)" alt=""></li>
<li class="slide" aria-hidden="true"><img src="
https://placehold.co/600x400/9575CD/ffffff?text=Image5(https://placehold.co/600x400/9575CD/ffffff?text=Image5)" alt=""></li>
</ul>
</div>
CSSのコード
CSSでは、Flexboxのgap
プロパティを使って画像間の余白を制御し、calc()
でアニメーションの移動距離を正確に計算するのがポイントです。
/* スライドショー全体のコンテナ */
.slideshow-wrapper {
width: 100%;
overflow: hidden; /* はみ出した部分を非表示にする */
}
/* 画像リストのコンテナ */
.slideshow-container {
display: flex; /* 画像を横並びにする */
gap: 20px; /* 画像間の余白を設定 */
list-style: none;
padding: 0;
margin: 0;
/* アニメーションの設定 */
animation: slideshow 20s linear infinite;
}
/* 各画像 */
.slide img {
width: 300px; /* 画像の幅を固定 */
height: auto;
}
/* アニメーションの定義 */
@keyframes slideshow {
0% {
transform: translateX(0);
}
100% {
/* (画像1枚の幅 + gap) × 5枚分 を左に移動させる */
transform: translateX(calc(-(300px + 20px) * 5));
}
}
/* マウスホバーで一時停止 */
.slideshow-wrapper:hover .slideshow-container {
animation-play-state: paused;
}
コードの詳しい解説
それでは、CSSコードが何をしているのか、詳しく見ていきましょう。
.slideshow-container
ul
タグにあたるこの要素では、display: flex;
で画像を横並びにしています。
ここでのポイントはgap: 20px;
です。
margin-right
などのプロパティと違い、gap
はflexアイテム(今回はli
要素)の「間」にだけ均等な余白を生成します。
これにより、最後の要素に不要な余白がつく問題をスマートに解決できます。
@keyframes slideshow
アニメーションの終点(100%
)で、画像をどれだけ左に移動させるかをtransform: translateX()
で指定しています。
ここが最も重要なポイントです。
transform: translateX(calc(-(300px + 20px) * 5));
この計算式は、以下のロジックで成り立っています。
(300px + 20px)
: まず、画像1枚あたりの実質的な幅(画像の幅300px
+ 画像間の余白20px
)を計算します。これで320px
となります。* 5
: 次に、その幅をスライドさせる画像の枚数(今回は5枚)で掛け合わせます。320px * 5
で、合計の移動距離1600px
が算出されます。-()
: 最後に、translateX
は正の値だと右、負の値だと左に移動するため、全体をマイナスにすることで左方向への移動を指定しています。
この書き方により、「画像1枚あたりの占有幅 × 枚数」というロジックがコード上で明確になり、非常にわかりやすくなりました。
HTMLのアクセシビリティについて
li
要素にaria-hidden="true"
を追加しました。
これは、スライドショーの画像が純粋な装飾であり、コンテンツを理解する上で必須の情報を含んでいないことを示します。
スクリーンリーダーなどの支援技術はこの属性を持つ要素を無視するため、視覚障害を持つユーザーが同じ画像の情報を何度も読み上げられるのを防ぎ、より快適なブラウジング体験を提供することに繋がります。
もし画像が重要な情報を持つ場合は、この属性を付けず、alt
属性に適切な説明を記述する必要があります。
【応用編】スライドショーをカスタマイズする方法
基本のスライドショーが作れたら、次は自分好みにカスタマイズしてみましょう。
CSSの値を少し変更するだけで、様々な調整が可能です。
スピードを調整する
スライドショーの速さは、.slideshow-container
のanimation
プロパティで変更できます。
.slideshow-container {
/* この「20s」の部分を変更する */
animation: slideshow 20s linear infinite;
}
20s
(20秒)の数値を大きくすればアニメーションはゆっくりに、小さくすれば速くなります。
例えば40s
にすると、ループにかかる時間が倍になります。
画像の枚数を変更する
画像の枚数を変更する場合は、HTMLのli
要素を増減させるのに加えて、CSSの@keyframes
内のcalc()
も修正する必要があります。
例えば、画像を7枚に増やした場合、以下のように変更します。
@keyframes slideshow {
0% {
transform: translateX(0);
}
100% {
/* (画像1枚の幅 + gap) × 7枚分を左に移動させる */
transform: translateX(calc(-(300px + 20px) * 7));
}
}
ポイントは、calc()
の最後にある掛け算の数値を、ループさせたい画像の枚数(この場合は7
)に合わせることです。
同様に、画像の幅(300px
)やgap
(20px
)を変更した場合も、この計算式を忘れずに調整してください。
マウスホバーで一時停止させる
ユーザーが画像にマウスカーソルを合わせたときに、スライドショーの動きを一時的に止めることができます。
これは、以下のCSSを追加するだけで実装できます。
.slideshow-wrapper:hover .slideshow-container {
animation-play-state: paused;
}
上記は、「.slideshow-wrapper
にマウスが乗ったら、その中の.slideshow-container
のアニメーションを一時停止(paused
)する」という指定です。
ユーザーがじっくり画像を見たい場合に便利な機能となります。
【コピペOK】フェードで切り替わるスライドショーの作り方
次に、横スクロールとは違った印象を与える、画像が「ふわっ」と切り替わるフェードイン・フェードアウトのスライドショーを作成してみましょう。
この方法では、複数の画像を同じ位置に重ねておき、順番に表示・非表示を繰り返すことで実現します。
HTMLのコード
HTMLの構造は横スクロールの時よりもさらにシンプルです。
画像をリストにするだけで構いません。
<div class="fade-slideshow-wrapper">
<ul class="fade-slideshow-container">
<li class="slide"><img src="
https://placehold.co/800x450/E57373/ffffff?text=Scene1(https://placehold.co/800x450/E57373/ffffff?text=Scene1)" alt="シーン1"></li>
<li class="slide"><img src="
https://placehold.co/800x450/81C784/ffffff?text=Scene2(https://placehold.co/800x450/81C784/ffffff?text=Scene2)" alt="シーン2"></li>
<li class="slide"><img src="
https://placehold.co/800x450/64B5F6/ffffff?text=Scene3(https://placehold.co/800x450/64B5F6/ffffff?text=Scene3)" alt="シーン3"></li>
<li class="slide"><img src="
https://placehold.co/800x450/FFD54F/ffffff?text=Scene4(https://placehold.co/800x450/FFD54F/ffffff?text=Scene4)" alt="シーン4"></li>
</ul>
</div>
CSSのコード
CSSではposition
プロパティを使って画像を重ね、opacity
(不透明度)をアニメーションで変化させるのがポイントです。
.fade-slideshow-wrapper {
width: 100%;
max-width: 800px; /* 最大幅を指定 */
height: 450px; /* 高さを指定 */
position: relative; /* 子要素の基準位置とする */
margin: auto;
}
.fade-slideshow-container .slide {
list-style: none;
position: absolute; /* 画像を重ねる */
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0; /* 最初は透明にする */
animation: fade-slideshow 16s linear infinite;
}
.fade-slideshow-container .slide img {
width: 100%;
height: 100%;
object-fit: cover; /* 画像の比率を保ったままトリミング */
}
/* アニメーションの遅延時間を設定 */
.fade-slideshow-container .slide:nth-child(2) {
animation-delay: 4s;
}
.fade-slideshow-container .slide:nth-child(3) {
animation-delay: 8s;
}
.fade-slideshow-container .slide:nth-child(4) {
animation-delay: 12s;
}
/* フェードアニメーションの定義 */
@keyframes fade-slideshow {
0% { opacity: 0; }
12.5% { opacity: 1; } /* 2秒かけてフェードイン */
25% { opacity: 1; } /* 2秒間表示 */
37.5% { opacity: 0; } /* 2秒かけてフェードアウト */
100% { opacity: 0; }
}
コードの詳しい解説
以下に、上記のコードについての解説を載せていきます。
画像を重ねる仕組み
.fade-slideshow-wrapper
にposition: relative;
を、.slide
にposition: absolute;
を指定しています。
これにより、全li
要素が親要素である.fade-slideshow-wrapper
の左上を基準として配置されるため、すべての画像が同じ位置に重なった状態になります。
アニメーションの仕組み
@keyframes fade-slideshow
でopacity
の値を変化させています。
opacity
は要素の不透明度を0(完全に透明)から1(完全に不透明)の間で指定するプロパティです。
0%
から12.5%
にかけてopacity
が1
になり、画像がフェードインします。12.5%
から25%
まではopacity
が1
のままで、画像が表示され続けます。25%
から37.5%
にかけてopacity
が0
に戻り、画像がフェードアウトします。- 残りの時間は透明のままです。
表示タイミングをずらす仕組み
すべてのアニメーションが同時に始まってしまうと、画像が一斉に表示されてしまうため、animation-delay
を使って各画像のアニメーション開始時間をずらしています。
animation: fade-slideshow 16s ...
と設定したので、アニメーション全体の長さは16秒です。
画像1枚あたりの表示時間は16秒 ÷ 4枚 = 4秒
となります。
- 1枚目(
:nth-child(1)
)はdelay
なしで0秒後に開始。 - 2枚目(
:nth-child(2)
)はanimation-delay: 4s;
で4秒後に開始。 - 3枚目(
:nth-child(3)
)はanimation-delay: 8s;
で8秒後に開始。
このようにタイミングをずらすことで、1枚目が消える頃に2枚目が現れる、という動きが実現できるのです。
もっと高機能なスライドショーを実装したい場合は?
CSSだけでも様々なスライドショーは作れますが、より複雑な機能を求めるならJavaScriptライブラリの活用も視野に入れるとよいでしょう。
ここでは、ライブラリを使うことのメリットと、代表的なものを紹介します。
JavaScriptライブラリの活用
「左右の矢印でスライドを切り替えたい」「今何枚目かを示すインジケーター(点)が欲しい」「スマホでスワイプ操作をしたい」といった高度な機能を実装したい場合、CSSだけでは限界があります。
そんな時に役立つのが「Swiper.js」のようなJavaScriptライブラリです。
これらはスライドショー作成に特化した便利な機能が詰まったツールキットのようなもので、数行のコードを追加するだけで、高機能なスライドショーを簡単に導入できます。
ライブラリを使うメリット・デメリット
■矢印ナビゲーションやページネーションなど、CSSだけでは難しい機能が簡単に実装できる
■レスポンシブ対応やタッチ操作(スワイプ)にも標準で対応していることが多い
■多くの開発者に使われており、ドキュメントや情報が豊富で安心
■外部ファイルを読み込むため、ページの表示速度にわずかながら影響が出る可能性がある
■ライブラリの仕様を学習する必要がある
シンプルなスライドショーで十分な場合はHTMLとCSSで、よりインタラクティブで多機能なものを求める場合はライブラリを導入するなど、目的に応じて使い分けるのがおすすめです。
まとめ
今回は、HTMLとCSSだけでスライドショーを実装する方法について、横スクロールとフェードの2種類を例に解説しました。
なお、HTMLを始めとする言語を体系的に学び、効率よくスキルを高めるには、プログラミングスクールを利用するのも有効です。
細かな疑問がすぐに解決するだけでなく、現役エンジニアが「質の高いポートフォリオ」を作成するための手助けをしてくれたり、エンジニア就職・転職のコツを教えてくれたりするなど、様々なメリットがありますので、独学に疲れた方は検討してみてはいかがでしょうか。