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

第8回マウスポインタを重ねたテキストのアニメーション(1)

今回はお題として、マウスポインタを重ねたときのテキストのアニメーションを取り上げたい。Inspiration for Text Styles and Hover Effectsを参考に、3つほどつくってみたサンプル1⁠。もちろん、HTMLとCSSの構成はわかりやすく改め、コードも絞り込んである。ただ、3つすべてを解説しようとすると長くなりそうだ。そこで、サンプル1の2つ目については次回に送り、今回はひとつ目と3つ目を説明しよう。

サンプル1 CSS3: Text styles and hover effects

2つの項目の静的なデザイン

<body>要素には、2つの項目をつぎのようなコードで構成した。項目ごとの<div>要素class属性"item")にリンクのための<a>要素class属性"link")を含め、テキストは<span>要素で加えている。アニメーションは、項目ごとの<a>要素にclass属性("animation-1"と"animation-3")を与え、後でCSSによって定める。なお、はじめの項目の<span>要素には、data-グローバル属性を加えた。これらの値は、アニメーションのCSSで用いることができる。さらに、すべての項目を<div>要素class属性"container")で包んだのは、まとめて扱えるようにするためだ。今回のお題では、とくにスタイルは定めない。

<div class="container">
    <div class="item">
        <a class="link animation-1" href="http://gihyo.jp/design/serial/01/createjs">
            <span data-letters-l="Crea" data-letters-r="teJS">CreateJS</span>
        </a>
    </div>
    <div class="item">
        <a class="link animation-3" href="http://gihyo.jp/design/serial/01/css-animation">
            <span>CSS</span>
            <span>3</span>
        </a>
    </div>
</div>

