MENU
カテゴリー
だいち
このブログの管理者
異業種で仕事をしながら、副業でWeb制作をしているアラサーリーマンです。
日々の勉強の記録や、お役立ち情報を発信していきます。
ホームページ制作などのお仕事に関するご依頼やご相談は、運営者情報のお問い合わせフォームかSNSのDMにて宜しくお願いします。

【CSSのみ】横方向に流れ続ける無限スライドショーの作り方

横向き矢印

どうも、ダイチです。

コンテンツが横方向に自動で流れ続けるスライドショー、と言われてイメージ湧きますでしょうか?

コンベアスライドショーともいいますが、今回はそちらをCSSのみで実装する方法をまとめました。

ECサイトなどで見かけることもありますし、iPhoneの方はApp Storeの中にこのスライドの動きがあるので見てみてください。

デモサイトも用意しているのでこちらもご確認ください。

jQueryのプラグインで実装することが多いですが、実はCSSだけでも結構簡単な記述で実現できますので、コードと合わせて解説していきます。

目次

横並びのレイアウトを作成

<ul class="slideshow">
    <li class="content">tomato</li>
    <li class="content">orange</li>
    <li class="content">blue</li>
    <li class="content">green</li>
</ul>
.content {
  width: 300px;
  height: 300px;
}

.content:nth-child(1) {
  background-color: tomato;
}

.content:nth-child(2) {
  background-color: orange;
}

.content:nth-child(3) {
  background-color: blue;
}

.content:nth-child(4) {
  background-color: green;
}

今こんな感じになっているかと思います。

ブロック縦並び状態

これを横並びにするために.contentの親要素にあたる.slideshowにdisplay: flex;をかけます。

.slideshow {
  display: flex;
}
横並びにした状態

次に要素を連続で流し続けるために同じ内容のcontentを下に2つ追加します。理由は後述しますが、ついでに.wrapとして親要素で包みます。

<div class="wrap">
 <ul class="slideshow">
    <li class="content">tomato</li>
    <li class="content">orange</li>
    <li class="content">blue</li>
    <li class="content">green</li>
 </ul>
 <ul class="slideshow">
    <li class="content">tomato</li>
    <li class="content">orange</li>
    <li class="content">blue</li>
    <li class="content">green</li>
 </ul>
 <ul class="slideshow">
    <li class="content">tomato</li>
    <li class="content">orange</li>
    <li class="content">blue</li>
    <li class="content">green</li>
 </ul>
</div>

これだけだと当然こうなりますね。

要素を重ねた状態

この3段を一列に並べるために.slideshowの親要素にあたる.wrapに対してdisplay: flex;をかけます。

.wrap {
  display: flex;
}

そうすると一列に並びます。

しかし、要素が画面外にはみ出るので横スクロールが表示されます。

横並びgif

ここではみ出た領域を隠すためのoverflow: hidden;を設定します。また、他パターンで高さが必要になるため予め.contentを包む高さを設定し、align-items: center;で中央揃えにします。

.wrap {
  display: flex;
  align-items: center;
 height: 340px; 
 overflow: hidden;
}

ここで下準備は完了なので、ここまでのコードをまとめて記述します。

<div class="wrap">
    <ul class="slideshow">
        <li class="content">tomato</li>
        <li class="content">orange</li>
        <li class="content">blue</li>
        <li class="content">green</li>
    </ul>
    <ul class="slideshow">
        <li class="content">tomato</li>
        <li class="content">orange</li>
        <li class="content">blue</li>
        <li class="content">green</li>
    </ul>
    <ul class="slideshow">
        <li class="content">tomato</li>
        <li class="content">orange</li>
        <li class="content">blue</li>
        <li class="content">green</li>
    </ul>
</div>
.wrap {
  display: flex;
  align-items: center;
 height: 340px; 
 overflow: hidden;
}

.slideshow {
  display: flex;
}

.content {
  width: 300px;
  height: 300px;
}

.content:nth-child(1) {
  background-color: tomato;
}

.content:nth-child(2) {
  background-color: orange;
}

.content:nth-child(3) {
  background-color: blue;
}

.content:nth-child(4) {
  background-color: green;
}

スライドアニメーションを設定する

.slideshow {
  display: flex;
  animation: loop-slide 20s infinite linear 1s both;
}

