
画像スライダーを作るとき、Slick.jsのようなライブラリでカクついた経験はありませんか?
この記事では、CSSアニメーションのみで“なめらか”に動く無限スライダーを構築する方法を紹介します。
JavaScriptの処理を極限まで減らすことで、
CPU負荷を抑えつつフレームレートを保つ、パフォーマンス重視のスライダーが完成します。
この実装の特徴
✅ Slick.js不要:CSSだけで動く
✅ カクつかない:GPU処理による滑らかなアニメーション
✅ hoverで一時停止対応
✅ レスポンシブ対応(PCとSPで速度調整)
✅ jQueryでulを自動複製して無限ループを再現
CodePen ソースコードサンプル
HTML
<div class="gallery">
<div class="gallery__container">
<div class="gallery__wrapper">
<ul class="gallery__list">
<li><a href=""><img src="https://web-developer-note.com/codepen/images/slide01.jpg" alt="" width="150" height="150" loading="lazy" class="imgauto"></a></li>
<li><a href=""><img src="https://web-developer-note.com/codepen/images/slide02.jpg" alt="" width="150" height="150" loading="lazy" class="imgauto"></a></li>
<li><a href=""><img src="https://web-developer-note.com/codepen/images/slide03.jpg" alt="" width="150" height="150" loading="lazy" class="imgauto"></a></li>
<li><a href=""><img src="https://web-developer-note.com/codepen/images/slide04.jpg" alt="" width="150" height="150" loading="lazy" class="imgauto"></a></li>
<li><a href=""><img src="https://web-developer-note.com/codepen/images/slide05.jpg" alt="" width="150" height="150" loading="lazy" class="imgauto"></a></li>
</ul>
<ul class="gallery__list">
<li><a href=""><img src="https://web-developer-note.com/codepen/images/slide01.jpg" alt="" width="150" height="150" loading="lazy" class="imgauto"></a></li>
<li><a href=""><img src="https://web-developer-note.com/codepen/images/slide02.jpg" alt="" width="150" height="150" loading="lazy" class="imgauto"></a></li>
<li><a href=""><img src="https://web-developer-note.com/codepen/images/slide03.jpg" alt="" width="150" height="150" loading="lazy" class="imgauto"></a></li>
<li><a href=""><img src="https://web-developer-note.com/codepen/images/slide04.jpg" alt="" width="150" height="150" loading="lazy" class="imgauto"></a></li>
<li><a href=""><img src="https://web-developer-note.com/codepen/images/slide05.jpg" alt="" width="150" height="150" loading="lazy" class="imgauto"></a></li>
</ul>
<ul class="gallery__list">
<li><a href=""><img src="https://web-developer-note.com/codepen/images/slide01.jpg" alt="" width="150" height="150" loading="lazy" class="imgauto"></a></li>
<li><a href=""><img src="https://web-developer-note.com/codepen/images/slide02.jpg" alt="" width="150" height="150" loading="lazy" class="imgauto"></a></li>
<li><a href=""><img src="https://web-developer-note.com/codepen/images/slide03.jpg" alt="" width="150" height="150" loading="lazy" class="imgauto"></a></li>
<li><a href=""><img src="https://web-developer-note.com/codepen/images/slide04.jpg" alt="" width="150" height="150" loading="lazy" class="imgauto"></a></li>
<li><a href=""><img src="https://web-developer-note.com/codepen/images/slide05.jpg" alt="" width="150" height="150" loading="lazy" class="imgauto"></a></li>
</ul>
<ul class="gallery__list">
<li><a href=""><img src="https://web-developer-note.com/codepen/images/slide01.jpg" alt="" width="150" height="150" loading="lazy" class="imgauto"></a></li>
<li><a href=""><img src="https://web-developer-note.com/codepen/images/slide02.jpg" alt="" width="150" height="150" loading="lazy" class="imgauto"></a></li>
<li><a href=""><img src="https://web-developer-note.com/codepen/images/slide03.jpg" alt="" width="150" height="150" loading="lazy" class="imgauto"></a></li>
<li><a href=""><img src="https://web-developer-note.com/codepen/images/slide04.jpg" alt="" width="150" height="150" loading="lazy" class="imgauto"></a></li>
<li><a href=""><img src="https://web-developer-note.com/codepen/images/slide05.jpg" alt="" width="150" height="150" loading="lazy" class="imgauto"></a></li>
</ul>
</div>
</div>
</div>CSS
.gallery__container {
overflow: hidden;
}
.gallery__wrapper {
display: flex;
width: max-content;
z-index: 1;
animation: scroll 90s linear infinite;
}
.gallery__wrapper:hover {
animation-play-state: paused;
}
.gallery__list {
display: flex;
margin: 0;
list-style: none;
}
.gallery__list li {
min-width: var(--this-width);
max-width: var(--this-width);
}
@keyframes scroll {
0% { transform: translateX(0); }
100% { transform: translateX(-50%); }
}
/* PC用:90秒でループ */
@media screen and (min-width: 768px){
.gallery__wrapper {
animation-duration: 90s;
}
.gallery__list li {
--this-width: clamp(200px, 25vw, 300px);
}
}
/* SP用:ゆっくりめに */
@media screen and (max-width: 767px){
.gallery__wrapper {
animation-duration: 120s;
}
.gallery__list li {
--this-width: 150px;
}
}カクつかない理由
- transformによる移動はGPU(ハードウェアアクセラレーション)で処理されるため、 CPU負荷が軽く、ブラウザ描画が滑らかになります。
- animation-timing-function: linear;で一定速度を保つことで、 余計な加減速が起こらず、カクつきが発生しにくくなります。
おまけ
ulを自動複製して自然なループへ
function galleryClone() {
const $gallery = $('.gallery__list');
const galleryCloneCount = 3; // 複製回数
for (let i = 0; i < galleryCloneCount; i++) {
$gallery.parent().append($gallery.clone());
}
}
$(document).ready(function() {
galleryClone();
});jsでリストを複製することも可能です。
jQueryのappend()で元のulを複製し、.gallery__wrapper内に3回追加することで、自然に流れ続けるようになります。
Slickとの比較:CSS版は圧倒的に軽い
| 比較項目 | CSSアニメーション版 | Slick.js |
|---|---|---|
| 初期ロード | 超軽量(CSSのみ) | JS読込あり |
| スクロールの滑らかさ | GPUでスムーズ | 多画像時にカクつく |
| 機能 | hover停止のみ | 矢印・ドット・フェードなど豊富 |
| コード量 | 約1/5 | 多め(依存関係あり) |
| メンテナンス | シンプル | バージョン依存あり |
まとめ
- CSSアニメーションだけでカクつかない無限スライダーを実装可能
- Slick.js不要で超軽量
- hover停止・レスポンシブ対応・自然なループ再現
- GPU処理によるスムーズな描画でパフォーマンス抜群
シンプルで“なめらか”なスライダーを求めるなら、CSSアニメーションだけで十分です。