Google Fontsはつぎの3つを使った(第5回のGoogle Fontsと回り込みの解除参照⁠⁠。また、CSSにベンダープレフィックスを付けなくて済むように、<script>要素で-prefix-freeを読み込んである(第1回のベンダープレフィックスと-prefix-freeの項参照⁠⁠。

<link href="https://fonts.googleapis.com/css?family=Raleway:400,900" rel="stylesheet" type="text/css">
<link href="https://fonts.googleapis.com/css?family=Dosis:400,800" rel="stylesheet" type="text/css">
<link href="https://fonts.googleapis.com/css?family=Playfair+Display" rel="stylesheet" type="text/css">
<script src="lib/prefixfree.min.js"></script>

前掲<body>要素の記述に対しては、以下のコード1<style>要素を与える。まだアニメーションもマウスインタラクションもない。ただし、はじめの項目には、すでにCSSで飾りつけがなされている図1⁠。水平に少し位置のずれたテキストが重なり、上下には線が加わった。

図1 はじめの項目テキストはふたつ重なって上下に線が加わった
図1 はじめの項目テキストはふたつ重なって上下に線が加わった
コード1 はじめの項目のテキストはふたつ重ねて上下に線を加える
body {
    font-family: Arial, sans-serif;
    background-color: Skyblue;
}
.item {
    padding: 25px 0;
    z-index: 1;
    display: flex;
    align-items: center;
    justify-content: center;
}
.link {
    text-decoration: none;
    position: relative;
    font-size: 5em;
    line-height: 1;
}
.animation-1 {
    font-family: 'Playfair Display', serif;
    font-weight: 400;
    color: Steelblue;
    padding: 0 0 0.125em;
    margin-top: -0.05em;
}
.animation-1::before,
.animation-1::after {
    content: '';
    width: 100%;
    height: 3px;
    background: Darkblue;
    position: absolute;
}
.animation-1::before {
    right: 0;
    top: 0;
}
.animation-1::after {
    left: 0;
    bottom: -0.05em;
}
.animation-1 span::before,
.animation-1 span::after {
    position: absolute;
    color: white;
}
.animation-1 span::before {
    content: attr(data-letters-l);
    left: 0;
    transform: translateX(-5px);
}
.animation-1 span::after {
    content: attr(data-letters-r);
    right: 0;
    transform: translateX(5px);
}

.animation-3 {
    font-weight: 900;
    font-family: 'Raleway', Arial, sans-serif;
    line-height: 1em;
    margin-top: 0;
    color: Steelblue;
}
.animation-3 span {
    position: relative;
    display: inline-block;
}

はじめの項目を擬似要素で飾りつける

このお題は、擬似要素::beforeおよび::afterでテキストの飾りつけやアニメーションを加えることがひとつの鍵となる。前掲コード1では、すでにはじめの項目に上下の線と、少しずらして重ねたテキストが擬似要素で加えられた。擬似要素がなければ、つぎの図2のようなスタイルを定めたテキストが示されるだけだ。

図2 <span>要素に加えられたテキスト
図2

まず、はじめの項目の<a>要素にアニメーションのため定めたclass属性("animation-1")に、上下の線を擬似要素::before::afterで以下のように加えよう図3⁠。それぞれの位置決めが右上と左下で異なるのは、後で変形アニメーションの原点とするためだ。

<a class="link animation-1" href="http://gihyo.jp/design/serial/01/createjs">

</a>
.animation-1::before,
.animation-1::after {
    content: '';
    width: 100%;
    height: 3px;
    background: Darkblue;
    position: absolute;
}
.animation-1::before {
    right: 0;
    top: 0;
}
.animation-1::after {
    left: 0;
    bottom: -0.05em;
}
図3 擬似要素でテキストの上下に加えた線
図3 擬似要素でテキストの上下に加えた線

つぎに、もとのテキスト<span>要素)と少し左右外側にずらして重ねたのも擬似要素::before::afterだ。テキストを加えたいときは、contentプロパティに定める。その文字列の値は、前項で触れた、要素のdata-グローバル属性に与えた。値を取り出すには、以下のようにattr()を用いればよい。そして、2つの擬似要素の水平位置は、translateX()関数[1]で少し外側にずらした図4⁠。

<span data-letters-l="Crea" data-letters-r="teJS">CreateJS</span>
.animation-1 span::before,
.animation-1 span::after {
    position: absolute;
    color: white;
}
.animation-1 span::before {
    content: attr(data-letters-l);
    left: 0;
    transform: translateX(-5px);
}
.animation-1 span::after {
    content: attr(data-letters-r);
    right: 0;
    transform: translateX(5px);
}
図4 擬似要素で左右外側にずらして重ねたテキスト
図4 擬似要素で左右外側にずらして重ねたテキスト

擬似要素をアニメーションさせる

はじめの項目にマウスポインタを重ねたら、擬似要素をアニメーションさせよう。まず、擬似要素で重ねたテキストは、はじめopacityプロパティで透明にしておく。そして、マウスポインタを重ねたとき:hover擬似クラス⁠⁠、不透明に戻す。さらに、水平位置もtranslateX()関数でもとのテキストと合わせた。これで、transitionプロパティに時間を定めれば、擬似要素で重ねたテキストがフェードインしながらもとの位置に動く図5⁠。

.animation-1 span::before,
.animation-1 span::after {

    opacity: 0;
    transition: 0.5s;
}

.animation-1:hover span::before,
.animation-1:hover span::after {
    opacity: 1;
    transform: translateX(0);
}
図5 マウスポインタを重ねると左右のテキストがフェードインしながらもとの位置に戻る
図5 マウスポインタを重ねると左右のテキストがフェードインしながらもとの位置に戻る

つぎに、上下の線のアニメーションだ。つぎのように、はじめscaleX()関数で幅を0に縮めておく。そして、:hover擬似クラスでもとの幅に戻す。ただ、デフォルトでは、中央から伸び縮みすることになる。そこで、transform-originプロパティにより、変形の原点を上下の線でそれぞれ右と左に定めた。こうして、マウスポインタを重ねたとき、上の線は右から、下の線は左から伸びてゆく図6⁠。はじめの項目のアニメーションはこれでできあがった。

.animation-1::before,
.animation-1::after {

    transform: scaleX(0);
    transition: 0.5s;
}
.animation-1::before {

    transform-origin: right;
}
.animation-1::after {

    transform-origin: left;
}
.animation-1:hover::before,
.animation-1:hover::after {
    transform: scaleX(1);
}
図6 マウスポインタを重ねると上下の線がそれぞれ右と左から伸びる
図6 マウスポインタを重ねると上下の線がそれぞれ右と左から伸びる

終わりの項目をアニメーションさせる

終わりの項目のテキストは、つぎのようにふたつの<span>要素に分けておいた。それぞれに異なったアニメーションを加えるためだ。

<a class="link animation-3" href="http://gihyo.jp/design/serial/01/css-animation">
    <span>CSS</span>
    <span>3</span>
</a>

テキストは、はじめ親要素class属性"animation-3")から同じ色を与えてあった(前掲コード1⁠。それを:hover擬似クラスで違う色に変えよう。2つの<span>要素は、擬似クラス:first-of-type:last-of-typeで選び分けられる。transitionプロパティを定めれば、マウスポインタを重ねるとカラーがアニメーションする図7⁠。

.animation-3 span {

    transition: 0.5s;
}
.animation-3:hover span:first-of-type {
    color: white;
}
.animation-3:hover span:last-of-type {
    color: Midnightblue;
}
図7 マウスポインタを重ねるとテキストの色が変わる
図7 マウスポインタを重ねるとテキストの色が変わる

さらに、2つの<span>要素に、つぎのようにそれぞれ::before擬似要素で矩形を加える。領域は、テキストのアニメーションに定めたカラーで塗った。それぞれの位置は、translateY()関数でテキストの領域の上下外側に大きくずらしてある図8⁠。

.animation-3 span::before {
    content: '';
    position: absolute;
    width: 100%;
    height: 100%;
    background: white;
}
.animation-3 span:last-of-type::before {
    background: Midnightblue;
}
.animation-3 span:first-of-type::before {
    transform: translateY(-150%);
}
.animation-3 span:last-of-type::before {
    transform: translateY(150%);
}
図8 テキスト領域の上下外側に擬似要素の矩形が置かれた
図8 テキスト領域の上下外側に擬似要素の矩形が置かれた

2つの矩形は、つぎのように垂直方向の反対側に向けて、テキストの上をアニメーションで横切らせる。そして、overflowプロパティプロパティの値をhiddenに定めれば、テキスト領域の外側は隠されてしまう。こうして、マウスポインタを重ねたとき、上下に動く矩形がテキストに色を加えたような表現ができた。

.animation-3 {

    overflow: hidden;

}

.animation-3 span::before {

    transition: 0.5s;
}

.animation-3:hover span:last-of-type::before,
.animation-3 span:first-of-type::before {
    transform: translateY(-150%);
}
.animation-3:hover span:first-of-type::before,
.animation-3 span:last-of-type::before {
    transform: translateY(150%);
}

これで、マウスポインタを重ねたときのテキストのアニメーションが2つできあがった。擬似要素をうまく使うと、このように単純なテキストにも多彩な表現が加えられる。2つの項目のCSSの定めは、つぎのコード2にまとめたとおりだ。そして、以下にサンプル2として、2つ分のアニメーションをjsdo.itに掲げた。次回に、残る項目のアニメーションについて説明する。

コード2 マウスポインタを重ねたときのテキストのアニメーション
body {
    font-family: Arial, sans-serif;
    background-color: Skyblue;
}
.item {
    padding: 25px 0;
    z-index: 1;
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
}
.link {
    text-decoration: none;
    position: relative;
    font-size: 5em;
    line-height: 1;
}
.animation-1 {
    font-family: 'Playfair Display', serif;
    font-weight: 400;
    color: Steelblue;
    padding: 0 0 0.125em;
    margin-top: -0.05em;
}
.animation-1::before,
.animation-1::after {
    content: '';
    width: 100%;
    height: 3px;
    background: Darkblue;
    position: absolute;
    transform: scaleX(0);
    transition: 0.5s;
}
.animation-1::before {
    right: 0;
    top: 0;
    transform-origin: right;
}
.animation-1::after {
    left: 0;
    bottom: -0.05em;
    transform-origin: left;
}
.animation-1:hover::before,
.animation-1:hover::after {
    transform: scaleX(1);
}
.animation-1 span::before,
.animation-1 span::after {
    position: absolute;
    color: white;
    opacity: 0;
    transition: 0.5s;
}
.animation-1 span::before {
    content: attr(data-letters-l);
    left: 0;
    transform: translateX(-5px);
}
.animation-1 span::after {
    content: attr(data-letters-r);
    right: 0;
    transform: translateX(5px);
}
.animation-1:hover span::before,
.animation-1:hover span::after {
    opacity: 1;
    transform: translateX(0);
}

.animation-3 {
    font-weight: 900;
    font-family: 'Raleway', Arial, sans-serif;
    line-height: 1em;
    margin-top: 0;
    overflow: hidden;
    color: Steelblue;
}
.animation-3 span {
    position: relative;
    display: inline-block;
    transition: 0.5s;
}
.animation-3:hover span:first-of-type {
    color: white;
}
.animation-3:hover span:last-of-type {
    color: Midnightblue;
}
.animation-3 span::before {
    content: '';
    position: absolute;
    width: 100%;
    height: 100%;
    background: white;
    transition: 0.5s;
}
.animation-3 span:last-of-type::before {
    background: Midnightblue;
}
.animation-3:hover span:last-of-type::before,
.animation-3 span:first-of-type::before {
    transform: translateY(-150%);
}
.animation-3:hover span:first-of-type::before,
.animation-3 span:last-of-type::before {
    transform: translateY(150%);
}
サンプル2 CSS3: Text styles and hover effects (1)

おすすめ記事

記事・ニュース一覧