CSSのtransitionプロパティは、マウスオーバー時のアニメーションを指定できるプロパティです。
WEBデザインにちょっとしたアクセントを加えたい時に便利なCSSですが、何らかの原因で上手く機能しないことがあります。
しかし、その原因のほとんどは、コーディング上のほんの小さなミスだったりします。
今回は、transitionが効かない時の原因とその対処法についてまとめてみました。
もくじ
transitionの基本的な使い方
まずtransitonの基本的な使い方を簡単におさらいしておきましょう。
transitionはマウスオーバー時の色や大きさ、位置などの変化に「時間」を設けるためのプロパティです。
マウスオーバー時の変化にはCSS疑似クラス:hoverを使いますが、transitionが指定されていない場合、変化前後の切り替わりが一瞬です。

transitionを追加することによって「じわじわ色が移り変わる」「最初は早く、最後は緩やかに」等のアニメーション的な動作が加えることができます。
CSSでは、以下のように記述します。
transition: 1s background linear 2s;
値は左から順番に「開始から終了までの時間」「適用するプロパティ」「変化の仕方」「開始するまでの時間」が指定されています。
つまり上記のコードは「1秒(1s)かけて背景(background)が一定に変化(linear)するアニメーションを2秒後(2s)に開始する」という意味です。
ちなみに「適用するプロパティ」には、個別指名しても良いですが「all」を指定することで一括できます。
例えば、以下のように:hoverに複数プロパティが存在し、全て同じ時間をかけて変化を実行したい場合には「all」で一括してしまったほうが楽です。
|
1 2 3 4 5 6 7 8 9 10 11 |
div.box { width: 200px; height: 200px; border: 1px solid #333; transition: 1s all linear; /* background・colorともに適用 */ } div.box:hover { background: #db7093; color: #fff; } |
また、transitionの値として不要なものがあれば省略可能です。
上記のコードでは、最後の値(開始するまでの時間)を省略していますが、アニメーションは機能します。
transitionが効かない時の原因&対処法
では、transitionの基本的な使い方を踏まえたうえで「効かない」原因を探っていきましょう。
今回はtransitionや:hover周辺のコーデイングで「ありがち」なミスを考えてみました。
基本的な項目もありますが、一つ一つチェックしていってみてください。
1.:hoverにtransitionを指定している
最も多いミスの一つがtransitionプロパティを疑似クラス内に指定してしまっていることです。
例えば、以下のような感じにです。
|
1 2 3 4 5 6 7 8 9 10 11 |
div.box { width: 200px; height: 200px; border: 1px solid #333; } div.box:hover { background: #db7093; color: #fff; transition: 1s all linear; } |
カーソルを離した時に元のスタイルに戻るアニメーションが発動しない場合など、このようなミスをしている可能性が高いです。

transitionの正しい指定位置は:hover内ではなく、本要素に直接です。
|
1 2 3 4 5 6 7 8 9 10 11 |
div.box { width: 200px; height: 200px; border: 1px solid #333; transition: 1s all linear; } div.box:hover { background: #db7093; color: #fff; } |
これで往路・復路ともにtransitionが効くようになります。
2.インライン要素にtransformを指定している
マウスオーバー時の変化させる時に、よく使われるスタイルがtransformプロパティです。
位置の移動や回転など、バラエティに富んだ変化を加えることができます。
しかし、transformは一部のインライン要素(aやspanなど)には効きません。
そのため、以下のように:hover内でtransformを指定しても、transitionどころかマウスオーバーイベント自体が発生しないのです。
|
1 |
<p><a href="#">インライン要素</a>にtransformは適用できる?</p> |
|
1 2 3 4 5 6 7 8 |
a { text-decoration: none; transition: 1s all; } a:hover { transform: translateY(3px); /* <a>はインライン要素なのでtransformは機能しない */ } |
とは言え、インライン要素が効かないだけなので、他の表示形式に変えてしまえば問題は解決します。
|
1 2 3 4 5 6 7 8 9 |
a { display: inline-block; text-decoration: none; transition: 1s all; } a:hover { transform: translateY(3px); } |
上記のように、インライン要素のスタイルにdisplay:inline-blockの一文を加えてください。

3.positionが正しく設定されていない
transitionで要素の位置を移動させたい時、positionプロパティを使うことがあります。
とても使い勝手の良いCSSですが、設定項目が多くケアレスミスしやすいです。
positionの基本的な使い方については詳しい説明を省きますが、「transitionとの組み合わせ」の中で見落としがちなミスとして、主に以下の2点をチェックしてみてください。
- 親要素にも
positionが設定されているか - 子要素に「変化前の位置」が指定されているか
一つずつ見ていきましょう。
まず、positionは基本的に親要素と子要素の両方に設定が必要です。
例えば、以下のような入れ子構造のボックスがあると仮定し、子要素(child_box)の位置をマウスオーバーで移動させたい場合。
|
1 2 3 |
<div class="parent_box"> <div class="child_box"></div> </div> |
この時、親要素(parent_box)のpositionがデフォルト値のstatic以外に指定されていないと、子要素の位置をpositionで変更することができません。
必ず親要素のスタイルでpositionをrelativeなどに指定しておきましょう。
|
1 2 3 4 5 6 |
.parent_box { width: 200px; height: 50px; border: 1px solid #333; position: relative; } |
次に見落としがちなのが、transitionとの組み合わせでは変化前の位置を指定しておく必要がある、ということです。
例えば、以下のようなコードではtransitionの設定は効きません。
|
1 2 3 4 5 6 7 8 9 10 11 |
.child_box { width: 100px; height: 50px; background: #db7093; position: absolute; transition: 1.5s all ease-in-out; /* 無効 */ } .parent_box:hover .child_box { left: 100px; } |
下図のようにマウスオーバーイベント自体は実行されているものの、transitionのスタイルは無視されているのがわかります。

positionのマウスオーバーイベントにtransitionを適用させるためには、子要素にデフォルトの位置を指定します。
|
1 2 3 4 5 6 7 8 9 10 11 12 |
.child_box { width: 100px; height: 50px; background: #db7093; position: absolute; left: 0; transition: 1.5s all ease-in-out; } .parent_box:hover .child_box { left: 100px; } |
マウスオーバーイベントでleftを指定している場合は、leftの開始地点を子要素に記しておきましょう。

4.transitionにdisplayを指定している
マウスオーバーによる表示・非表示を切り替えたい時displayを使うことがあります。
display: noneを指定することで要素をまるごと非表示にしてから、:hover時のスタイルをdisplay: blockに戻して表示させるテクニックです。
例えば、下図のようなドロップダウン式のメニューを作る際、:hoverでdisiplayの値を操作することによって、下層メニューの表示・非表示を切り替えています。

この「触れると表示されるメニュー」に、今度はtransitionを指定して時間をかけて表示させてみたいと思います。
まず、HTMLは以下の通りです。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
<ul class="parent_list"> <li> <a href="#" class="heading">Fishes</a> <ul class="child_list"> <li><a href="#">Mackerel</a></li> <li><a href="#">Sardine</a></li> <li><a href="#">Salmon</a></li> </ul> </li> <li> <a href="#" class="heading">Meats</a> <ul class="child_list"> <li><a href="#">Beef</a></li> <li><a href="#">Pork</a></li> <li><a href="#">Chicken</a></li> </ul> </li> <li> <a href="#" class="heading">Vegetables</a> <ul class="child_list"> <li><a href="#">Carrot</a></li> <li><a href="#">Cabbage</a></li> <li><a href="#">Green pepper</a></li> </ul> </li> </ul> |
このようにリストを入れ子状態にし、下層メニュー(.child_list)の初期値にdisplay: noneを、マウスオーバー時のスタイル(:hover)にdisplay: blockを指定しています。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
ul { list-style-type: none; padding: 0; } .parent_list { position: relative; } .parent_list > li { display: inline-block; } .parent_list a{ display: block; width: 200px; padding: 5px 20px; background: #fff; border-right: 1px solid #333; border-left: 1px solid #333; border-bottom: 1px solid #333; } .heading{ border-top: 1px solid #333; } .child_list { position: absolute; display: none; /* 下層メニューを非表示 */ transition: 1s all linear; } .parent_list li:hover .child_list { display: block; /* 下層メニューを表示 */ } .child_list a:hover{ background: #aaa; } |
しかし、残念ながら上記を反映させてもtransitionは効きません(※マウスオーバーイベントはきちんと機能します)。
というのも、どうやらtransitionでdisplayを操作することはできないようなのです。
そこで代替策としてopacityプロパティを使います。
先ほどのCSSコードの28~36行目を次のように変更してください。
|
1 2 3 4 5 6 7 8 9 10 11 |
.child_list { position: absolute; visibility: hidden; opacity: 0; transition: 1s all linear; } .parent_list li:hover .child_list { visibility: visible; opacity: 1; } |
opacityは不透明度を調整するプロパティですが、「0」を指定すると全く見えない状態(=非表示)に、「1」を指定すると完全に見えている状態(=表示)にすることが可能です。
transitionを指定することで、下層メニューがジワジワと現れ出るような動きになります。
ちなみに、visibilityもhidden(非表示)からvisible(表示)に切り替えるよう指定してください。
というのも、opacityだけだと透明な範囲に触れるとマウスイベントが発生してしまうためです。
下図のように親メニューに触れた時のみ下層メニューが表示させるようにするには、opacity&visibilityとセットでtransitionを設定してください。

(※画質の劣化により枠線の表示が乱れていますが、実際の使用では枠線がきちんと表示されます)
まとめ
今回は、transitionが効かない時の原因と対処法を解説しました。
マウスオーバー時の変化にアニメーションのような動きを与えることができるtransitionは、今ではWEBデザインには欠かせない存在です。
しかし一方で、ルールなどが多く初心者がつまづきやすいプロパティでもあります。
もしもtransitionが上手く機能しない時は、再びこの記事を参照してみてください。
最後にtransitionが効かない時に確認すべきポイントを簡単におさらいしておきましょう。
:hover{}内ではなく、変化させたい要素のスタイルにtransitionを指定しようspamやaなどのインライン要素をtranform(変形)させることはできないpositionで要素を移動させる時は、カーソルが触れる前の位置を指定しようdiplayはtransitionで操作できない ⇒opacity&visiblityで対応しよう



