動くCSSのためのメモ。
マウスオーバーエフェクト

ボタンや画像にカーソルを乗せた時の反応って大事ですよね。
リンクするエリアにカーソルを合わせた時に、カーソルが指のアイコンに変わったり、テキストの色が変わったりすれば、カーソルが乗ったという事が認識しやすくなります:)。それに加えて、ちょっとしたエフェクトがあれば、温度や感触や、世界観まで伝えられるかも。

ふわっとする

下のサンプルみたく、:hoverを使ってスタイルを指定しておけば、カーソルが乗った時に、そのスタイルが適用されます。
けどそれだけだと、カチッと切り替わるだけ。

a:hover {
	color: indianRed;
	text-decoration: inherit;
}

サイトの雰囲気にもよるけれど、もちょっとだけ柔らかい印象にしたいなって時には、ふわっとするとよいかもです。文字の色が切り替わるスピードと、下線が消えてゆくスピードを調整することで、ふわっとした感じになります:)
切り替わるスピードを調整するにはtransitionプロパティを使います!
下記のように書くと、a要素でのcolorプロパティの値の変化の仕方を指定することができます。下記は「0.3秒かけていい感じで切り替わる」という指定。

a {
	transition: color 0.3s ease 0s;
}

transitionの値は左から順に、property(プロパティ)duration(速度)timing-function(緩急具合)delay(遅延時間)を表してて、上の例を個別に指定するなら、下記のようにも書けます。

a {
	transition-property: color;
	transition-duration: 0.3s;
	transition-timing-function: ease;
	transition-delay: 0s;
}

初期値を省略して、下記だけでもよいです:)

a {
	transition: color 0.3s;
}

それから、値が1未満の小数なら、最初の0端折ハショることができるので、下記のようにも書けます。

a {
	transition: color .3s;
}

これでテキストの色だけ、ふわっと変化するようになりました。;D

さらに下線もゆっくり消えてゆくようにするには、transitionプロパティのcolorについての指定の後に、下記のようにカンマ区切りで、text-decorationについての指定を追記します。

a {
	transition: color .3s, text-decoration .3s;
}

ただし、これだけじゃ下のサンプルのようにまだカチッとしたまま。

というのも、カーソルを乗せた時に下線を消す方法を、text-decoration: inheritとしちゃっているからなんです。inheritインハーリット継承するという意味。a要素の親要素(つまりp要素)のtext-decorationプロパティの値を継承するということで、それだと、text-decoration: none solid currentcolorということになっちゃうんです。
transitionは、値の変化をスムーズにすることができるプロパティ、なので、その効果を発揮できるのは、プロパティの値が数値の時(数値で表せる時)なのですね。
カーソルを乗せた時、下線の表示をnoneにするのではなくて、下線の色を透明にするようにすれば、transitrionの効果を発揮できるはずです。
下線の色を透明するにはtext-decorationの値に、透明色を表す値transparentを指定してやります。

a:hover {
	text-decoration: transparent;
}

まだカチッですね…。
text-decorationの値にはline(表示位置)style(種類)color(色)の3つの値を指定しているんですけれど、線をどこに表示するかを表すtext-decoration-lineの初期値がnoneなので、text-decoration: transparentと書くと、text-decoration: none solid transparentと指定されちゃうことになります。(※ハショった値は初期値になっちゃうということ。)

なのでここでは、text-decoration-colorプロパティを使って、線の色だけ変更するようにします。

a:hover {
	text-decoration-color: transparent;
}

ページトップへ戻る

transition-delayについて

transition-delayの値を.3sとした場合、0.3秒待ってから変化を開始、-.3sとした場合には、0.3秒進んだ時点から変化を開始します。

transition-delay、プラスの値とマイナスの値の違い

下のサンプルでは、それぞれtransition-delayを変えてます。

カーソルを乗せると3つ同時に変化を開始しますが、待ち時間によって、変化が完了するタイミングがズレてますね。
一番上のサンプルでは、カーソルを乗せてから1秒で変化を完了しますが、真ん中のサンプルの場合は1.3秒、一番下のサンプルは0.7秒かかる事になります。

画像ボタンもふわっする

画像ボタンやバナーの場合は、img要素を包むa要素の背景画像に、マウスオーバー時の画像を指定して、img要素のopacityを徐々に変化させれば、ふわっと切り替わったように見えます:)

