タイトル: スライダーの作成とカスタマイズ
SEOタイトル: JavaScript スライダー実装ガイド(Swiper / Slick / 自前実装 / React / Vue)
| この記事の要点 |
|
JavaScript スライダーの選択肢
| ライブラリ | 特徴 | サイズ |
|---|---|---|
| Swiper.js | 依存なし、タッチ最適化、超多機能 | 140KB(gzip 40KB) |
| Slick.js | jQuery 必須、レガシ案件に多い | 40KB + jQuery |
| Glide.js | 軽量、依存なし | 30KB |
| Splide.js | アクセシビリティ重視 | 50KB |
| jQuery UI Slider | つまみ型(カルーセルでなく値選択) | jQuery UI |
Swiper.js(推奨)
2026 年現在、新規実装は Swiper.js 一択と言って良いほど。CDN ですぐ使えます:
<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('.swiper', {
loop: true,
autoplay: { delay: 3000, disableOnInteraction: false },
pagination: { el: '.swiper-pagination', clickable: true },
navigation: { nextEl: '.swiper-button-next', prevEl: '.swiper-button-prev' },
effect: 'slide', // slide | fade | cube | coverflow | flip
speed: 600,
});
</script>
Swiper の主要オプション
| オプション | 説明 |
|---|---|
slidesPerView | 同時に表示するスライド数(複数表示) |
spaceBetween | スライド間の余白 (px) |
loop | 無限ループ |
autoplay | 自動再生 { delay: 3000 } |
effect | slide / fade / cube / coverflow / flip / creative |
breakpoints | レスポンシブ別オプション |
centeredSlides | 中央寄せ |
lazy | 画像遅延読み込み |
レスポンシブ対応
new Swiper('.swiper', {
slidesPerView: 1,
spaceBetween: 10,
breakpoints: {
640: { slidesPerView: 2, spaceBetween: 20 },
768: { slidesPerView: 3, spaceBetween: 30 },
1024: { slidesPerView: 4, spaceBetween: 40 },
},
});
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;
}
React で使う(swiper/react)
import { Swiper, SwiperSlide } from 'swiper/react';
import { Navigation, Pagination, Autoplay } from 'swiper/modules';
import 'swiper/css';
import 'swiper/css/navigation';
import 'swiper/css/pagination';
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>
);
}
Vue で使う(vue-awesome-swiper / swiper/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 'swiper/vue';
import { Navigation, Pagination, Autoplay } from 'swiper/modules';
import 'swiper/css';
import 'swiper/css/navigation';
import 'swiper/css/pagination';
const modules = [Navigation, Pagination, Autoplay];
defineProps(['items']);
</script>
Slick.js(レガシ案件向け)
<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() {
$('.my-slider').slick({
autoplay: true,
autoplaySpeed: 3000,
dots: true,
arrows: true,
infinite: true,
slidesToShow: 1,
});
});
</script>
自前実装(依存なし)
ライブラリを使いたくない場合の最小実装:
<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('.slides');
let index = 0;
let startX = 0;
let dragX = 0;
setInterval(() => {
index = (index + 1) % 3;
slides.style.transform = `translateX(-${index * 100}%)`;
}, 3000);
slides.addEventListener('touchstart', e => {
startX = e.touches[0].clientX;
});
slides.addEventListener('touchmove', e => {
dragX = e.touches[0].clientX - startX;
});
slides.addEventListener('touchend', () => {
if (Math.abs(dragX) > 50) {
index = (index + (dragX < 0 ? 1 : -1) + 3) % 3;
slides.style.transform = `translateX(-${index * 100}%)`;
}
});
</script>
jQuery UI Slider(値選択用つまみ)
「スライダー」でも値を選ぶつまみ型 UIを作りたい場合はこちら:
// HTML: <div id="amount-slider"></div> <input id="amount" value="500">
$('#amount-slider').slider({
min: 0,
max: 1000,
step: 10,
value: 500,
slide: function(event, ui) {
$('#amount').val(ui.value);
},
});
FAQ
Q: Swiper の loop で重複コンテンツが SEO に悪影響しない?
A: 内部的にクローンを aria-hidden="true" で複製しているだけで、Googlebot は実体を 1 つと認識します。
Q: アクセシビリティ的にスライダーは推奨される?
A: 自動再生はユーザーの注意を奪うため、停止ボタン必須・prefers-reduced-motion 尊重・キーボード操作対応が WCAG 推奨です。
Q: 画像が大量で遅い
A: Swiper の lazy オプションで遅延読み込み。または loading="lazy" 属性を画像に付与。
📸 参考画像
※ 旧バージョンから引き継いだ参考画像です。手順・図解の補助としてご覧ください。
