動き:CSSだけでスライドショーと横流れアニメーションを作ろう

完成イメージ

このベルトコンベア風の動きは CSS の @keyframes だけで実装していますが、 最後の画像が流れ終わったあと、また最初に戻るときに「パッ」と切り替わる印象になるのは、CSSの制限によるものです。もっと滑らかにループさせたい場合は JavaScript の処理で補うのが一般的です。 先の、JavaScript学習で、そのような動きを解決していきます。

JavaScriptを使わず、CSSだけでスライドショー(スライダー)や横スクロールアニメーションを実装する方法を解説します。animation@keyframestransform を組み合わせることで、画像が自動的に切り替わるアニメーションや、横方向に流れるカルーセル風の動きを再現できます。

「JavaScriptをまだ勉強していない」「HTMLとCSSだけで動きのあるサイトを作りたい」と考えている人におすすめの練習課題です。このページでは、以下のようなことが学べます:

  • CSSアニメーションだけで動くスライドショーの作り方
  • 画像が横に流れ続ける 無限ループアニメーション(横流れ)
  • animation-duration, animation-timing-function, infinite の意味と使い方
  • スマホ対応や画像比率を整えるコツ
  • JavaScriptのスライダー(Swiperなど)との違い・メリット・デメリット

初心者でもコピーして使えるコード例と、応用のヒントも掲載しています。

作成ファイル・保存場所

css-practice フォルダに以下のファイルを作成してください。

ファイル名内容
css-slideshow-scroll.htmlスライドショーと横流れアニメーションのHTMLファイル
css-slideshow-scroll.cssアニメーション用スタイルシート

HTMLとCSSは <link> タグで連携してください。

目的

  • CSSの @keyframes と animation を使って、JavaScriptを使わないスライド表現を学ぶ
  • フェードイン・フェードアウトで画像を順番に切り替えるスライドショーを作る
  • ベルトコンベアのように画像が横に流れるアニメーションを体験する
  • animation-delay や translateX() を活用し、タイミング制御の考え方を理解する

チェックポイント

  • @keyframes でのアニメーションの構文が正しく書けているか
  • opacity を使ったフェードの切り替えが自然にできているか
  • 画像の z-index や position を適切に制御できているか
  • translateX() と animation でループアニメーションができているか
  • 表示エリア(overflow: hidden)が正しく設定されているか

HTML構造の例

下記の例は、ダミー画像を使用しています。下記の構造はコピーをして使用してください。

<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CSS Practice 07</title>
    <link rel="stylesheet" href="css-slideshow-scroll.css">
</head>

<body>
    <h1>CSSだけでスライドショーとベルトコンベア風アニメーション</h1>

    <main>
        <!-- スライドショー(フェードイン・アウト) -->
        <section class="slider">
            <img src="https://dummy.kobeya.com/?width=600&height=400&bg=fffac7&color=000000&text=Slide_01&_=1745369315600"
                class="slide slide--1" alt="スライド画像1">
            <img src="https://dummy.kobeya.com/?width=600&height=400&bg=ffc7fa&color=000000&text=Slide_02&_=1745369315600"
                class="slide slide--2" alt="スライド画像2">
            <img src="https://dummy.kobeya.com/?width=600&height=400&bg=c7fffb&color=000000&text=Slide_03&_=1745369315600"
                class="slide slide--3" alt="スライド画像3">
        </section>

        <!-- ベルトコンベア風アニメーション -->
        <section class="belt">
            <div class="belt-track">
                <img src="https://dummy.kobeya.com/?width=300&height=200&bg=95f2f9&color=000000&text=image01&_=1745369423301"
                    alt="画像1">
                <img src="https://dummy.kobeya.com/?width=300&height=200&bg=95f2f9&color=000000&text=image02&_=1745369423301"
                    alt="画像2">
                <img src="https://dummy.kobeya.com/?width=300&height=200&bg=95f2f9&color=000000&text=image03&_=1745369423301"
                    alt="画像3">
                <img src="https://dummy.kobeya.com/?width=300&height=200&bg=95f2f9&color=000000&text=image04&_=1745369423301"
                    alt="画像4">
                <img src="https://dummy.kobeya.com/?width=300&height=200&bg=95f2f9&color=000000&text=image05&_=1745369423301"
                    alt="画像5">
                <img src="https://dummy.kobeya.com/?width=300&height=200&bg=95f2f9&color=000000&text=image06&_=1745369423301"
                    alt="画像6">
            </div>
        </section>
    </main>
</body>

</html>

画像の準備について

画像は、フォルダに写真を用意するか、ダミー画像ジェネレーター を活用してください。 alt 属性は、画像の内容に応じてわかりやすい説明文に変更しましょう。

スライドショーとベルトコンベア風アニメーションCSS

/* 全体のスタイル */
body {
    font-family: sans-serif;
    background-color: #f5f5f5;
    padding: 2rem;
    text-align: center;
}

h1 {
    margin-bottom: 2rem;
}

main {
    width: 1200px;
    margin: 0 auto;
}

/* スライドショー(フェードイン) */
.slider {
    position: relative;
    width: 600px;
    height: 400px;
    margin: 0 auto 3rem;
    overflow: hidden;
}

.slide {
    position: absolute;
    width: 100%;
    height: 100%;
    opacity: 0;
    top: 0;
    left: 0;
    animation: fade 9s infinite;
}

.slide--1 {
    animation-delay: 0s;
}

.slide--2 {
    animation-delay: 3s;
}

.slide--3 {
    animation-delay: 6s;
}

@keyframes fade {
    0% {
        opacity: 0;
    }

    10% {
        opacity: 1;
    }

    30% {
        opacity: 1;
    }

    40% {
        opacity: 0;
    }

    100% {
        opacity: 0;
    }
}

/* ベルトコンベア風 */
.belt {
    overflow: hidden;
    width: 100%;
    padding: 1rem 0;
}

.belt-track {
    display: flex;
    animation: scroll 20s linear infinite;
}

.belt-track img {
    width: 300px;
    height: 200px;
    flex-shrink: 0;
    margin-right: 1rem;
}

@keyframes scroll {
    0% {
        transform: translateX(0);
    }

    100% {
        transform: translateX(-50%);
    }
}


/* ==========================
   さらに調べてみよう!について
   animation-iteration-count / animation-timing-function / animation-direction
   ========================== */

/* animation-iteration-count:繰り返す回数を指定(infinite = 無限) */
/* .belt-track {
    animation-iteration-count: infinite;
} */

/* ⏳ animation-timing-function:動き方(加速・減速)を指定 */
/* ease, ease-in, ease-out, ease-in-out なども試せます */
/* 一定のスピード */
/* .belt-track {
    animation-timing-function: linear;
} */

/* animation-direction:アニメーションの進行方向を制御 */
/* alternate → 順→逆→順と交互に動く */
/* reverse → 逆向きにスタート */
/* 最初から最後へ(初期値) */
/* .belt-track {
    animation-direction: normal;
} */

CSS補足

  • スライドショーは opacity を使って、時間差で表示/非表示を切り替える形で作ります
  • ベルトコンベア風は、画像を inline-block + translateX で左に動かすアニメーションにします
  • スムーズな無限ループには画像を複製して繋げると滑らかになります

さらに調べてみよう!
animation-iteration-countanimation-timing-functionanimation-direction を使いこなすと、より自在な動きが実現できます。