CSSで本の表紙を開くようなアニメーションをつける(スマホ簡易対応版)

CSSで本の表紙を開くようなアニメーションをつける(スマホ簡易対応版)
CSSで本の表紙を開くようなアニメーションをつける(スマホ簡易対応版)

前回の記事「CSSで本の表紙を開くようなアニメーションをつける」を元に、スマホ対応の追加だけを考えた案です(ブラウザの問題は未解決)。

「試したらできたレベル」なので作り方に問題がある可能性が高く、書くか迷いましたが、想定どうりに動かせた部分もあり、やはり記録として残したいと思います。

なお多くの部分が前回の記事と同じですが、今回のサンプル作成時に判明した問題の解決のため変更した部分もあります。

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

実現したいこと

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

スマホでも動作させる場合、hoverの代わりとしては以下が理想だとは思います。

  • 本をタップして開閉

しかしながらこれを実現する方法を考えた場合、本の内部のリンクを動作させたり、テキストをコピーできたりという動作を可能にする目処が立ちませんでした。

そこで簡易対応として考えていた以下の方法を試しました。

  • ボタンを押したら開閉させる

この方向で作成したのが後述するサンプルです。

仕組みと注記

今回のコードには注意するべき点がありますので、関係すると仕組みと問題点を記載します。

仕組み

ボタンは1つで良いため、偶数回のクリックでチェックを外せるtype="checkbox"を使っており、ボタンを本の下に配置するためinputタグとlabelタグを分離させています。

また、data属性を利用してボタンのラベルを「開く」と「閉じる」の切替も試していて、やりすぎたという自覚はありますが、案外動くものだなと…。

WordPressの投稿欄で使う場合

WordPressの投稿欄でこの記事のコードを使う場合、一点問題があります。

サンプルのHTMLを入力すると、labelタグの前にpタグの開始タグだけが自動整形処理で挿入されてしまい、以下の問題が生まれます。

  • 終了タグがない壊れたHTMLになる(ブラウザが自動で補完はしてくれる)
  • 想定していないpタグで囲まれるため、inputタグとlabelタグが同階層に存在しない状態になり、不具合が出る

そのためpタグ除去の仕組みを作成し、現在試験的に当サイトで実装中です。

pタグの自動整形に関してはそれぞれに対策(全体的な自動整形の停止など)が必要になる可能性もありますので、この点は留意してください。

コード1:IE対応/スマホ対応

以下サンプル。hoverでの動作も残していますが、ボタンで開いた状態でhoverさせても元に戻りません。

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

以下HTML。



<div class="book-wrap">
  <input id="book-simple-open" type="checkbox" name="book-simple-switch" value="action">

<div class="book-simple" id="book-simple-contents">

<div class="book-inbox">

<ul>

 	<li><a href="">テキストリンク</a>←リンクも使えます。</li>


 	<li>この本はCSSで作成されています。</li>


 	<li>カーソルがホバーしている間は開いたままです。</li>

</ul>

</div>

</div>

<label class="book-simple-switch" for="book-simple-open" data-book-simple-open="開く" data-book-simple-shut="閉じる">本を</label>
</div>

以下CSS。


/* 表紙 */
.book-simple {
  position: relative;
  box-sizing: border-box;
  width: 200px;
  height: 250px;
  margin-right: auto;
  margin-bottom: 20px;
  margin-left: auto;
  padding-bottom: 10px;
  -webkit-transition: box-shadow 2s ease;
          transition: box-shadow 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, #book-simple-open:checked ~ #book-simple-contents {
  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::before {
  position: absolute;
  z-index: 1;
  top: 0;
  left: 0;
  display: block;
  width: 100%;
  height: calc( 100% - 10px);
  content: '';
  -webkit-transition-timing-function: ease;
          transition-timing-function: ease;
  -webkit-transition-duration: 2.5s;
          transition-duration: 2.5s;
  -webkit-transition-property: transform;
          transition-property: transform;
  -webkit-transform-origin: 0 0;
          transform-origin: 0 0;
  background-color: #249690;
  box-shadow: 0 2px 0 0 #124f4b;
}
.book-simple:hover::before, #book-simple-open:checked ~ #book-simple-contents::before {
  -webkit-transform: rotateY(-185deg);
          transform: rotateY(-185deg);
}

/* 中身 */
.book-simple .book-inbox {
  position: relative;
  box-sizing: border-box;
  height: 100%;
  padding: 10px;
  transition: box-shadow 1.8s ease;
  transition-delay: .3s;
  background-color: #e2e1dc;
  box-shadow: 200px 0 1px 0 rgba(0,0,0,.4) inset,-2px 0 0 0 #249690;
}
.book-simple .book-inbox:after {
  position: absolute;
  bottom: -8px;
  left: 0;
  display: block;
  box-sizing: border-box;
  width: 100%;
  height: 8px;
  content: '';
  background-color: #afada3;
}
.book-simple:hover .book-inbox, #book-simple-open:checked ~ #book-simple-contents .book-inbox {
  box-shadow: -0 0 8px 0 rgba(0,0,0,.0) inset,-2px 0 0 0 #249690;
}