@keyframes loop-slide {
  from {
    transform: translateX(0);
  }
  to {
    transform: translateX(-100%);
  }
} 

animationプロパティを解説

ショートハンドで記述したanimationプロパティを分解します。

animation-name: loop-slide;      /* アニメーション名 */
animation-duration: 20s;        /* 開始から終了までの所要時間 */
animation-iteration-count: infinite; /* アニメーションのループ回数 */
animation-timing-function: linear;  /* 動きの加減速 */
animation-delay: 1s;           /* アニメーションが開始するまでの遅延時間 */
animation-fill-mode: both;            /* アニメーション開始前・終了後の挙動 */

ポイントはanimation-iteration-countを infiniteとし、無限ループを実行させている点です。

また、animation-fill-modeを bothとすることで、アニメーション開始前と終了後にキーフレームアニメーションで指定したプロパティが適用されるので、連続性を表現できます。

keyframesを解説

from { transform: translateX(0);}は開始地点の指定なし=動かしていない状態を意味しています。

to { transform: translateX(-100%); }は親要素(.wrap)の幅100%分左方向に移動させる状態。要は.slideshowに入っている4つのブロックがまるごと画面外に移動して消える、という指定です。

※HTMLに同じ.slideshowを3連続で記述したのも、1つだけだと画面幅より小さくなり、スライドのアニメーションに連続性が持たせられなくなるためだから、ということです。

これでこんな感じのスライドショーが実装できます。

横並びアニメーションgif

ホバー時に動きを止める実装

ここからは必要であれば。

<div class="wrap slide-paused" ontouchstart="">
</div>

hoverさせる用のクラスとして、.wrapと同じタグに.slide-pausedというクラスを付与します。(ontouchstart=”” はスマホタップ時に反応させる為の記述で、スライドアニメーションの動き自体には関係ありません)

.slide-paused:hover .slideshow {
  animation-play-state: paused;
}

.slide-pausedに対してhoverクラスを設定し、子要素の.slideshowに動きをつけます。

animation-play-stateプロパティは、要素にキーフレームアニメーションを適用する場合の動きをつけるもので、pausedを指定すると一時停止にすることができます。これによりhover時にスライドコンテンツが止まることになります。

hoverで止まるスライドgif

ホバー時に要素へ動きを与える

スライドショーの動きとは関係ないですが、おまけで載せておきます。

.contentにホバー時の装飾をつけるためのクラス.content-hoverを追加します。

<li class="content content-hover">tomato</li>
.content-hover {
  transition: all 0.2s;
}

.content-hover:hover {
  transform: translateY(-20px);
  border-radius: 0 10%;
  box-shadow: 0 3px 10px 0 #333;
  opacity: 0.8;
  cursor: pointer;
}

transition: all 0.2s;でホバーした際の動きにスピードをつけます。

transform: translateY(-20px);で要素を上に移動させます。

border-radius: 0 10%;で右上と左下の角を10%丸めます。

box-shadow: 0 3px 10px 0 #333;で影をつけます。

opacity: 0.8;で透明度を上げます。

hoverで形が変わる

デモサイトのコード一覧

改めてデモサイトのコードを記載します。

