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

第5回画像にポインタを重ねるとキャプションが現れる

今回のお題は、画像にキャプションを示すアニメーションだ。マウスポインタを画像に重ねると説明書きが現れるサンプル1⁠。画像にもちょっとしたアニメーションが加えてある。用いる設定は、さほど目新しいものではない。組み合わせや細かな調整を加えてつくり上げた表現だ。

サンプル1 CSS3: Hover effect of an image and a caption

キャプションを加えた画像の静的スタイル

<body>要素に書くコードはつぎのように構成した。画像の<img>要素に続けて<div>要素class属性"mask")を置き、<div>要素の中に、タイトルの<h3>要素class属性"figure-title")と説明書きの<div>要素class属性"figure-caption")を加えた。それらを<div>要素class属性"figure")でひとつにまとめ、さらに<div>要素class属性"container")で包んでいる。

<div class="container">
    <div class="figure">
        <img src="images/photo_001.png" alt="pen" width="300" height="200">
        <div class="mask">
            <h3 class="figure-title">Figure Title</h3>
            <p class="figure-caption"><!-- テキスト省略 --></p>
        </div>
    </div>
</div>

この<body>要素の記述に対して、つぎのような<style>要素を与える。画像にキャプションを重ねただけで、まだアニメーションもマウスインタラクションもない図1⁠。なお、CSSにベンダープレフィックスを付けなくて済むように、<script>要素で-prefix-freeを読み込んでいる(第1回のベンダープレフィックスと-prefix-freeの項参照⁠⁠。

<script src="lib/prefixfree.min.js"></script>
<link href="https://fonts.googleapis.com/css?family=Open+Sans:400,600" rel="stylesheet" type="text/css">
<style>
img {
    vertical-align: bottom;
}
.container {
    width: 340px;
    margin: 20px auto;
    cursor: default;
}
.container::after {
    content: "";
    clear: both;
    display: block;
}
.figure {
    position: relative;
    color: white;
    overflow: hidden;
    float: left;
    margin-left: 20px;
    font-family: "Open Sans", sans-serif;
}
.figure-title,
.figure-caption {
    position: absolute;
    left: 20px;
    width: 260px;
    text-align: center;
}
.figure-title {
    top: 10px;
    font-size: 24px;
    font-weight: 600;
}
.figure-caption {
    top: 60px;
    font-size: 12px;
    font-weight: 400;
}
</style>
図1 画像に重ねられたキャプション
図1 画像に重ねられたキャプション

Google Fontsと回り込みの解除

アニメーションに取りかかる前に、2つほど補っておく。ひとつは、Google Fontsのフォントを使ったことだ。サイトのページ左側にある検索のフールドやフィルタで好みのフォントが絞り込める。今回はOpen Sansを用いた図2⁠。[Quick-use]のボタンから開くページで、選べるオプションや<link>要素の書き方などが示される。

図2 Google FontsのフォントOpen Sans
図2 Google FontsのフォントOpen Sans

もうひとつは、つぎのような::after擬似要素clearプロパティの定めにより、画像への回り込みを解除していることである(⁠CSS の after 擬似要素で回り込みを解除する参照⁠⁠。サンプル1は回り込むものがないので、このCSSの記述はなくても問題ない。だが、以下のコードのように<div>要素class属性"container")の後に<p>要素でテキストを加えると、画像に回りこんでしまう図3上⁠⁠。::after擬似要素の記述を加えることで、これが防げる図3下⁠⁠。

.container::after {
    content: "";
    clear: both;
    display: block;
}
<div class="container">

</div>
<p><!-- テキスト省略 --></p>
図3 ::after擬似要素で回り込みが解除される
図3 ::after擬似要素で回り込みが解除される 図3 ::after擬似要素で回り込みが解除される

画像にポインタが重なったらキャプションを示す

それでは、画像にポインタが重なったら、キャプションをアニメーションで示すようにしよう。キャプションの表示・非表示は、opacityプロパティで滑らかに変える。また、transformプロパティにscale()関数を与えて、伸縮のアニメーションも加える。タイトルclass属性"figure-title")と説明書きclass属性"figure-caption")に定めたCSSはつぎのとおりだ。

.figure-title,
.figure-caption {

    opacity: 0;
    transform: scale(10);
    transition: 0.3s ease-in-out;
}

