最近のウェブデザインでは、ユーザーの目を引くインタラクティブな演出が求められることが多いです。中でも、カード型の UI を立体的に回転させるアニメーションは、ちょっとした驚きと楽しさを加えることができます。

この記事では、CSSだけで視差効果のある立体的な回転カードを作る方法をご紹介します。

LINE着せかえ「回るお寿司」販売中!

動作サンプル

まずは、実際に動作するサンプルです。マウスを乗せるとカードが回転し、その際に中の文字が浮き上がっているように見えます。

See the Pen CSS 3D Flip Card by YUTSUZO (@YUTSUZO) on CodePen.

動作サンプルのコード

HTML のコード

まずは、HTML のコードです。カード内の要素は、表側と裏側で分かれていて、さらにその中で浮き上がらせる要素を.innerで囲っています。

<div class="container">
  <div class="card">
    <div class="front">
      <div class="thumb"><img src="https://yutsuzo.com/wp-content/uploads/2025/03/css-subgrid-card-alignment-01.jpg" width="640" height="336"></div>
      <div class="inner">
        <h2>森の静寂と<br>鳥のさえずり</h2>
      </div>
    </div>
    <div class="back">
      <div class="inner">
        <p>静かな森の中で、鳥のさえずりと木々のざわめきを聞きながら心を落ち着かせる時間は、日々の喧騒を忘れさせてくれる。</p>
      </div>
    </div>
  </div>
  <div class="card">
    <div class="front">
      <div class="thumb"><img src="https://yutsuzo.com/wp-content/uploads/2025/03/css-subgrid-card-alignment-02.jpg" width="640" height="336"></div>
      <div class="inner">
        <h2>青空と流れる雲</h2>
      </div>
    </div>
    <div class="back">
      <div class="inner">
        <p>どこまでも広がる青空に浮かぶ雲を眺めながら、ゆっくりと流れる時間に身を委ねる。</p>
      </div>
    </div>
  </div>
  <div class="card">
    <div class="front">
      <div class="thumb"><img src="https://yutsuzo.com/wp-content/uploads/2025/03/css-subgrid-card-alignment-03.jpg" width="640" height="336"></div>
      <div class="inner">
        <h2>滝のせせらぎと<br>清らかな流れ</h2>
      </div>
    </div>
    <div class="back">
      <div class="inner">
        <p>清らかな水が岩を伝って流れ落ちる滝の音に耳を傾けると、大自然の力強さと癒しを同時に感じることができる。</p>
      </div>
    </div>
  </div>
</div>

CSS のコード

続いて、CSS のコードです。カードのアニメーションに関わる行をハイライト表示しています。

body {
  padding: 30px 15px;
  font-family: serif;
  background: #666;
}

.container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
  margin-inline: auto;
  max-width: 900px;
}

.card {
  --rotate-deg: 0deg;

  container-type: inline-size;
  position: relative;
  aspect-ratio: 1 / 1;
  color: #FFFFFF;

  &:hover {
    --rotate-deg: -180deg;
  }

  *,:before {
    backface-visibility: hidden;
    perspective: 1000px;
    transform-style: preserve-3d;
    transition: transform 0.5s;
  }

  .front {
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;

    .thumb {
      position: absolute;
      inset: 0;
      transform: rotateY(var(--rotate-deg));

      img {
        width: 100%;
        height: 100%;
        object-fit: cover;
      }
    }

    .inner {
      padding: 10%;
      transform: rotateY(var(--rotate-deg)) translateZ(50px) scale(0.95);
      text-shadow: 0 0 4px #000;

      h2 {
        text-align: center;
        font-size: 10cqw;
      }
    }
  }

  .back {
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;

    &:before {
      content: '';
      position: absolute;
      inset: 0;
      background: #333;
      transform: rotateY(calc(var(--rotate-deg) - 180deg));
    }

    .inner {
      padding: 10%;
      transform: rotateY(calc(var(--rotate-deg) - 180deg)) translateZ(50px) scale(0.95);
      text-shadow: 0 0 4px #000;
      
      p {
        font-size: 6cqw;
      }
    }
  }
}

実装のポイント

  • カード内の要素は個別で回転させる :
    カード全体を回転させてしまうと、回転の途中でホバー状態が解除されて戻ってしまうため、カード内の要素を個別で回転させます。また、その中でもtranslateZが異なる要素をそれぞれ個別で回転させることで、視差を付けることができます。
  • 浮き上がらせる要素にはtranslateZscaleを指定する :
    浮き上がっているように見せたい要素には、translateZを指定します。translateZの指定により、サイズが少し大きくなって文字がぼやけるので、scaleで元のサイズと同じくらいにリサイズすると軽減されます。
  • backface-visibility: hidden; で、裏側を表示しないようにする :
    回転させる要素は、裏側の状態のものは内容を表示させたくないので、backface-visibility: hidden;を指定します。ほとんどのブラウザではこれだけで十分なのですが、Safari ではtransform-style: preserve-3d;も必要だったため指定しています。

終わりに

CSS だけでここまでインタラクティブな動きを実現できるのは楽しいですね。シンプルな構造で動きにメリハリを出すことができるので、カード型の UI 以外にも応用可能です。ぜひ、ご自身のウェブサイトでも使ってみてください!