画像ボタンの構造

ふわっとカチッする

CSSで作ったボタンなら、backgroundbox-shadowなど、いじれるプロパティがいっぱいあるので、ふわっとさせ甲斐がありますねー!まとめてtransitionを指定すれば、より魅力的な変化を表現できます。

上の例では、ボタンの地色background、文字色color、影の色と位置box-shadow、ボタンの位置transformを、徐々に変化させてます。

ボタンの仕組み

また、カーソルを乗せた時にはゆったり動いてますが、マウスを押下した時にはちょっと早めに動くようにしてます。ここでは、durationの値を、下記のように変えています。

.btn a {
	/* 略 */
	transition: color .3s, background.3s, box-shadow .3s, transform .3s;
}
.btn a:active {
	transition-duration: .1s;
}

a要素に指定したtransitionの値を、active時にtransition-durationの値のみ上書きしてるんですねー。これで、マウスを押下した時だけは0.1秒で変化して、それ以外の時には0.3秒で変化するようになります。

ページトップへ戻る

ピカッとする

カーソルを乗せた時に一瞬ピカッとか、キラッとか、発光するボタンが作りたいという時、transitionだと「ピカッとする」まではできますが、そこからもとの明るさに戻るっていうのができません…。

ピカッとしっぱなし

こんな時にはanimationというプロパティを使うのが良いです。下記のように指定します。

.btn a:active {
	animation: flash 1s;
}

ただし、この指定だけではアニメーションは機能しません。ちゃんとアニメーションさせるには、別途@keyframesルールという、キーフレームを定義するための特別な構文を使って、アニメーションを用意する必要があるんです。用意して初めて、animationプロパティで使えるようになるんですねー。
ここでは、以下のように定義してみました。

@keyframes flash {
	0% { background: #20b2aa; }
	10% { background: #96e9e6; }
	100% { background: #20b2aa; }
}

ピカッと感が出ましたね!

animationにはname(アニメーション名)duration(速度)timing-function(緩急具合)delay(遅延時間)iteration-count(反復回数)direction(方向)play-state(再生状態)fill-mode(充填モード)という8つの値が指定できます。durationtiming-functiondelayは、transitionにもありましたね。

animationプロパティにまとめて指定する場合は、半角スペースを空けて、下記みたく連ねて書くこともできます:)

p {
	animation: name ease-in-out 2s 1s 5 alternate running forwards;
}

順番は自由だけれど、ひとつだけ、durationdelayの順番だけは「durationが先」と決まってるので注意です。※上記の場合なら、1秒待ってから2秒かけて5回アニメーション(ただし偶数回めは逆再生)するという指定になります。

アニメーションのイージングanimation-timing-functionについて

animation-timing-functionで指定したアニメーションの仕方は、アニメーション全体を通してではなく、@keyframesで定義したフレームごとに適用されます(下のサンプル参照)
「ろ」は0%と100%のみ、「ぱ」は0%、50%、100%時点を、「ん」は0%、10%、30%、60%、100%時点を、それぞれ定義し、イージングは「cubic-bezier(0.19, 1, 0.22, 1)easeOutExpo」を指定してます。
「最初は速くてだんだん遅くなる」というイージングが、フレームごとに適用されてますね。

パーセント指定した時点がフレームの節目になる

アニメーションの逆再生animation-directionについて

上のサンプルは「左から右へ移動する」というアニメーションしか定義してないのに、右から左へもアニメーションして戻ってます。これは、animation-directionに「alternate」を指定してるため、偶数回めのアニメーションが逆再生されてるからなんです。
左から右へ移動する時は「最初は速くてだんだん遅くなる」という風にアニメーションしてますが、戻る時(右から左へ移動する時)は「最初が遅くてだんだん速くなる」という風に、イージングの仕方も逆になってるのがわかります。

戻る時はイージングも逆方向になる

animation-directionの値を「normal」にしてみました。偶数回めも左から右へ移動するアニメーションが再生されるので、繋がりがなくて不自然ですね。。

下のサンプルならnormalで繰り返しても割と不自然じゃないです:)

normalでやる時は、開始と完了地点が見えないようにするか、ボタンの時みたくちゃんともとの状態に戻るようにした方がよさげです。
使う場面によって使い分けが必要ということですね;)

