CSS3アニメーションでつくるインターフェイス表現

第4回3次元で垂直に回る立方体のメニュー

今回のお題も、前回と同じく項目を並べたメニューだサンプル1⁠。ただし、今度は3次元のアニメーションにした。マウスポインタをメニュー項目に重ねると、立方体のように垂直に回る。CSS3を使えば、このような3次元の表現もできてしまう。CodePenに公開されたCSS Cube Flipを参考に、HTMLとCSSのコードの構成を改め、簡潔にした。

サンプル1 CSS3: Cube Flip

メニューのもとになる静的スタイル

まず、<body>要素に書くコードの構成だ。メニューは、つぎのように<ul>要素でリストとして組み立てる。メニュー項目を<li>要素class属性"component")とし、その中の<a>要素class属性"face")にテキストを加えた。そして、メニューの<ul>要素全体を、<div>要素class属性"container")で包んでいる。

<div class="container">
    <ul>
        <li class="component"><a href="#" class="face">C</a></li>
        <li class="component"><a href="#" class="face">U</a></li>
        <li class="component"><a href="#" class="face">B</a></li>
        <li class="component"><a href="#" class="face">E</a></li>
    </ul>
</div>

この<body>要素の記述に対して、つぎのような<style>要素を加える。今のところ、メニューは動きのない背景が四角い文字で図1⁠、マウスインタラクションも加えられていない。なお、CSSにベンダープレフィックスを付けなくて済むように、<script>要素で-prefix-freeを読み込んでいる(第1回のベンダープレフィックスと-prefix-freeの項参照⁠⁠。

<script src="lib/prefixfree.min.js"></script>
<style>
body {
    font-family: Arial, Helvetica, sans-serif;
}
.container {
    text-align: center;
    color: white;
}
.component {
    display: inline-block;
    line-height: 40px;
}
.face {
    display: inline-block;
    width: 40px;
    color: white;
    text-decoration: none;
    background: turquoise;
    cursor: default;
}
</style>
図1 メニューのもととなるスタイル
図1 メニューのもととなるスタイル

要素にポインタを重ねたら水平軸で回す

マウスポインタを重ねたら、要素が垂直に回るようにしよう。垂直の向きに回すということは、x軸を中心にするということだ。その場合、transformプロパティで用いるのがrotateX()関数である。引数には度数を表す単位のdegがつく。今回は、立方体のように回したい。つまり、前面を回し終えたら、上面になるということだ。そのためには、回し始めの軸は上辺とし、回しながらその垂直位置を真ん中にもってくればよい。まず、回転の原点はtransform-originプロパティで動かせる。水平方向と垂直方向のふたつの位置を与える。デフォルト値はともに中央のcenterだ。この垂直位置を上方のtopにずらす。

transform-origin: 水平位置 垂直位置

つぎに、回しながら要素を上に動かせば、回転軸は相対的に下がることになる。したがって、つぎのようにtransform-originプロパティで回転軸を上辺に定めたうえで、transformプロパティでは高さの半分translateY()関数で上に動かした。

.face {

    transition: 0.3s;
    transform-origin: center top;

}
.face:hover,
.face:focus {
    transform: rotateX(90deg) translateY(-20px);
}

さらに、3次元の表現を使うためには、あと2つ、つぎのようなプロパティの定めがいる。ひとつは、transform-styleプロパティだ。デフォルト値は2次元のflatなので、3次元にする値preserve-3dを与える。もうひとつは、perspectiveプロパティで遠近感を加える図2右⁠⁠。単位はpxで、数字が大きいほど遠近の差が小さくなる。デフォルト値は差のないnoneのため、そのままでは回っているというより伸び縮みしているように見えてしまう図2左⁠⁠。

.component {

    perspective: 500px;
}
.face {

    transform-style: preserve-3d;
}
図2 perspectiveプロパティで遠近感が加わる
図2 perspectiveプロパティで遠近感が加わる 図2 perspectiveプロパティで遠近感が加わる

ここまでのCSSの定めを以下のコード1にまとめた。これで、立方体にした場合の前面が、マウスポインタを重ねたときに水平軸で上面に回る図1⁠。

図3 項目にポインタを重ねると水平軸で回る
図3 項目にポインタを重ねると水平軸で回る
コード1 ポインタを重ねた項目が水平軸で回る
body {
    font-family: Arial, Helvetica, sans-serif;
}
.container {
    text-align: center;
    color: white;
}
.component {
    display: inline-block;
    line-height: 40px;
    perspective: 500px;
}
.face {
    display: inline-block;
    width: 40px;
    color: white;
    text-decoration: none;
    background: turquoise;
    cursor: default;
    transition: 0.3s;
    transform-origin: center top;
    transform-style: preserve-3d;
}
.face:hover,
.face:focus {
    transform: rotateX(90deg) translateY(-20px);
}

それぞれの項目に底面を加える

それでは、底面を加えよう。もちろん、HTMLコードに要素を書き足してもよい。だが今回は、::after擬似要素を使ってCSSで、つぎのようにつくってみよう。contentプロパティには表示する文字を与えることにする。それぞれの親要素class属性"face")がもつ文字を得るため、以下のHTMLコードのとおり、カスタムデータ属性に文字を定めた。その場合、属性の名前はdata-で始めるのが決まりだ。値はattr()関数で取り出せる。なお、底面なので初めにx軸で-90度回しておく。

.face::after {
    position: absolute;
    top: 100%;
    left: 0;
    width: 100%;
    background: darkcyan;
    content: attr(data-hover);
    transform: rotateX(-90deg);
    transform-origin: center top;
}
<div class="container">
    <ul>
        <li class="component"><a href="#" class="face" data-hover="C">C</a></li>
        <li class="component"><a href="#" class="face" data-hover="U">U</a></li>
        <li class="component"><a href="#" class="face" data-hover="B">B</a></li>
        <li class="component"><a href="#" class="face" data-hover="E">E</a></li>
    </ul>
</div>

もうひとつ、マウスポインタを重ねて底面が正面に回るとき、つぎのようにもとの色より少し明るめのカラーに変わるようにした。これで、項目にポインタを重ねると、立方体が垂直に回るアニメーションができあがる図4⁠。書き上がったCSSの定めは、以下のコード2にまとめた。

.face:hover::after,
.face:focus::after {
    background: lightseagreen;
}
図4 ポインタを重ねると項目が立方体のように回る
図4 ポインタを重ねると項目が立方体のように回る
コード2 ポインタを重ねた項目が水平軸で立方体のように回る
body {
    font-family: Arial, Helvetica, sans-serif;
}
.container {
    text-align: center;
    color: white;
}
.component {
    display: inline-block;
    line-height: 40px;
    perspective: 500px;
}
.face {
    display: inline-block;
    width: 40px;
    color: white;
    text-decoration: none;
    background: turquoise;
    cursor: default;
    transition: 0.3s;
    transform-origin: center top;
    transform-style: preserve-3d;
}
.face::after {
    position: absolute;
    top: 100%;
    left: 0;
    width: 100%;
    background: darkcyan;
    content: attr(data-hover);
    transform: rotateX(-90deg);
    transform-origin: center top;
}
.face:hover,
.face:focus {
    transform: rotateX(90deg) translateY(-20px);
}
.face:hover::after,
.face:focus::after {
    background: lightseagreen;
}

おすすめ記事

記事・ニュース一覧