z-indexが効かない場合はtransformに気をつけよう!【safari】

公開日:

こんにちは、れい@xxbicotです。
この間、iPhoneとMacのsafariブラウザでcssのz-indexが効かない、なぜか指定した順番通りにならない、という事象が発生しました。
どうやらtransformが怪しそう…ということで、調査して修正方法をまとめました。

safariブラウザ以外にも有効な場合があるようなので、z-indexにお困りの方はご参考にどうぞ!

z-indexが効かない

今回起きた事象をシンプルなコードで再現してみました。

See the Pen z-index3Dver by BICOxxx (@BICOxxx) on CodePen.

サンプルでは大きいdivを赤背景、青背景の2つ用意しています。

  • 背景→ヘッダーのようにabsolute要素で上部固定、 z-index:2 を指定。(やや透過させています)
  • 背景→relative要素で z-index:1 を指定。
  • 背景→青背景要素の子要素。

という感じ。

おおよそのブラウザでは下の図のように、上から赤要素→緑要素→青要素の順で重なって表示されます。


※ほとんどのブラウザの表示

しかし、safariで先ほどのcodepenを見るとわかるかと思いますが、iOSとMacのsafariブラウザでは緑要素→赤要素→青要素の順で表示されてしまっています。


※safariブラウザの表示

safariのバグが原因

要素の表示順に関して調べて見ると、2Dと3Dで異なる値を使用しているようです。
それぞれ以下のプロパティの値で制御しているとのこと。

表示順制御値
2Dレンダリング z-indexの値
3Dレンダリング transformのz軸の値
(translate3d(0,0,●)またはtranslateZ(●))

今回の事象は、このz値にsafariの不具合が関連して発生しているらしい。

こちらに同事象についての詳しく書かれていました。

ちょっと理解できなかった部分があったので個人的な解釈が入りますが、

  • 2Dも3Dも基本的にはそれぞれのグループ内で表示順が保持される
  • しかしsafariでは3Dアニメーションを行うとき元のz-indexが失われてしまう
  • この時アニメーションされた要素のz軸が別のz-indexグループにいれられるため、他のz-indexを無視して前にでてきてしまう

こういうことのようです。

これを解決するには、それぞれのz-indexを保持してもらう必要があるので、
3D要素を包む要素に、transformのz軸の値を指定して順番を指定してあげればいいとのこと。

親要素にtransformのz軸を指定することで解消

ためしてみます。

今回のサンプルでは、緑要素の表示順がおかしくなっているので、親である青背景の要素にtransformのz軸(ここではtransform:translate3d(0,0,0) )を追記。

※z軸”0″は要調整

これだけでさくっと修正!

親要素に transform-style:preserve-3d を指定していたり、複雑な構成だったりする場合は1行では解決しないかもしれないので、transform関連のプロパティを色々いじってみましょう。

まとめ

最初にも書きましたが、safari以外のブラウザでもtransformのz軸を調整したらz-indexが正常に効くようになったという事例がいくつかありました。
なのでz-indexが効かなくて困ったら、まずはtransformのz軸を確認してみましょう。

以上、z-indexが効かない時の対処法でした!

  • このエントリーをはてなブックマークに追加