アニメーションの前後に適用されるスタイルanimation-fill-modeについて

下のサンプルでは、背景色がグレーのp要素に、カーソルを乗せると1秒かけて青緑色から赤色にグラデーションするgradationというアニメーションを適用しています。

p {
	background: #eee;
}
p:hover {
	animation: gradation 1s;
}
@keyframes gradation {
	0% { background: lightSeaGreen; }
	100% { background: indianRed; }
}

上の青緑色のボタンをクリックすると、animation-fill-modeプロパティの値をそれぞれ、noneforwardsbackwardsbothに切り替えることができるので、それぞれの挙動を確認してみてください:)

下の「1秒後にグラデーションする要素」の方が、それぞれの値の特徴が顕著に現れてますね。
noneでは、カーソルを乗せても何も変化せず、1秒後にようやく青緑色から赤色へ変化し、アニメーション後はまたすぐグレーに戻ってしまいます。
forwardsも、1秒間は何も変化せず、1秒後にようやく青緑色から赤色へ変化しますが、そのあとはカーソルを外すまで赤色のままです。
backwardsでは、カーソルを乗せた後すぐに青緑色に変わり、1秒後にグラデーションを開始し、アニメーション後はまたすぐグレーに戻ります。
そしてbothでは、すぐに青緑色に変わり、1秒後にグラデーションを開始し、カーソルを外すまで赤色のままです。

animation-fill-modeの値の役割をまとめてみると下図のようになります!
使いどころに合わせて、効率的に使いたいですねー;D

animation-fill-modeのまとめ

ページトップへ戻る

詳細はあとから表示する

最初は表示されてないんだけど、サムネイル画像の上にカーソルを乗せると、その画像に関する情報が表示されるような、そんなUIよくありますね。
ごちゃごちゃした情報は見たい時だけ、最初の見た目が煩雑にならずにシンプルなデザインにできるので、フラットなデザインとも相性がいいんですよね:)
下のサンプルみたいなの、よく見る気がします:D

そんなわけで、上のサンプルの左のやつから順に仕組みメモです。それぞれHTMLの構造は下記のようになってます。
li要素の中に、img要素(サムネイル画像)と、dl要素(詳細情報)が並んでる状態ですね。

<ul class="details">
	<li>
		<img src="https://placeholdit.imgix.net/~text?bg=20b2aa&txtcolor=fff&txtsize=39&txt=image&w=200&h=180">
		<dl>
			<dt>Placehold.it</dt>
			<dd>この画像は「Placehold.it」で生成されるダミー画像を使用しています。</dd>
			<dd><a href="http://www.placehold.it/" target="_blank">Placehold.it</a></dd>
		</dl>
	</li>
	<!-- 略 -->
</ul>

上記のHTMLを元に、詳細は後から表示するためのCSSの指定方法を紹介してゆきます!

下からニュッと出る

詳しい情報は画像の下に隠しておいて、カーソルが乗ったら下からスッとスライドする仕組み。

普段は画像の下に隠れてる

まずはli要素にposition: relativeを指定。これで、li要素が、その子要素を絶対配置するときの基準になります。dl要素にposition: absoluteを指定しtop: 0とすれば、img要素の上に重なった状態で配置されます。

li {
	position: relative;
}
dl {
	position: absolute;
	top: 0;
	margin: 0;
	padding: 16px 24px;
	box-sizing: border-box;
	color: #fff;
	background: rgba(205,92,92,.9);
}

dl要素の上下のスライドはtransformプロパティtranslateで移動させてます。
最初の状態では、dl要素にtranslateY(100%)と指定。これで、その要素の高さ分、下方向に移動します。カーソルが乗ったときはnoneとして、元の位置に戻します。

.type1 {
	overflow: hidden;
}
.type1 dl {
	opacity: 0;
	transform: translateY(100%);
	transition: opacity .6s, transform .6s cubic-bezier(0.215, 0.61, 0.355, 1);
}
.type1:hover dl {
	opacity: 1;
	transform: none;
}

けど、カーソルに乗った時の指定って、opacityプロパティもtransformプロパティも初期値に戻すだけなので、なんだか冗長です…。こんな時は、:not()(否定擬似クラス)を使うとよいです。通常状態とカーソルが乗った時の両方を指定するのでなくて、カーソルが乗っていない時だけ指定するってわけですね;)

