CSSで本の表紙を開くようなアニメーションをつける

CSSで本の表紙を開くようなアニメーションをつける
CSSで本の表紙を開くようなアニメーションをつける

それなりに見えるところまではできたと思うので、記事として残しておきたいと思います。

なお、紆余曲折がありサンプルの1つはIEの切り捨てです。

もう1つは、装飾や表現をシンプルにしてIEに対応させています。

構築環境
対応ブラウザIE不可

実現したいこと

実現したいことは以下の通り。

  • CSSだけで本が開くようなアニメーションをつける
  • 本の中のリンクやテキストは通常通り操作できるようにする

追記

スマホでも動作するサンプルを検討して記事にしています。

なお、新たな問題が浮上してしまい、この記事のシンプル版しか意図どうりに動きませんでした。

コード1:IE切り捨て

まず動作サンプルですが、hoverにしか対応していないのでスマホなどのタッチデバイスでは動作が確認できません。

  • テキストリンク←リンクも使用可。
  • この本はCSSで作成されています。
  • カーソルがhoverしている間は開いたままです。

続いてHTMLです(※上記サンプルの表紙と裏表紙の画像の設定は入っていません)。


<div class="book">
  <div class="book-inbox">
  <ul>
    <li><a href="">テキストリンク</a>←リンクも使えます。</li>
    <li>この本はCSSで作成されています。</li>
    <li>カーソルがホバーしている間は開いたままです。</li>
  </ul>
  </div>
</div>

装飾の都合上、内部に1つdivを作らなければなりませんでした。

続いてCSS。


.book {
  position: relative;
  box-sizing: border-box;
  width: 200px;
  height: 250px;
  margin-right: auto;
  margin-left: auto;
  padding-bottom: 10px;
  background-color: #124f4b;
  box-shadow: -2px 0 0 0 #124f4b,2px 5px 1px 4px rgba(0,0,0,.2);

  -webkit-perspective: 1000px;
          perspective: 1000px;
  -webkit-perspective-origin: 0 150%;
          perspective-origin: 0 150%;
  -webkit-transform-style: preserve-3d;
          transform-style: preserve-3d;
}
.book-inbox {
  box-sizing: border-box;
  height: 100%;
  padding: 10px;
  transition: all 1.8s ease;
  transition-delay: .3s;
  background-color: #e2e1dc;
  box-shadow: 0 8px 0 0 #afada3,200px 0 1px 0 rgba(0,0,0,.4) inset,-2px 0 0 0 #249690;
}
.book:hover .book-inbox {
  box-shadow: 0 8px 0 0 #afada3,-0 0 8px 0 rgba(0,0,0,.0) inset,-2px 0 0 0 #249690;
}
.book::before, .book::after {
  position: absolute;
  z-index: 1;
  top: 0;
  left: 0;
  display: block;
  width: 100%;
  height: calc( 100% - 10px);
  -webkit-transition: all 2.5s ease;
          transition: all 2.5s ease;
  -webkit-transform-origin: 0 0;
          transform-origin: 0 0;
}
.book::before {
  font-size: 3em;
  content: 'Book';
  -webkit-transform: rotateY(0deg) translateZ(1px);
          transform: rotateY(0deg) translateZ(1px);
  text-align: center;
  color: #fff;
  background-color: #249690;
  box-shadow: 0 2px 0 0 #124f4b;
  text-shadow: -1px -1px 0 rgba(0,0,0,.4);
}
.book::after {
  content: '';
  -webkit-transform: rotateY(0deg) translateZ(0px);
          transform: rotateY(0deg) translateZ(0px);
  background-color: #033330;
}
.book:hover::before, .book:active::before {
  -webkit-transform: rotateY(-185deg) translateZ(1px);
          transform: rotateY(-185deg) translateZ(1px);
}
.book:hover::after {
  -webkit-transform: rotateY(-185deg) translateZ(0px);
          transform: rotateY(-185deg) translateZ(0px);
  background-color: #38b7b0;
}

今回は大枠のdivの幅に合わせて数値を変更する必要のある部分が多めなので、その点あまりよろしくない状態です。

perspectiveやz軸などの扱いや、transitionの切り替えタイミング(今回であれば裏と表が変わるタイミングがどこなのか)が理解し切れていないので微妙な出来映えですが、勉強にはなりました。

z-indexを切り替える方法

translateZではなく、z-indexの値を変化させても実現は可能でしたが、IEとEdgeでは以下のような問題がありました。

  • hoverさせた瞬間に裏表紙が見えてしまう

z-indexのように変化に中間がない指定では、transition実行時に切り替わるタイミングとしてIEやEdgeの方が正しいのかどうかはまだ不明です。

しかしながら、正しかったとしても意図した動作にする方法が見つからなかったため、z-indexを使う方法でも問題がありました。

IEでの表示

IE11でサンプルを表示させると、最初から裏表紙が見えた状態になっています。このまま動作を開始させても表紙は見えません。

色々試したところ、以下の状態に見えました。

  • before疑似要素とafter疑似要素が別々のレイヤーに存在していて、 translateZの値を変更しても順序が入れ替わらない

イメージ的にはIE6とIE7のz-indexのバグに似ている感覚です。

この状態が解決できずIE対応は断念しました…。

なんとかIEで動かすためには

