【備忘録】CSSとJavaScriptライブラリで3Dのフリップカードを作った

# はじめに

初投稿です。現在フロントエンジニアを目指して学習中です。アウトプット及び備忘録としてQiita始めました。

本記事の目的は自分が忘れないように記録しておくためです。間違っている箇所等ありましたら、ご指摘頂けると助かります。

## 流れ

CSS で 3D アニメーションを実装し、*Swiper.js*を使って 3D のフリップカードを実装する。

:::note info
Swiper.js とはスライダーが作れる JavaScript のライブラリのこと。レスポンシブにも対応。
:::

## 結果

作れたもの。

![](https://media.giphy.com/media/mxjzVdNAUU1Uiok7ee/giphy.gif)

## 手順

1. HTML を書く(カード 1 枚分のみ。wrapper などは省略。)


```html
<!--　5枚のカード全体のラッパー　-->
 <div class="packages-wrapper swiper-wrapper">
    <!-- カード単体のラッパー -->
    <div class="package swiper-slide">

        <!-- カードの表面 -->
        <div class="package-face package-front">
            <div class="img-wrapper">
                <img src="img/package-1.jpg" alt="" />
            </div>
            <div class="package-text">
                <h4 class="package-name">Discover Japan</h4>
                    <p class="package-paragraph">
                        in-depth cultural experience
                    </p>
            </div>
        </div>

        <!-- カードの裏側 -->
        <div class="package-face package-back">
            <p class="package-tags">
                <span class="tag place">Kyoto, Tokyo</span>
                <span class="tag culture">Culture</span>
                <span class="tag food">Food</span>
            </p>
            <h5 class="price">$3,900</h5>
            <p class="term">10 days</p>
            <button class="btn primary-btn">Check More</button>
        </div>
    </div>

.....
</div>
```

2. カードの表面と裏面を CSS でスタイリング＋ 3D のスタイリング

```css
/*　カード全体のラッパー　*/
.packages-wrapper {
  width: 100%;
  height: 70%;
  padding: 3rem 0 4rem 0;
  display: flex;
  flex-direction: row;

  /* Perspectiveを指定することで、このラッパーを3Dで使うよう指定。値はユーザーからの距離を表していると考える　*/
  perspective: 1000rem;
  -webkit-perspective: 1000rem;
  -moz-perspective: 1000rem;
  -ms-perspective: 1000rem;
}


/* カード単体の大きさなどスライリング　*/
.package {
  width: 300px !important;
  height: 400px !important;

  /* perserveを指定することで、これのラッパーから3D環境を受け継ぐ*/
  transform-style: preserve-3d;
  -webkit-transform-style: preserve-3d;
  -moz-transform-style: preserve-3d;
  position: relative;
  margin: 0 0.5rem;
  box-shadow: 0.1rem 0.1rem 0.1rem rgba(0, 0, 0, 0.3);
}

/* カード表面と裏面共通クラスのスタイリング　*/
.package-face {
  width: 100%;
  height: 100%;
  position: absolute;
  top: 0;
  left: 0;
}

/* カード表面　*/
.package-front {
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  text-align: end;
  transform: rotateY(0deg);
  -webkit-transform: rotateY(0deg);
  -ms-transform: rotateY(0deg);
  position: relative;

  /*　この面が表にある時裏側を隠す　*/
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
  -moz-backface-visibility: hidden;
}

.package-text {
  position: absolute;
  bottom: 3rem;
  right: 2rem;
}

.package-text > *,
.package-back > * {
  color: var(--white-color);
  text-shadow: 0.1rem 0.1rem 1rem var(--secondary-color);
  font-family: var(--main-font-family);
}

.package .package-name {
  font-size: 2rem;
  padding-bottom: 1rem;
}

.package-paragraph {
  font-size: 1rem;
}

/* カード表面　*/
.package-back {
  background-color: var(--secondary-color);
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;

  /*　裏側になるので、rotateしてスタイリング　*/
  transform: rotateY(180deg);
  -webkit-transform: rotateY(180deg);
  -ms-transform: rotateY(180deg);
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
  -moz-backface-visibility: hidden;
}
.package-tags {
  font-size: 1rem;
}

.price {
  font-size: 1.8rem;
  font-weight: 400;
  padding: 2.2rem 0;
}

.term {
  font-size: 1rem;
  margin-bottom: 4rem;
}

.package .img-wrapper img {
  opacity: 1;
}

```

## キーワード

⭐︎Perspective ->　親要素に 3D 環境設定。
⭐︎Transform-style: preserve-3d -> 子要素にも引き継ぐ。
⭐︎表面、裏面共通クラスでポジションをスタイリング、rotate にて表裏に配置。


3 . Swiper.js のインポート
   自分のScript.jsファイルで、Swiperオブジェクトのカスタムをするので、必ず、そのあとでインポートすること! 　　
   
ドキュメンテーションを見ながら、 HTMLのタグ内にSwiperクラス名を追記(上記のHTML参照)、  CSSでSwiperオブジェクトのスタイリングをすること。  
私はcoverflowのエフェクトを使用しました。

```html
<script src="https://unpkg.com/swiper@7/swiper-bundle.min.js"></script>
    <script src="script.js"></script>
```


```js
var swiper = new Swiper(".mySwiper", {
  effect: "coverflow",
  grabCursor: true,
  centeredSlides: true,
  slidesPerView: "auto",
  coverflowEffect: {
    rotate: 100,
    stretch: 0,
    depth: 100,
    modifier: 1,
    slideShadows: true,
  },
  pagination: {
    el: ".swiper-pagination",
  },
});


```

## 感想
最初はCSSでスタイリングするときに、3Dにするためのプロパティなどベンダープリフィックスは意識しないでやってました。  開発中はChromeでやっていて、特に問題はなかったのですが、Safariで確認した時に、一部transformプロパティが効いておらず、ベンダープリフィックスを追加したところ、正常に動作しました。　　
今回はポートフォリオに乗せるプロジェクトの開発の一環で、ウェブデザインから開発まで行いました。
最終的にできたものは[こちら](https://yumimachino.github.io/JTRAVEL/)になります。

# 参考

3DのTransformプロパティについてはこちらを参考にしました。
[Intro to CSS 3D transforms](https://3dtransforms.desandro.com/box)

使ったライブラリ:
[Swiper.js](https://swiperjs.com)