.type1 {
	overflow: hidden;
}
.type1 dl {
	transition: opacity .6s, transform .6s cubic-bezier(0.215, 0.61, 0.355, 1);
}
.type1:not(:hover) dl {
	opacity: 0;
	transform: translateY(100%);
}

ページトップへ戻る

くるんと裏返る

まるで一枚のカードみたく、写真の裏面に詳細情報が載ってるような表現です。

上述と同じように、position: absoluteでimg要素とdl要素を重ねて配置。
最初の状態では、dl要素は裏返ってる状態なので、rotateX()を使ってX軸を中心に上下に回転させておき、カーソルが乗った時に、img要素とdl要素を同時に+180°回転させてます。

.type2 dl {
	background: #cd5c5c;
	transform: rotateX(-180deg);
}
.type2:hover img {
	transform: rotateX(180deg);
}
.type2:hover dl {
	transform: none;
}

カーソルが乗った時に<img><dl>を、同じタイミングで回転させる事で、一枚のカードのように見せてるんですねー。

普段は画像の裏側に隠れてる

裏返る演出で大事なのがbackface-visibilityというプロパティ。このプロパティにhiddenと指定した要素は、裏返った時に不可視状態になります。

backface-visibilityで裏側だと判断されるのは、transformプロパティのrotateX()rotateY()で、90°以上回転した時。下のサンプルは、左が「表面の要素のみ」真ん中が「裏面の要素のみ」になってます。表面が裏返ると不可視状態になり、その瞬間に裏面が可視状態になってるのがよくわかりますねー。

この指定がないと下のサンプルのように、裏側も丸見え、というか、裏面が表面の上に乗っちゃってます。

backface-visibilityについて詳しくは下記サイトを参照のこと。
backface-visibility - CSS: カスケーディングスタイルシート | MDN

あと、回転する要素の親要素には、perspectiveプロパティを指定してます。

.type2 {
	perspective: 1000px;
}

perspectiveは、遠近感を指定することができるプロパティ。指定する値は、その要素を見ている視点の位置を表してて、ここでは、1000px離れた所で見てる感じになります。

100px離れたとこからみてる人と、1000px離れたとこからみてる人

つまり、この値が小さい(近い)ほど遠近感が強く、大きい(遠い)ほど遠近感が緩くなるってことですね:)
この指定がないと、下のサンプルみたく、立体感がなくなって、裏返ったのか縦に縮んだのかわからなくなっちゃいます…。

perspectiveについては下記記事が詳しいです。
HTML5 × CSS3 × jQueryを真面目に勉強 – #10.1 CSS3 Transforms(3D) | Developers.IO(2012.12.27)

ページトップへ戻る

左右から背景が出てくる

パネル状の背景が左右から入ってきて、カーテンを閉めるように中央でピッタリ閉じられると、詳細情報がフェードインしてきます。

左右から出てくる背景は::before疑似要素::after疑似要素で表示させてます。
疑似要素を使うと、指定した要素の中に、新たに要素を追加できちゃいます。
ただし、要素を追加するにはもうひとつ、contentプロパティというのも使わなきゃいけません。下記みたく書きます。

HTMLには「 / 」と出力するだけのp要素がひとつ、なのにPREVIEWを見るとテキストが表示されてますね!
こんな感じで、疑似要素とcontentプロパティを使えば、HTMLで書かれた要素とは別に、CSSで新たに要素を作れちゃうんです(擬似的に!):D
::beforeは、指定した要素の開始タグの直後に、::afterは、指定した要素の閉じタグの直前に、要素を追加します。※Chromeで「検証」をしてみても存在を確認できますよ;)

Chromeのデベロッパーツールで存在が確認できる

左右から出てくる背景は、dl要素内に、::before::afterで2つの要素を追加してたわけです(擬似的に!:D

疑似要素で作る疑似背景

他にもいろんなプロパティと組み合わせればもっと面白な演出だってできちゃいます。トリッキー。

下記サイトでいろんなエフェクトが紹介されてます。どれも素敵ですねーXD
Circle Hover Effects with CSS Transitions(2012.8.8)

Comment & Pingback

コメントを残す

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください