- web design -

blog

CSS transform / opacity / transition 周りの意図しない挙動・不具合・バグフィックスまとめ [ 随時更新 ]

CSS

こんにちは、ma-ya’s CREATE[まーやずくりえいと]です。

要素をアニメーションさせる時に毎度お世話になるCSSのtransformやopacity。描画とロジックをCSSとJSに分離するためにも、なくてはならない存在だと思ってます。

しかし多用した場合、他のソース部分と干渉して意図しない挙動になることもしばしば。毎度毎度調べるのも面倒なので記事で簡潔にまとめていくことにしました。

あくまで自分用メモなので解説は少な目かつ順不同です(苦笑)。

 

意識しておいた方が良い前提

 

transformやopacity指定をした要素はスタックコンテキストを生成する

スタックコンテキストとは何ぞや?というのはMDNさんにでもお任せするとして…

コレが生成されると意図しない挙動に遭遇する可能性が高まります

要素の重なり順からアニメーションの挙動、さらには一見関係のなさそうな部分まで幅広い範囲に影響を及ぼすことがあります。

 

そのバグ、周辺要素にtransformとか(opacityとか)指定してませんか?

バグと対峙した時、とりあえずスタックコンテキストを生成している要素が無いかを確認してみます。

周辺要素にtransform / opacityが指定されていると、そこが原因の可能性があります。

厄介なのは、こういった意図しない挙動は見た目だけだと原因の推測が非常にし難いです。

なので推測より先に、周辺要素にスタックコンテキストを生成するような指定が無いかを見つける方がベターなケースもあります。

 

 

transform変形した要素がぼやける

 

 

汎用的な解決法

対象もしくは親要素に下記指定

-webkit-backface-visibility: hidden;
backface-visibility: hidden;

もしくは

filter: blur(0);
-webkit-filter: blur(0);

 

 

テキストがぼやける

※主にchrome / safari / firefox

対象もしくは親要素に下記指定

-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;

 

 

transform変形した要素にジャギーが出る

 

※主にfirefox

対象要素に下記指定

outline: 1px solid transparent;

 

 

transform:scale()による拡大縮小アニメーションがカクカクする

 

※主にIE11

transform:rotate()プロパティを追加する

transformscale(1.15) rotate(0.001deg);

deg値は見た目に影響の出ない範囲で指定する。

 

transitionアニメーションがちらつく

 

対象要素に下記指定

-webkit-backface-visibility: hidden;
backface-visibility: hidden;

 

iOS(iPhone)のアニメーションちらつき

perspective: 1000; //正の値

 

※will-changeプロパティは適切に実装しないとパフォーマンスに影響することがあるので次点

CSS will-changeプロパティについて知っておくべきこと

 

 

ホバー時に要素が1pxずれる

 

※主にChrome

対象要素に下記指定

-webkit-backface-visibility: hidden;
backface-visibility: hidden;

もしくは下記指定

display: inline-block;

 

 

子要素のtransition時に親要素のoverflow:hiddenが効かない

 

※主にwindows環境

※親子要素にposition指定がされていることが前提

親要素にz-index整数値を指定

親要素 {
  z-index:1;
}

子要素に指定されたtransformプロパティでスタックコンテキストが生成されることが原因か。

 

top / left / right / bottom は初期値が無いとtransitionしない

.transitionElem {
  top : 0; //初期値必須
  transition : top .3s ease;
}
.transitionElem:hover {
  top : 10px;
}

※ちなみにtransformの方がハイパフォーマンスなのでなるべくposition位置プロパティでのアニメーションは避けるべき

 

 

「transitionアニメーションがちらつく」追加
 「transform:scale()による拡大縮小アニメーションがカクカクする」追加