ズームイン、ズームアウトしながら画像が切り替わるスライドショーと、流れるスライドショーについて、jQueryなどのライブラリはおろかjavaScriptなしで作る方法についてご紹介します。一部は本サイトのトップページでも使っているものとなります。

一気に説明せず、ひとつひとつの要素に分けてご説明していきます。

スライドショーをCSSのみ(javaScriptなし)で作る

画像が切り替わるスライドショー

(1)基本形

次のようなスライドショーをCSSだけで作成できます。

ソースコード

HTML
<div class="img-frame">
   <div class="img-01"></div>
   <div class="img-02"></div>
   <div class="img-03"></div>
</div>
CSS
.img-frame{
   position: relative;
   width: 70%;
   height: 300px;
   overflow: hidden;
   margin: 0 auto;
}
.img-01, .img-02, .img-03{
   position: absolute;
   top:0;
   left:0;
   width: 100%;
   height: 100%;
   background-size: cover;
   background-repeat: no-repeat;
}

.img-01{
   background-image: url('画像の場所');
   animation: slide-animation-01 24s infinite;
}
.img-02{
   background-image: url('画像の場所');
   animation: slide-animation-02 24s infinite;
}
.img-03{
   background-image: url('画像の場所');
   animation: slide-animation-03 24s infinite;
}

@keyframes slide-animation-01 {
   0% {opacity: 1; transform: scale(1.0);}
   30% {opacity: 1;}
   40% {opacity: 0; transform: scale(1.15);}
   90% {opacity: 0}
   100% {opacity: 1; transform: scale(1.0);}
 }
 @keyframes slide-animation-02 {
   0% {opacity: 0;}
   30% {opacity: 0; transform: scale(1.1);}
   40% {opacity: 1;}
   60% {opacity: 1;}
   70% {opacity: 0; transform: scale(1.0);}
   100% {opacity: 0;}
 }
 @keyframes slide-animation-03 {
   0% {opacity: 0;}
   60% {opacity: 0;  transform: scale(1.0);}
   70% {opacity: 1;}
   90% {opacity: 1;}
   100% {opacity: 0; transform: scale(1.1);}
 }

解説

以下、CSSセレクタで対象要素を説明します。

  • .img-frameで外枠を作っています。外枠の大きさをwidth: 70%height: 300pxとしていますが、そこは好きな大きさにできるところです。
  • 画像3枚は.img-01.img-02.img-03のそれぞれに背景画像として指定しています。ここはimg要素を使って普通に画像にしても実現可能なのですが、背景画像にした方がカスタマイズ性が高くできます。どのようにカスタマイズ性が違うのかは後述します。
  • .img-frameoverflow: hiddenを指定して、内枠の背景画像がはみ出したぶんを非表示にします。
  • .img-01.img-02.img-03はそれぞれ、position: absoluteとして、外枠に対して同じ位置で表示されるようにします。
  • .img-01.img-02.img-03それぞれに同じ時間(この例では24秒間ですが、好きな長さに設定可能)のanimationをつけています。3枚それぞれをCSSのanimationで、拡大縮小、透明度の変化をつけることでこのスライドショーが実現できます。

(2)上に半透明の矩形を重ねる

次のように上に半透明の矩形を乗せることもCSSで可能です。

ソースコード

先ほどの(1)のCSSに対して、以下の追記をすればこうなります。

CSS
.img-frame::after{
   content: '';
   position: absolute;
   top: 0;
   left: 0;
   width: 100%;
   height: 100%;
   background-color: rgba(0, 0, 0, .5);
}

解説

外枠に疑似要素を指定して、position: absolute;で外枠と同じ位置に半透明の矩形を乗せています。

(3)テキストを乗せる

次のようなこともCSSだけでできます。

京都

横浜

良い街

ソースコード

(1)のHTMLを次のように変え、疑似要素で付けている半透明の上に乗せた矩形は、外枠ではなく.img-03につける形に変更です。それ以外のCSSは(1)に対する追記です。

HTML
<div class="img-frame">
   <div class="img-01"><p class="msg msg-01">京都</p></div>
   <div class="img-02"><p class="msg msg-02">横浜</p></div>
   <div class="img-03 cover"><p class="msg msg-03">良い街</p></div>    
</div>
CSS
.msg{
   font-size: 20px;
   color: #fff;
   position: absolute;
   top: 50%;
   left: 50%;
   transform: translate(-50% , -50%);
}

.msg-01, .msg-02{
    text-shadow: 2px 2px 3px #000, -1px -1px 3px #000;
}

.img-03.cover::after{
   content: '';
   position: absolute;
   top: 0;
   left: 0;
   width: 100%;
   height: 100%;
   background-color: rgba(0, 0, 0, .7);
}

.msg-03{
   z-index:1;
}

解説