.figure:hover .figure-title,
.figure:hover .figure-caption {
    opacity: 1;
    transform: scale(1);
}
.figure:hover .figure-title {
    transition-delay: 0.1s;
}
.figure:hover .figure-caption {
    transition-delay: 0.2s;
}

コードの中に用いたtransition-delayプロパティは、アニメーションが始まるのを与えた秒数分遅らせる(デフォルト値0s⁠⁠。この値はtransitionプロパティで定めることもできる。今回は要素によって遅らせる時間を変えるため、transition-delayプロパティを使うことにした。これで、画像にマウスポインタを重ねると、キャプションがタイトルと説明書きで少し時間がずれて現れる図4⁠。ここまでのCSSの定めを、以下のコード1にまとめた。

図4 画像にポインタを重ねるとキャプションが時間差で現れる
図4 画像にポインタを重ねるとキャプションが時間差で現れる
コード1 画像にポインタを重ねたときキャプションがアニメーションで現れる
img {
    vertical-align: bottom;
}
.container {
    width: 340px;
    margin: 20px auto;
    cursor: default;
}
.container::after {
    content: "";
    clear: both;
    display: block;
}
.figure {
    position: relative;
    color: white;
    overflow: hidden;
    float: left;
    margin-left: 20px;
    font-family: "Open Sans", sans-serif;
}
.figure-title,
.figure-caption {
    position: absolute;
    left: 20px;
    width: 260px;
    text-align: center;
    opacity: 0;
    transform: scale(10);
    transition: 0.3s ease-in-out;
}
.figure-title {
    top: 10px;
    font-size: 24px;
    font-weight: 600;
}
.figure-caption {
    top: 60px;
    font-size: 12px;
    font-weight: 400;
}
.figure:hover .figure-title,
.figure:hover .figure-caption {
    opacity: 1;
    transform: scale(1);
}
.figure:hover .figure-title {
    transition-delay: 0.1s;
}
.figure:hover .figure-caption {
    transition-delay: 0.2s;
}

画像に色をかぶせる

マウスポインタを重ねたときキャプションを出すのに加え、画像に半透明のカラーをかぶせよう。キャプションが入った<div>要素class属性"mask")につぎのようなCSSを定める。backgroundに半透明のカラーを与え、表示・非表示はやはりopacityプロパティで変えた。transition-durationプロパティは、アニメーションの時間を決める。あらかじめtransitionプロパティで設定された時間だけを変えたい場合に使うとよい。このコードでは、マウスポインタを重ねたときと外したときとでアニメーションの時間が変わる。

.mask {
    position: absolute;
    top: 0;
    width: 100%;
    height: 100%;
    background: rgba(0, 0, 0, 0.4);
    opacity: 0;
    transition: 0.5s;
}

.figure:hover .mask {
    opacity: 1;
    transition-duration: 0.3s;
}

これで、マウスポインタを画像に重ねたとき、キャプションが現れるとともに半透明のカラーがかぶさる図5⁠。背景色により、テキストがより際立つようになった。ここまでのCSSの定めは、以下のコード2にまとめたとおりだ。

図5 ポインタを重ねるとキャプションに加えて画像にカラーがかぶさる
図5 ポインタを重ねるとキャプションに加えて画像にカラーがかぶさる
コード2 ポインタを重ねるとキャプションと半透明のカラーが画像にかぶさる
img {
    vertical-align: bottom;
}
.container {
    width: 340px;
    margin: 20px auto;
    cursor: default;
}
.container::after {
    content: "";
    clear: both;
    display: block;
}
.figure {
    position: relative;
    color: white;
    overflow: hidden;
    float: left;
    margin-left: 20px;
    font-family: "Open Sans", sans-serif;
}
.mask {
    position: absolute;
    top: 0;
    width: 100%;
    height: 100%;
    background: rgba(0, 0, 0, 0.4);
    opacity: 0;
    transition: 0.5s;
}
.figure-title,
.figure-caption {
    position: absolute;
    left: 20px;
    width: 260px;
    text-align: center;
    opacity: 0;
    transform: scale(10);
    transition: 0.3s ease-in-out;
}
.figure-title {
    top: 10px;
    font-size: 24px;
    font-weight: 600;
}
.figure-caption {
    top: 60px;
    font-size: 12px;
    font-weight: 400;
}
.figure:hover .mask {
    opacity: 1;
    transition-duration: 0.3s;
}
.figure:hover .figure-title,
.figure:hover .figure-caption {
    opacity: 1;
    transform: scale(1);
}
.figure:hover .figure-title {
    transition-delay: 0.1s;
}
.figure:hover .figure-caption {
    transition-delay: 0.2s;
}

