この内容は古いバージョンです。最新バージョンを表示するには、戻るボタンを押してください。
バージョン:4
ページ更新者:guest
更新日時:2026-06-10 11:03:32

タイトル: スライダーの作成とカスタマイズ
SEOタイトル: JavaScript スライダー実装ガイド(Swiper / Slick / 自前実装 / React / Vue)

この本文には実行可能なタグ等が含まれるため、安全のためHTMLソースとして表示しています。本文データは変更していません。

<table border="1" cellpadding="6" cellspacing="0" style="border-collapse:collapse;background:#fffbea;border:1px solid #f4c430;margin:1em 0;width:100%"><tr><td style="background:#f4c430;color:#000;font-weight:bold;padding:8px">この記事の要点</td></tr><tr><td style="padding:10px"><ul><li>現在の定番は <strong>Swiper.js</strong>(タッチ・モバイル対応・依存なし)</li><li>昔ながらの選択肢: <strong>Slick.js</strong>(jQuery 必須) / <strong>jQuery UI Slider</strong>(つまみ型)</li><li>自前実装は <strong>touchstart / touchmove / touchend</strong> + <strong>transform: translateX()</strong> の組み合わせ</li><li>オプション: <strong>autoplay / loop / pagination / navigation / effect:"fade"</strong></li><li>フレームワーク版: <strong>Vue Awesome Swiper</strong> / <strong>swiper/react</strong> / <strong>react-slick</strong></li></ul></td></tr></table>
<h2>JavaScript スライダーの選択肢</h2>

<table border="1" cellpadding="6" cellspacing="0" style="border-collapse:collapse;width:100%">
<thead><tr style="background:#e3f2fd"><th>ライブラリ</th><th>特徴</th><th>サイズ</th></tr></thead>
<tbody>
<tr><td><strong>Swiper.js</strong></td><td>依存なし、タッチ最適化、超多機能</td><td>140KB(gzip 40KB)</td></tr>
<tr><td>Slick.js</td><td>jQuery 必須、レガシ案件に多い</td><td>40KB + jQuery</td></tr>
<tr><td>Glide.js</td><td>軽量、依存なし</td><td>30KB</td></tr>
<tr><td>Splide.js</td><td>アクセシビリティ重視</td><td>50KB</td></tr>
<tr><td>jQuery UI Slider</td><td>つまみ型(カルーセルでなく値選択)</td><td>jQuery UI</td></tr>
</tbody>
</table>

<h2>Swiper.js(推奨)</h2>

<p>2026 年現在、新規実装は Swiper.js 一択と言って良いほど。CDN ですぐ使えます:</p>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-html"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.css" />
<script src="https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.js"></script>

<div class="swiper" style="width:600px;height:400px">
    <div class="swiper-wrapper">
        <div class="swiper-slide"><img src="/img/1.jpg"></div>
        <div class="swiper-slide"><img src="/img/2.jpg"></div>
        <div class="swiper-slide"><img src="/img/3.jpg"></div>
    </div>
    <div class="swiper-pagination"></div>
    <div class="swiper-button-prev"></div>
    <div class="swiper-button-next"></div>
</div>

<script>
const swiper = new Swiper(&apos;.swiper&apos;, {
    loop: true,
    autoplay: { delay: 3000, disableOnInteraction: false },
    pagination: { el: &apos;.swiper-pagination&apos;, clickable: true },
    navigation: { nextEl: &apos;.swiper-button-next&apos;, prevEl: &apos;.swiper-button-prev&apos; },
    effect: &apos;slide&apos;,         // slide | fade | cube | coverflow | flip
    speed: 600,
});
</script></code></pre>
<h2>Swiper の主要オプション</h2>

<table border="1" cellpadding="6" cellspacing="0" style="border-collapse:collapse;width:100%">
<thead><tr style="background:#e3f2fd"><th>オプション</th><th>説明</th></tr></thead>
<tbody>
<tr><td><code>slidesPerView</code></td><td>同時に表示するスライド数(複数表示)</td></tr>
<tr><td><code>spaceBetween</code></td><td>スライド間の余白 (px)</td></tr>
<tr><td><code>loop</code></td><td>無限ループ</td></tr>
<tr><td><code>autoplay</code></td><td>自動再生 <code>{ delay: 3000 }</code></td></tr>
<tr><td><code>effect</code></td><td>slide / fade / cube / coverflow / flip / creative</td></tr>
<tr><td><code>breakpoints</code></td><td>レスポンシブ別オプション</td></tr>
<tr><td><code>centeredSlides</code></td><td>中央寄せ</td></tr>
<tr><td><code>lazy</code></td><td>画像遅延読み込み</td></tr>
</tbody>
</table>

<h2>レスポンシブ対応</h2>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-javascript">new Swiper(&apos;.swiper&apos;, {
    slidesPerView: 1,
    spaceBetween: 10,
    breakpoints: {
        640:  { slidesPerView: 2, spaceBetween: 20 },
        768:  { slidesPerView: 3, spaceBetween: 30 },
        1024: { slidesPerView: 4, spaceBetween: 40 },
    },
});</code></pre>
<h2>CSS カスタマイズ</h2>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-css">/* ページネーションの bullet を四角に */
.swiper-pagination-bullet {
    width: 20px;
    height: 4px;
    border-radius: 0;
    background: #ccc;
    opacity: 1;
}
.swiper-pagination-bullet-active {
    background: #ff6b6b;
}