<h1>ループで流れる横スライドショー</h1>
      <h2>無限スクロール例1</h2>
      <div class="wrap">
        <ul class="slideshow">
          <li class="content">tomato</li>
          <li class="content">orange</li>
          <li class="content">blue</li>
          <li class="content">green</li>
        </ul>
        <ul class="slideshow">
          <li class="content">tomato</li>
          <li class="content">orange</li>
          <li class="content">blue</li>
          <li class="content">green</li>
        </ul>
        <ul class="slideshow">
          <li class="content">tomato</li>
          <li class="content">orange</li>
          <li class="content">blue</li>
          <li class="content">green</li>
        </ul>
      </div>

      <h2>無限スクロール例2(ホバー時にストップ)</h2>
      <div class="wrap slide-paused" ontouchstart="">
        <ul class="slideshow">
          <li class="content">tomato</li>
          <li class="content">orange</li>
          <li class="content">blue</li>
          <li class="content">green</li>
        </ul>
        <ul class="slideshow">
          <li class="content">tomato</li>
          <li class="content">orange</li>
          <li class="content">blue</li>
          <li class="content">green</li>
        </ul>
        <ul class="slideshow">
          <li class="content">tomato</li>
          <li class="content">orange</li>
          <li class="content">blue</li>
          <li class="content">green</li>
        </ul>
      </div>

      <h2>無限スクロール例3(ホバー時にストップ+ピックアップ)</h2>
      <div class="wrap slide-paused" ontouchstart="">
        <ul class="slideshow">
          <li class="content content-hover">tomato</li>
          <li class="content content-hover">orange</li>
          <li class="content content-hover">blue</li>
          <li class="content content-hover">green</li>
        </ul>
        <ul class="slideshow">
          <li class="content content-hover">tomato</li>
          <li class="content content-hover">orange</li>
          <li class="content content-hover">blue</li>
          <li class="content content-hover">green</li>
        </ul>
        <ul class="slideshow">
          <li class="content content-hover">tomato</li>
          <li class="content content-hover">orange</li>
          <li class="content content-hover">blue</li>
          <li class="content content-hover">green</li>
        </ul>
      </div>
* {
  box-sizing: border-box;
  list-style: none;
  padding: 0;
  margin: 0;
}

body {
  padding: 30px 50px;
}

h1 {
  margin-bottom: 100px;
}

h2 {
  margin-bottom: 50px;
}

/* スライドする要素 */
.content {
  width: 300px;
  height: 300px;
}

.content:nth-child(1) {
  background-color: tomato;
}

.content:nth-child(2) {
  background-color: orange;
}

.content:nth-child(3) {
  background-color: blue;
}

.content:nth-child(4) {
  background-color: green;
}

/* スライドレールの枠 */
.wrap {
  overflow: hidden;
  display: flex;
  align-items: center;
  height: 340px; 
  margin-bottom: 100px;
}

/* content4つをまとめたスライドブロック */
.slideshow {
  display: flex;
  -webkit-animation: loop-slide 20s infinite linear 1s both;
  animation: loop-slide 20s infinite linear 1s both;
}

@-webkit-keyframes loop-slide { 
  from {
    transform: translateX(0);
  }
  to {
    transform: translateX(-100%);
  }
}

@keyframes loop-slide {
  from {
    transform: translateX(0);
  }
  to {
    transform: translateX(-100%);
  }
} 

/* ホバー時に動きを止める(パターン2・3)*/
.slide-paused:hover .slideshow {
  -webkit-animation-play-state: paused;
  animation-play-state: paused;
}

/* ホバー時の装飾(パターン3) */
.content-hover {
  transition: all 0.2s;
  margin-right: 20px;
}

.content-hover:hover {
  transform: translateY(-20px);
  border-radius: 0 10%;
  box-shadow: 0 3px 10px 0 #333;
  opacity: 0.8;
  cursor: pointer;
}

メディアクエリ のCSSは動きに関係ないのでここには載せてません。

また、上では説明してませんが、デモサイトレイアウト用の要素間marginやベンダープレフィックスなどを記載しています。

まとめ

ECサイトやキャンペーンサイトなどで見かけることがある、横方向自動スクロールの実装方法でしたがいかがでしたでしょうか?

しっかり見せたいコンテンツにはあまり適さないアニメーションかと思いますが、要素が多い場合などの装飾としてはいいかと思います。

また、コーディング勉強中の方は自分のエディタにコードをコピペし、数値などをいじりながら変化を見ることでアウトプットするのがオススメです。

ただ、ここで紹介した動き以上に複雑にしたい場合はjs・jQueryが必要になります。そのあたりもまとめられたら公開したいと思います!

シンプルな実装であれば今回のようにCSSのみでも十分かと思うので、参考にしていただけると嬉しいです。

それでは今回はこのへんで!

横向き矢印

この記事が気に入ったら
フォローしてね!

よかったらシェアしてね!

この記事を書いた人

異業種で仕事をしながら、副業でWeb制作をしているアラサーリーマンです。
日々の勉強の記録や、お役立ち情報を発信していきます。
ホームページ制作などのお仕事に関するご依頼やご相談は、運営者情報のお問い合わせフォームかSNSのDMにて宜しくお願いします。

コメント

コメントする

CAPTCHA


目次
閉じる