画像に変形のアニメーションを加える

画像にも軽くアニメーションを加えよう。マウスポインタを重ねたら、少し大きくして傾けることにする図6⁠。<img>要素には、つぎのようにclass属性"transform"を与えた。そして、以下のCSSのとおり、transformプロパティに関数rotate()scale()で、回転と拡大の変形を加えている。

<div class="container">
    <div class="figure">
        <img src="images/photo_001.png" alt="pen" width="300" height="200" class="transform">

    </div>
</div>
.transform {
    transition: 0.3s ease-in-out;
}
.figure:hover .transform {
    transform: rotate(-15deg) scale(1.4);
}
図6 ポインタを重ねると画像は大きくなって傾く
図6 ポインタを重ねると画像は大きくなって傾く

リンクボタンをアニメーションで加える

仕上げとして、リンクのボタンをアニメーションで加えよう。<div>要素class属性"container")に、つぎのように<a>要素class属性"info-link")を含める。CSSは以下のとおり、ボタンとしての見た目を整え、画像の下端から上ってくる動きにした図7⁠。アニメーションの始まりはもっとも遅い。書き上がった<body>要素へのタグの記述とCSSの定めは、以下のコード3にまとめたとおりだ。

<div class="container">
    <div class="figure">

    <a href="#" class="info-link">More info</a>
    </div>
</div>
.transform,
.info-link {
    transition: 0.3s ease-in-out;
}

.info-link {
    position: absolute;
    top: 200px;
    left: 100px;
    width: 80px;
    padding: 5px 10px;
    background: navy;
    color: white;
    text-decoration: none;
}
.figure:hover .info-link {
    top: 150px;
    transition-delay: 0.4s;
}
図7 ポインタを重ねたとき最後に画像下端からリンクボタンが上ってくる
図7 ポインタを重ねたとき最後に画像下端からリンクボタンが上ってくる
コード3 画像にポインタを重ねるとキャプションなどがアニメーションで現れる
<div class="container">
    <div class="figure">
        <img src="images/photo_001.png" alt="Cactus" width="300" height="200" class="transform">
        <div class="mask">
            <h3 class="figure-title">Figure Title</h3>
            <p class="figure-caption"><!-- テキスト省略 --></p>
        </div>
        <a href="#" class="info-link">More info</a>
    </div>
</div>
img {
    vertical-align: bottom;
}
.container {
    width: 340px;
    margin: 20px auto;
    cursor: default;
}
.container::after {
    content: "";
    clear: both;
    display: block;
}
.figure {
    position: relative;
    color: white;
    overflow: hidden;
    float: left;
    margin-left: 20px;
    font-family: "Open Sans", sans-serif;
}
.mask {
    position: absolute;
    top: 0;
    width: 100%;
    height: 100%;
    background: rgba(0, 0, 0, 0.4);
    opacity: 0;
    transition: 0.5s;
}
.figure-title,
.figure-caption {
    position: absolute;
    left: 20px;
    width: 260px;
    text-align: center;
    opacity: 0;
    transform: scale(10);
    transition: 0.3s ease-in-out;
}
.figure-title {
    top: 10px;
    font-size: 24px;
    font-weight: 600;
}
.figure-caption {
    top: 60px;
    font-size: 12px;
    font-weight: 400;
}
.figure:hover .mask {
    opacity: 1;
    transition-duration: 0.3s;
}
.figure:hover .figure-title,
.figure:hover .figure-caption {
    opacity: 1;
    transform: scale(1);
}
.figure:hover .figure-title {
    transition-delay: 0.1s;
}
.figure:hover .figure-caption {
    transition-delay: 0.2s;
}
.transform,
.info-link {
    transition: 0.3s ease-in-out;
}
.figure:hover .transform {
    transform: rotate(-15deg) scale(1.4);
}
.info-link {
    position: absolute;
    top: 200px;
    left: 100px;
    width: 80px;
    padding: 5px 10px;
    background: navy;
    color: white;
    text-decoration: none;
}
.figure:hover .info-link {
    top: 150px;
    transition-delay: 0.4s;
}

おすすめ記事

記事・ニュース一覧