/* ボタン */
.book-simple-switch {
  display: block;
  width: 6em;
  margin-right: auto;
  margin-left: auto;
  padding: .5em;
  text-align: center;
  border: 1px solid #ccc;
  border-radius: 3px;
  background-color: #fff;
  box-shadow: 0 5px 0 0 #999;
}
input[name='book-simple-switch'] {
  display: none;
}
#book-simple-open ~ .book-simple-switch:after {
  content: attr(data-book-simple-open);
}
#book-simple-open:checked ~ .book-simple-switch:after {
  content: attr(data-book-simple-shut);
}

コード2:IE切り捨て/スマホ対応未完

以下サンプルですが、iPhoneでは表示がおかしくなります。

コード1は動いていたので、そこから考えますと「いろいろ付けすぎた」「CSSの書き方が悪い」などの理由になるかもしれません。

ちらつき対策などは試していませんが、現状では解決の目処たたず。

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

以下HTML。



<div class="book-wrap">
  <input id="book-open" type="checkbox" name="book-switch" value="action">

<div class="book" id="book-contents">

<div class="book-inbox">

<ul>

 	<li><a href="">テキストリンク</a>←リンクも使えます。</li>


 	<li>この本はCSSで作成されています。</li>


 	<li>カーソルがホバーしている間は開いたままです。</li>

</ul>

</div>

</div>


<label class="book-switch" for="book-open" data-book-open="開く" data-book-shut="閉じる">本を</label>
</div>

以下CSS。


/* 表紙 */
.book {
  position: relative;
  box-sizing: border-box;
  width: 200px;
  height: 250px;
  margin-right: auto;
  margin-bottom: 20px;
  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::before, .book::after, #book-open ~ #book-contents::before, #book-open ~ #book-contents::after {
  position: absolute;
  z-index: 1;
  top: 0;
  left: 0;
  display: block;
  width: calc(100% + 2px);
  height: calc( 100% - 10px);
  -webkit-transition-timing-function: ease;
          transition-timing-function: ease;
  -webkit-transition-duration: 2.5s;
          transition-duration: 2.5s;
  -webkit-transition-property: transform,background-color;
          transition-property: transform,background-color;
  -webkit-transform-origin: 0 0;
          transform-origin: 0 0;
}
.book::before {
  font-size: 3em;
  content: 'Book';
  -webkit-transform: translateZ(2px) rotateY(0deg);
          transform: translateZ(2px) rotateY(0deg);
  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: translateZ(1px) rotateY(0deg);
          transform: translateZ(1px) rotateY(0deg);
  background-color: #033330;
}
.book:hover::before, #book-open:checked ~ #book-contents::before {
  -webkit-transform: translateZ(1px) rotateY(-185deg);
          transform: translateZ(1px) rotateY(-185deg);
}
.book:hover::after, #book-open:checked ~ #book-contents::after {
  -webkit-transform: translateZ(2px) rotateY(-185deg);
          transform: translateZ(2px) rotateY(-185deg);
  background-color: #38b7b0;
}

/* 中身 */
.book-inbox {
  position: relative;
  box-sizing: border-box;
  height: 100%;
  padding: 10px;
  transition: box-shadow 1.8s ease;
  transition-delay: .3s;
  background-color: #e2e1dc;
  box-shadow: 200px 0 1px 0 rgba(0,0,0,.4) inset,-2px 0 0 0 #249690;
}
.book-inbox:after {
  position: absolute;
  bottom: -8px;
  left: 0;
  display: block;
  box-sizing: border-box;
  width: 100%;
  height: 8px;
  content: '';
  background-color: #afada3;
}
.book:hover .book-inbox, #book-open:checked ~ #book-contents .book-inbox {
  box-shadow: -0 0 8px 0 rgba(0,0,0,.0) inset,-2px 0 0 0 #249690;
}

/* ボタン */
.book-switch {
  display: block;
  width: 6em;
  margin-right: auto;
  margin-left: auto;
  padding: .5em;
  text-align: center;
  border: 1px solid #ccc;
  border-radius: 3px;
  background-color: #fff;
  box-shadow: 0 5px 0 0 #999;
}
input[name='book-switch'] {
  display: none;
}
#book-open ~ .book-switch:after {
  content: attr(data-book-open);
}
#book-open:checked ~ .book-switch:after {
  content: attr(data-book-shut);
}

参考サイト

結び

無理矢理作った感が強いのでやはり使用はあまりお勧めしませんが、仕組み的にはいろいろ試せたので、作った本人としてはよかったなという感想です。

11人がこの記事を評価

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

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