上記の問題はとりあえず脇において、今回のサンプルをIEでも使える形で考えると、前述のCSSの最下部に以下を追記すればある程度誤摩化せると思います。
※後述するシンプル版と同じ見た目を意図しています。


/* 全IEに適用 */
.book::before,.book:hover::before{
  color:transparent\0;
  color:transparent\9;
  text-shadow:none\0;
  text-shadow:none\9;
}
.book::after {
  content:none\0;
  content:none\9;
}

上記は以下のページを参考にしました。

裏表紙用の疑似要素を使わず、表紙のテキストを透明化することで、表紙と裏表紙の差をなくし違和感がでないようにする、という趣旨です。

見た目が貧相になるうえにCSSハックをつかわねばならないのがしんどいので、今回のサンプルを使う場合はIE切り捨て前提になると思います。

IEのハイコントラストモードを利用したCSSハック

IE11からダメなのでIE全体に効く方法はないかと探したところ、-ms-high-contrastを使うコードが散見されました。

しかし、以下のような記事も見つけました。

私自身は-ms-high-contrastを使うハックは使ったことがなかったのでほぼ初見でしたが、上記記事の主張に同意のため使用しないことにしました。

コード2:IE対応版

IE対応したシンプル版に変えてしまった方がまだ良いかもしれないので、以下にシンプル版のコードを記載したいと思います。

まずはサンプル。

  • テキストリンク←リンクも使用可。
  • この本はCSSで作成されています。
  • カーソルがhoverしている間は開いたままです。

表紙も裏表紙も装飾なしで同色ですが、影の動きは少し追加しています。

光源の位置を考えると動きが微妙なのですが、transitionを使う都合上、hoverさせた時と外した時の動きを別々に調整できないので、こんな感じが精一杯でした。

続いてHTML。


<div class="book-simple">
  <div class="book-inbox">
  <ul>
    <li><a href="">テキストリンク</a>←リンクも使えます。</li>
    <li>この本はCSSで作成されています。</li>
    <li>カーソルがホバーしている間は開いたままです。</li>
  </ul>
  </div>
</div>

続いてCSS。


.book-simple {
  position: relative;
  box-sizing: border-box;
  width: 200px;
  height: 250px;
  margin-right: auto;
  margin-left: auto;
  padding-bottom: 10px;
  -webkit-transition: all 2s ease;
          transition: all 2s ease;
  background-color: #124f4b;
  box-shadow: -2px 0 0 0 #124f4b,-1px 4px 1px 1px rgba(0,0,0,.2),20px 0 20px 0 rgba(0,0,0,0);

  -webkit-perspective: 1000px;
          perspective: 1000px;
  -webkit-perspective-origin: 0 150%;
          perspective-origin: 0 150%;
}
.book-simple:hover{
  box-shadow: -2px 0 0 0 #124f4b,0 4px 1px 1px rgba(0,0,0,.2),-195px 5px 1px -5px rgba(0,0,0,.2);
}
.book-simple .book-inbox {
  box-sizing: border-box;
  height: 100%;
  padding: 10px;
  transition: all 1.8s ease;
  transition-delay: .3s;
  background-color: #e2e1dc;
  box-shadow: 0 8px 0 0 #afada3,200px 0 1px 0 rgba(0,0,0,.4) inset,-2px 0 0 0 #249690;
}
.book-simple:hover .book-inbox {
  box-shadow: 0 8px 0 0 #afada3,-0 0 8px 0 rgba(0,0,0,.0) inset,-2px 0 0 0 #249690;
}
.book-simple::before {
  position: absolute;
  z-index: 1;
  top: 0;
  left: 0;
  display: block;
  width: 100%;
  height: calc( 100% - 10px);
  content: '';
  -webkit-transition: all 2.5s ease;
          transition: all 2.5s ease;
  -webkit-transform-origin: 0 0;
          transform-origin: 0 0;
  background-color: #249690;
  box-shadow: 0 2px 0 0 #124f4b;
}
.book-simple:hover::before {
  -webkit-transform: rotateY(-185deg);
          transform: rotateY(-185deg);
}

参考

参考にしたサイトは以下の通りです。

結び

アニメーションを設定する場合は基点や設定が重要ですが、3Dになると軸やパースなどさらに多くの設定が必要になります。

感覚的に「こうしたい」という形があってもなかなか設定できない(大抵は設定箇所の理解不足でしたが)のがもどかしく。

なお、当記事の手法ではスマホどころかIEとEdgeでも不具合があるので、お蔵入りはほぼ決定になりそうです。

開閉のトリガーとなるアクション

開閉のトリガーに関しては、スマホを考えるなら以下のように作るほうが良いとは思います。

  • PCはクリックで動作可能
  • スマホなどのタッチデバイスはタップで動作可能

上記を実現する構造がぼんやりと頭にありますが、同時に浮かぶ問題が解決しづらそうで試していません。

上手くいくなら後日改良版を作ってみたいと思いますが、現状ではブラウザの問題が解決できていないため実現は遠そうです。

24人がこの記事を評価

役に立ったよという方は上の「記事を評価する」ボタンをクリックしてもらえると嬉しいです。

連投防止のためにCookie使用。SNSへの投稿など他サービスとの連動は一切ありません。

コメント欄