/* prev/next ボタンの色 */
.swiper-button-prev,
.swiper-button-next {
    color: #ff6b6b;
    --swiper-navigation-size: 28px;
}

/* スライド画像をはみ出さない */
.swiper-slide img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}</code></pre>
<h2>React で使う(swiper/react)</h2>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-jsx">import { Swiper, SwiperSlide } from &apos;swiper/react&apos;;
import { Navigation, Pagination, Autoplay } from &apos;swiper/modules&apos;;
import &apos;swiper/css&apos;;
import &apos;swiper/css/navigation&apos;;
import &apos;swiper/css/pagination&apos;;

export default function Carousel({ items }) {
    return (
        <Swiper
            modules={[Navigation, Pagination, Autoplay]}
            navigation
            pagination={{ clickable: true }}
            autoplay={{ delay: 3000 }}
            loop
            spaceBetween={20}
            slidesPerView={1}
            breakpoints={{
                640: { slidesPerView: 2 },
                1024: { slidesPerView: 3 },
            }}
        >
            {items.map(item => (
                <SwiperSlide key={item.id}>
                    <img src={item.image} alt={item.title} />
                </SwiperSlide>
            ))}
        </Swiper>
    );
}</code></pre>
<h2>Vue で使う(vue-awesome-swiper / swiper/vue)</h2>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-vue"><template>
  <swiper
    :modules="modules"
    :slides-per-view="1"
    :space-between="20"
    navigation
    :pagination="{ clickable: true }"
    :autoplay="{ delay: 3000 }"
    loop
  >
    <swiper-slide v-for="item in items" :key="item.id">
      <img :src="item.image" />
    </swiper-slide>
  </swiper>
</template>

<script setup>
import { Swiper, SwiperSlide } from &apos;swiper/vue&apos;;
import { Navigation, Pagination, Autoplay } from &apos;swiper/modules&apos;;
import &apos;swiper/css&apos;;
import &apos;swiper/css/navigation&apos;;
import &apos;swiper/css/pagination&apos;;

const modules = [Navigation, Pagination, Autoplay];
defineProps([&apos;items&apos;]);
</script></code></pre>
<h2>Slick.js(レガシ案件向け)</h2>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-html"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/slick-carousel@1.8/slick/slick.css" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/slick-carousel@1.8/slick/slick-theme.css" />
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/slick-carousel@1.8/slick/slick.min.js"></script>

<div class="my-slider">
    <div><img src="/img/1.jpg"></div>
    <div><img src="/img/2.jpg"></div>
    <div><img src="/img/3.jpg"></div>
</div>

<script>
$(document).ready(function() {
    $(&apos;.my-slider&apos;).slick({
        autoplay: true,
        autoplaySpeed: 3000,
        dots: true,
        arrows: true,
        infinite: true,
        slidesToShow: 1,
    });
});
</script></code></pre>
<h2>自前実装(依存なし)</h2>

<p>ライブラリを使いたくない場合の最小実装:</p>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-html"><style>
.slider { position: relative; overflow: hidden; width: 600px; height: 300px; }
.slides { display: flex; transition: transform 0.5s ease; }
.slide  { min-width: 100%; }
.slide img { width: 100%; height: 300px; object-fit: cover; }
</style>

<div class="slider">
    <div class="slides">
        <div class="slide"><img src="/img/1.jpg"></div>
        <div class="slide"><img src="/img/2.jpg"></div>
        <div class="slide"><img src="/img/3.jpg"></div>
    </div>
</div>

<script>
const slides = document.querySelector(&apos;.slides&apos;);
let index = 0;
let startX = 0;
let dragX = 0;

setInterval(() => {
    index = (index + 1) % 3;
    slides.style.transform = `translateX(-${index * 100}%)`;
}, 3000);

slides.addEventListener(&apos;touchstart&apos;, e => {
    startX = e.touches[0].clientX;
});
slides.addEventListener(&apos;touchmove&apos;, e => {
    dragX = e.touches[0].clientX - startX;
});
slides.addEventListener(&apos;touchend&apos;, () => {
    if (Math.abs(dragX) > 50) {
        index = (index + (dragX < 0 ? 1 : -1) + 3) % 3;
        slides.style.transform = `translateX(-${index * 100}%)`;
    }
});
</script></code></pre>
<h2>jQuery UI Slider(値選択用つまみ)</h2>

<p>「スライダー」でも<strong>値を選ぶつまみ型 UI</strong>を作りたい場合はこちら:</p>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-javascript">// HTML: <div id="amount-slider"></div> <input id="amount" value="500">

$(&apos;#amount-slider&apos;).slider({
    min: 0,
    max: 1000,
    step: 10,
    value: 500,
    slide: function(event, ui) {
        $(&apos;#amount&apos;).val(ui.value);
    },
});</code></pre>
<h2>FAQ</h2>

<p><strong>Q: Swiper の loop で重複コンテンツが SEO に悪影響しない?</strong><br />
A: 内部的にクローンを <code>aria-hidden="true"</code> で複製しているだけで、Googlebot は実体を 1 つと認識します。</p>

<p><strong>Q: アクセシビリティ的にスライダーは推奨される?</strong><br />
A: 自動再生はユーザーの注意を奪うため、停止ボタン必須・<code>prefers-reduced-motion</code> 尊重・キーボード操作対応が WCAG 推奨です。</p>

<p><strong>Q: 画像が大量で遅い</strong><br />
A: Swiper の <code>lazy</code> オプションで遅延読み込み。または <code>loading="lazy"</code> 属性を画像に付与。</p>