CSS
HTML5
React

CSSアニメーション、このくらいはわかった方がいいよ。

More than 1 year has passed since last update.

Reactのアニメーションを学ぶ前に背景知識としてCSSのアニメーションについて紹介する。

ReactではなくてもこのくらいのCSSアニメーションの扱い方は覚えた方がいいと思う。


CSS transition

transition効果(時間的変化)を与えるために使うプロパティ

百聞は一見にしかず、早速だがソースコードをみよう。

<!DOCTYPE html>

<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>Hover Transition</title>
<style media="screen">
a{
font-family: Helvetica, Arial, sans-serif;
text-decoration: none;
color: #ffffff;
}

.button{
padding: 0.74rem 1rem;
border-radius: 0.3rem;
box-shadow: 0;
background-color: #bbbbbb;
}

.button:hover{
background-color: #ee2222;
box-shadow: 0 4px #990000;
webkit-transition: 0.5s;
transition: 0.5s;
}
</style>
</head>
<body>
<a href="#" class="button">Hover Me!</div>
</body>
</html>

buttonについて2つのクラスが用意されている。

マウスのカーソルをbuttonの上に移動する(hover)とbuttonの色と影(shadow)が変化する。

変化を目で識別するために、transition(時間差)を0.5sで設定している。

transitionではアニメーションの開始と終了だけ制御ができる。

開始と終了の間のアニメーションはすべてブラウザーに依存する。

ani01.gif


Keyframe Animations

アニメーションをブラウザーがすべて処理するtransitionに対してkeyframeはアニメーション中に到達するべきポイント(キーフレーム)を明示することで、アニメーションの中間地点の制御ができる。

<!DOCTYPE html>

<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>Pulsing Heart</title>
<style media="screen">
body{
text-align: center;
}
@keyframes pulsing-heart {
0% { transform: none; }
50% { transform: scale(1.4); }
100% { transform: none; }
}
.heart {
font-size: 10rem;
color: #ff0000;
}
.heart:hover {
animation: pulsing-heart .5s infinite;
transform-origin: center;
}
</style>
</head>
<body>
<div>
<div class="heart">&hearts; </div>
</div>
</body>
</html>

@keyframesとtransformプロパティに値を設定することで、アニメーションが作られる。

上記のpulsing-heartはキーフレームの集合で、0%、50%、100%に該当する3つのキーフレームで構成されている。

transformプロパティで使えるメソッドには次の4つがある。

メソッド
説明

scale
対象のサイズ

translate
対象の移動

skew
対象の傾斜

rotate
対象の回転

ブラウザーで確認してみよう。

赤いハートが表示されて、ハートの上にマウスのカーソルを移動すると心臓が鼓動するようにハートが変化する。

ani02.gif


  • 参考

@keyframesのtransform

cssのanimation


class swappingとjavascript

異なるcssのclassを定義してあるイベントが発火した場合、javascriptでclassを変更することでアニメーションの効果が作られる。

<!DOCTYPE html>

<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>Hacked together sidebar Transition</title>
<style media="screen">
ul {
list-style-type: none;
padding: 0;
}
li {
padding: 15px;
border-bottom: solid 1px #eee;
background-color: #ddd;
}
.sidebar {
background-color: #eee;
box-shadow: 1px 0 3px #888888;
position: absolute;
width: 15rem;
height: 100%;
}
.sidebar-transition {
opacity: 0;
left: -15rem;
}
.sidebar-transition-active {
opacity: 1;
left: 0;
transition: 0.5s;
}
</style>
</head>
<body>
<header>
<button onclick="document.querySelector('.sidebar').classList.add('sidebar-transition-active');">&#9776;</button>
</header>
<div class='sidebar sidebar-transition'>
<ul>
<li>Some content</li>
<li>Content B</li>
<li>Content C</li>
<li>Content X</li>
</ul>
</div>
</body>
</html>

sidebarは幅が15rem、sidebar-transitionで透明にしてleftから-15remすることでsidebarを隠す。

sidebar-transition-activeでは不透明にしてleftを0に変えることでsidebarを表示する。

buttonをクリックするとsidebar-transitionでsidebar-transition-activeを追加することで隠されたsidebarが現れる。

ani03.gif


emとrem

「エム」と呼ぶ。

1emは1文字分の大きさで、font-sizeが100%(デフォルト)であれば「1em = 16px」になる。

emとremの違いは親要素のサイズを継承するかしないかである。

body{

font-size: 1.5em;
}
p{
font-size: 1.5em;
}

この場合、pタグのフォントサイズは16px * 1.5em * 1.5em = 36px

emではないremで設定された場合は親要素のサイズを継承しないので、16px * 1.5rem = 24px