昨年末にリリースされた Chrome と Edge の 108 以降では、Flexbox で並べた子要素の重なり順がこれまでと逆になるという現象が発生しています。一方、Firefox や Safari ではこれまでの Chrome と同じ表示のままで、変化はありません。
読者の方からいただいたメールで気付くことができましたので、原因と対処方法をまとめておきます(本当にありがとうございました)。
エビスコムの書籍でこの現象の影響を受けたのは『HTML&CSS コーディング・プラクティスブック 4』です。この本の作例に対処方法を反映する手順やコードについては、ダウンロードデータを更新しましたので参照してください。
この現象の原因を調べてみたところ、どうやら Chrome と Edge(いずれも Blink)のバグのようです。
1395330 - Using flex-direction: row-reverse now layers child elements in the opposite order. - chromium
https://bugs.chromium.org/p/chromium/issues/detail?id=1395330
Flexbox の flex-direction: row-reverse や column-reverse で子要素の並び順を変え、z-index なしで重ねたときに発生します。
たとえば、HTML で[画像 <figure>] → [テキスト <h1>]の順に記述したものを Flexbox で横並びにし、並び順を変えずにネガティブマージン(マイナスマージン)で重ねてみます。
z-index は指定していないため、重なり順は DOMツリーに従い、後から記述したテキストが上になります。この場合、Chrome 108 以降でも Firefox や Safari と同じ重なり順になり、問題は発生しません。
<div class="flex">
<figure><img src="lemon.jpg" alt="" /></figure>
<h1>Fresh Lemon</h1>
</div>
.flex {
display: flex;
}
.flex > h1 {
margin-left: -80px;
}
しかし、flex-direction: row-reverse で並び順を逆にすると、Chrome 108 以降では重なり順が逆になってしまいます。
.flex {
display: flex;
flex-direction: row-reverse;
}
.flex > h1 {
margin-right: -80px;
}
Flexboxの仕様書では、flex-direction の項目に「reverse 値はボックスの順序を逆転させない」「ペイント順、読み上げ順、ナビゲーション順も影響を受けない」との注意書きがあります。
NOTE: The reverse values do not reverse box ordering
https://w3c.github.io/csswg-drafts/css-flexbox/#flex-direction-property
そのため、row-reverse を適用してもボックスの順序(重なり順)を逆転させない、Firefox や Safari によるこれまで通りの表示が正しいと言えるでしょう。
Chrome 108 以降で重なり順が逆になるのを防ぐためには、z-index で重なり順を明示します。
たとえば、<h1> に z-index: 1 を適用すると、row-reverse で並びを逆にしていてもテキストが上になり、ほかのブラウザと表示がそろいます。
.flex {
display: flex;
flex-direction: row-reverse;
}
.flex > h1 {
margin-right: -80px;
z-index: 1;
}
現時点では、Chrome の canary 版(112)でも修正は入っていません。こうした問題が発生することを考えると、要素を重ねるときには確実に z-index を指定した方がよいのかもしれません。