半透明の矩形を外枠に対してつけるのではなく、内枠の背景画像の3番目に対して付けてます。

あとはテキストの位置を、position: absolute;で外枠に対して中央に配置しようとしたんですが、何故か下寄りになりますね・・。内枠の背景画像と同じ階層にp要素を移しても結果は同じでした。

何故だろう・・分かる人いたら教えてください・・。

というわけで、そんなことを考えていたのでここ作るのに思ったより時間がかかってしまいました。

いつもはこういう場合、「えいっ」と調整してます、はい。

(4)角丸をつける、画像の大きさを変える

京都

横浜

良い街

ソースコード

(3)のソースコードのCSSに以下の変更/追記をするだけです。

CSS
.img-frame{
   width: 100%;
   height: 200px;
   clip-path: (0 round 0 0 0 50px);
} 

解説

外枠のwidthを70%から100%に、heightを300pxから200pxに変えています。

また、外枠にclip-pathで角丸をつけています。

こういうのが、img要素ではなく背景画像を使ったときにカスタマイズ性が高くなるところです。

角丸はborder-radiusでも同様に外枠に対して指定すれば付けられるのですが、border-radiusだとiOSでは現時点、つきません。なので、clip-pathにしています。
こういうの最近多いですね、Appleさん。

(5)画像の表示位置を変える

スマホだと調整が大変なので、ここではPCでだけ変わるようにしています。PCで違いをご確認ください

京都

横浜

良い街

ソースコード

(4)のソースコードのCSSに以下の追記をするだけです。上述の通り、ここではあえてPCでだけ変わるようにしています。

CSS
@media screen and (min-width:768px){
   .img-01{
      background-position: 0 -250px;
   }
   .img-02{
      background-position: 0 -200px;
   }
   .img-03{
      background-position: 0 -200px;
   }
}

解説

背景画像の位置はbackground-positionで変更できるので、それを利用しています。

これもimage要素を使うとできないことです。image要素を使った場合はtransformプロパティを使ってトライすることになると思うんですが、思うようにいかないと思います(私はそうでした)。

これも注意点があって、iOSとAndroidで大きく表示位置が異なります・・なので、ここまでカスタマイズしようと思うと、ちょっと検証が大変ではあります。

画像が流れるスライドショー

次のような流れるスライドショーもCSSだけでできてしまいます。

京都 横浜 良い街
京都 横浜 良い街
京都 横浜 良い街

ソースコード

HTML

<div class="slide-container">
   <div class="slide-wrapper">
      <img class="slide" src="画像の場所" alt="京都">
      <img class="slide" src="画像の場所" alt="横浜">
      <img class="slide" src="画像の場所" alt="良い街">
   </div>
   <div class="slide-wrapper">
      <img class="slide" src="画像の場所" alt="京都">
      <img class="slide" src="画像の場所" alt="横浜">
      <img class="slide" src="画像の場所" alt="良い街">
   </div>
   <div class="slide-wrapper">
      <img class="slide" src="画像の場所" alt="京都">
      <img class="slide" src="画像の場所" alt="横浜">
      <img class="slide" src="画像の場所" alt="良い街">
   </div>
</div>

CSS

.slide-container {
  width: 700px;
  display: flex;
  align-items: center;
  height: 340px;
  overflow: hidden;
}

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

.slide{
  width: 300px;
  object-fit: cover;
  border: 1px solid #ddd;
}

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

解説

外枠をoverflow: hidden;にしてはみ出す部分を表示させないようにし、3×3で9枚の画像をループさせて3枚の画像だけがループしているように見せるという方法です。

まとめ

CSSだけでスライドショー作れちゃうよシリーズでした。
ライブラリを使った方が実装は早いというケースももちろんあるとは思いますが、基本的にはJavaScriptを使うよりCSSのみの処理速度が速いと思います。また、ライブラリだと何か思ったように動かないというときに、環境のバグなのかカスタマイズの仕方が悪いのかの特定が難しくなりますし、ちゃんと動きの理屈を理解したコードの方が思ったようにいきやすかったりすると思います。

著者のイメージ画像

BringFlower|稲田 高洋

2003年から大手総合電機メーカーでUXデザインプロセスの研究、実践。UXデザイン専門家の育成プログラム開発。SEOにおいても重要なW3Cが定めるWeb標準仕様策定にウェブアクセシビリティの専門家として関わる。2010~2018年に人間中心設計専門家を保有。その後、不動産会社向けにSaaSを提供する企業の事業開発部で複数サービスを企画、ローンチ。CMSを提供し1000以上のサイトを分析。顧客サポート、サイト運営にも関わる。2022年3月にBringFlowerを開業し、SEOコンサル、デザイン、ウェブ制作を一手に受ける。グッドデザイン賞4件、ドイツユニバーサルデザイン賞2件、米国IDEA賞1件の受賞歴あり。