画像にマスクをかけてスライドが切り替わるたびにカーテンのようにマスクが開いていくSwiperスライダーを実装してみる(パターン2)(備忘録)

今回は画像にマスクをかけてスライドが切り替わるたびにカーテンのようにマスクが開いていくSwiperスライダーを別のパターンで実装していく。

前回の記事とは見た目は全く同じ内容となっている。

前回の記事はこちら

何が変わったのかというと、HTML側の記述を見直し、前回書いた記事よりはカスタマイズ性が高い内容になったかと思う。

HTMLの記述について

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Swiperスライダー</title>
  <link rel="stylesheet" href="../reset.css">
  <link rel="stylesheet" href="https://unpkg.com/swiper@8/swiper-bundle.min.css" />
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main>
    <div class="swiperCont">
      <div class="swiper mySwiper">
        <div class="swiper-wrapper">
          <div class="swiper-slide">
            <div class="swiper-slide-inner">
              <img src="img1.jpg" />
            </div>
          </div>
          <div class="swiper-slide">
            <div class="swiper-slide-inner">
              <img src="img2.jpg" />
            </div>
          </div>
          <div class="swiper-slide">
            <div class="swiper-slide-inner">
              <img src="img3.jpg" />
            </div>
          </div>
          <div class="swiper-slide">
            <div class="swiper-slide-inner">
              <img src="img4.jpg" />
            </div>
          </div>
        </div>
      </div>
      <div class="swiper-pagination"></div>
      <div class="swiper-button-prev"></div>
      <div class="swiper-button-next"></div>
    </div>
    <section>
      <div class="ly_inner" id="menu1">
        <h2>menu1</h2>
        <div class="md_textblock">
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
        </div>
      </div>
    </section>
    <section>
      <div class="ly_inner" id="menu2">
        <h2>menu2</h2>
        <div class="md_textblock">
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
        </div>
      </div>
    </section>
    <section>
      <div class="ly_inner" id="menu3">
        <h2>menu3</h2>
        <div class="md_textblock">
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
        </div>
      </div>
    </section>
    <section>
      <div class="ly_inner" id="menu4">
        <h2>menu4</h2>
        <div class="md_textblock">
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
        </div>
      </div>
    </section>
    <section>
      <div class="ly_inner" id="menu5">
        <h2>menu5</h2>
        <div class="md_textblock">
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
        </div>
      </div>
    </section>
  </main>
  <script src="https://unpkg.com/swiper@8/swiper-bundle.min.js"></script>
  <script src="style.js"></script>
</body>
</html>

HTMLの記述はswiper-slideに対して入れ子でswiper-slide-innerを入れている点だ。

これにより、swiper-slide-innerで囲まれているもの全体にスライダーが適用されるため、カスタマイズがしやすくなる。

今後のブログでも紹介していく予定だが、例えば画像の下に文字を記載したり、画像に重なるように文字を置くことができたりする。他にもいろんなことができるようになる。

今回は、画像の上に重ねてマスクを擬似要素で対応するため、特にimgタグ以外は記載していない。

<div class="swiper-slide">
  <div class="swiper-slide-inner">
    <img src="img1.jpg" />
  </div>
</div>

CSSの記述について

@charset "utf-8";

/* ==========================
  初期設定
========================== */
*,
*::before,
*::after {
  box-sizing: border-box;
}

body {
  position: relative;
}

img {
  width: 100%;
}

/* ==========================
  swiperslider
========================== */
.swiperCont {
  width: 80%;
  margin: 0 auto;
  position: relative;
}

.swiper {
  width: 100%;
}

.swiper-button-next,
.swiper-rtl .swiper-button-prev,
.swiper-button-prev,
.swiper-rtl .swiper-button-next {
  background-color: #ccc;
  border-radius: 50%;
  padding: 30px;
}

.swiper-button-next,
.swiper-rtl .swiper-button-prev {
  right: -70px;
}

.swiper-button-prev,
.swiper-rtl .swiper-button-next {
  left: -70px;
}

.swiper-button-next:focus,
.swiper-rtl .swiper-button-prev:focus,
.swiper-button-prev:focus,
.swiper-rtl .swiper-button-next:focus {
  outline: none;
}

.swiper-button-prev:after,
.swiper-rtl .swiper-button-next:after,
.swiper-button-next:after,
.swiper-rtl .swiper-button-prev:after {
  color: #fff;
  font-size: 24px;
}

.swiper-pagination-bullet-active {
  opacity: var(--swiper-pagination-bullet-opacity, 1);
  background: #444;
}

.swiper-horizontal>.swiper-pagination-bullets,
.swiper-pagination-bullets.swiper-pagination-horizontal,
.swiper-pagination-custom,
.swiper-pagination-fraction {
  bottom: -30px;
}

.swiper-slide .swiper-slide-inner::before {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  content: "";
  background-color: #222;
  transition: 1s;
}
.swiper-slide.swiper-slide-active .swiper-slide-inner::before {
  width: 0;
}

@media screen and (max-width: 767px) {
  .swiperCont {
    width: 100%;
    padding: 0 70px;
  }

  .swiper-button-next,
  .swiper-rtl .swiper-button-prev {
    right: 10px;
  }

  .swiper-button-prev,
  .swiper-rtl .swiper-button-next {
    left: 10px;
  }

  .swiper-button-next,
  .swiper-rtl .swiper-button-prev,
  .swiper-button-prev,
  .swiper-rtl .swiper-button-next {
    padding: 24px;
  }

  .swiper-button-prev:after,
  .swiper-rtl .swiper-button-next:after,
  .swiper-button-next:after,
  .swiper-rtl .swiper-button-prev:after {
    font-size: 16px;
  }
}

/* ==========================
  コンテンツの中身
========================== */
.ly_inner {
  width: 100%;
  max-width: 1080px;
  margin: 100px auto;
  padding: 20px;
  background-color: #ccc;
}

.ly_inner h2 {
  font-size: 150%;
  font-weight: bold;
  margin-bottom: 30px;
}

.md_textblock>*+* {
  margin-top: 10px;
}

今回変更・追加している記述は下記になるが、特別なことはしていない。swiper-slide-innerに対して擬似要素を前回の記事同様にあてているだけである。

.swiper-slide .swiper-slide-inner::before {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  content: "";
  background-color: #222;
  transition: 1s;
}
.swiper-slide.swiper-slide-active .swiper-slide-inner::before {
  width: 0;
}

JavaScriptの記述について

'use strict'

// swiperslider
const swiper = new Swiper('.mySwiper', {
  loop: true,
  speed: 0,
  effect: 'fade',
  pagination: {
    el: '.swiper-pagination',
    clickable: true,
  },
  autoplay: {
    delay: 3000,
    disableOnInteraction: false,
  },
  navigation: {
    nextEl: '.swiper-button-next',
    prevEl: '.swiper-button-prev',
  },
})

JavaScriptは、speedを0にして、effectをfadeにすることで、スライダーが切り替わるときのアニメーションがふわっとではなく、パッとすぐに切り替わるようになるので、マスクがカーテンのようにに開いていくアニメーションが自然なかたちで実現できるようになる。

以上で実装完了だ。