はじめに
こんにちは。CMA制作部スタッフYaatonです。
WEBサイトのデザインでは、複数の画像が流れるように移動するスライダーがよく使われます。
JavaScriptのライブラリ(SlickSliderやSplideなど)を使うことでも実装は可能ですが、「ただ流れていくだけ」のスライダーであればCSSだけで実装することができます。
今回は、流れるスライダーをCSSだけで作る方法をご紹介します。
最終的なソースコードはこちらになります。
※CodePenの中ではスライダー画像はbase64エンコードしてあります。
See the Pen CSSだけで流れるスライダー by CMA Designer (@CMA-Designer) on CodePen.
このスライダーの特徴
- 切れ目なく、無限に流れるように見える
- スライダーの高さでサイズを調節できる
- 進む、戻る、クリックなどの操作はできない
- 画像を一枚ずつ配置するタイプではなく、1枚の大きな画像にまとめて使用する
- 画像はCSSの背景画像として読み込む
どうやって無限に流れるように見せるのか
このスライダーのポイントは、「無限に切れ目なく流れるように見せること」です。
HTMLでスライダーを構築する際、画像を1枚ずつ配置する方法も考えられますが、画面幅が広い環境では隙間ができてしまいます。
その隙間を埋めるには要素を複製する必要があり、いくつ複製すべきかという問題も発生します。
このスライダーでは、JavaScriptを使わずに画像を連続させるために、CSSのbackground-repeatを活用しています。
それでは、実装の流れを紹介していきます。
(1).slider_body要素
.slider_body要素には、スライダー画像の縦横比を指定します(aspect-ratio:横/縦;)。
(2).slider_image要素に画像を読み込む
.slider_bodyの子要素に.slider_imageを作ります。
.slider_imageの幅は、親要素(.slider_body)の幅+画面の幅(100vw)にします。
背景にスライダー画像を設定し、repeat-xで横方向に繰り返します。
(3)アニメーション
最後にアニメーションを設定します。
.slider_imageを親要素(.slider_body)の幅分だけ左方向に移動させ、この動きをループさせます。
.slider_imageが.slider_bodyの幅分スライドすると、画面左端から.slider_imageの右端までが100vwになります。
このように、画面幅がどれだけ大きくても.slider_imageは100vw+repeat-xで表示されるため、隙間が生じません。
また、スライダー画像がどれだけ大きくても、画像の幅分を確実にスライドするため、すべての画像が表示されます。
最終的なソースコード
<div class="slider">
<div class="slider_body">
<div class="slider_image"></div>
</div>
</div>
@keyframes nagareruSlider {
0% {
left: 0;
}
100% {
left: -100%;
}
}
.slider {
overflow: hidden;
.slider_body {
position: relative;
aspect-ratio: 1860 / 300; //スライダー画像の縦横比
width: auto;
height: 200px;
}
.slider_image {
position: absolute;
top: 0;
left: 0;
width: calc(100% + 100vw);
height: 100%;
animation: nagareruSlider 30s linear infinite;
background-image: url(/img/slider.png); //スライダーの画像
background-repeat: repeat-x;
background-position: left top;
background-size: auto 100%;
}
}
カスタマイズ
サイズ変更
heightの値でサイズ調整が簡単にできます。
.slider {
overflow: hidden;
.slider_body {
position: relative;
aspect-ratio: 1860 / 300;
width: auto;
height: 200px;
@media(max-width:576px){
height: 50vh; //環境に応じてサイズ調整が可能
}
...
逆方向
方向を逆向き(左→右)にしたい場合、.slider_imageにanimation-direction: reverse;を追加します。
.slider {
overflow: hidden;
&.--reverse {
.slider_image {
animation-direction: reverse;//逆方向
...
See the Pen CSSだけで流れるスライダー(逆方向) by CMA Designer (@CMA-Designer) on CodePen.
縦方向
幅やrepeat方向を変えれば縦方向にもできます。
See the Pen CSSだけで流れるスライダー(縦) by CMA Designer (@CMA-Designer) on CodePen.
斜め
斜めにしたい場合は、rotateを使用します。
.slider {
rotate: 330deg;
ただし、斜めにすると開始直後に隙間が見えてしまうため、隙間を埋める工夫が必要です。
.slide_imageの幅を、親要素(.slider_body)2つ分の幅+斜めにした時の距離にします。
斜めにした時の距離は、スライダーが入ってる要素の幅(底辺)と角度(斜辺と底辺の角度)を使って以下の様に求めます。
斜辺の長さ = \frac{底辺}{\cos\theta}
この式をCSSで記述するとこの様になります。
--slide-hypotenuse: calc(100vw / cos(330deg));
.slider_image {
width: calc(200% + var(--slide-hypotenuse));
}
アニメーションは、left: -100% → left: -200%にスライドさせます。
始点を-100%にすることで、あらかじめスライダー画像1枚分を左にずらして隙間を埋め、終点を-200%にすることで画像1枚分の幅だけスライドします。
@keyframes nagareruSlider {
0% {
left: -100%;
}
100% {
left: -200%;
}
}
See the Pen CSSだけで流れるスライダー(斜め) by CMA Designer (@CMA-Designer) on CodePen.
注意が必要な点
- .slider_imageではなく.slider_bodyにtransformを使ってスライドさせる方法もありますが、
@keyframesでtransformを使用するとSafariでちらつきが発生することがあります。will-changeやtranslateZ(0)を指定して改善する方法もありますが、今回は確実にちらつきを抑えるため、leftを使ってスライドさせています。 - スライダー画像が大きすぎるとページの読み込みに影響が出ます。WebP形式に変換するなどして軽量化しておくことをおすすめします。
まとめ
今回は、CSSだけを使って無限に切れ目なく流れるスライダーを実装する方法をご紹介しました。
ベースとなる仕組みを作ってしまえば、さまざまな動き方に応用できます。
記述量も多くなく、デザインパーツとしてカスタマイズしながら幅広く活用できそうです。
ぜひ実装の際の参考にしてみてください。





