ある日の我が家
娘「ねぇ、パパ!」
ワイ「おお、なんや?娘ちゃん」
娘「HTMLとCSSでダイアログを作る方法を教えて欲しいの!」
ワイ「おお、ええでぇ」
ワイ「ちょうど今、ワイの個人ブログを作ってるところでな」
ワイ「これからダイアログを作るから、やり方を見せてあげるでぇ」
娘「わ〜い、ありがとう!」
娘「わたし、z-index
がうまく使えなくて困ってたの!」
ワイ「おぉ、パパに任せとき!」
ワイ「パパはz-index
を完全に理解してるからな!」
z-index
完全理解ワイ、説明開始
ワイ「今、こんなサイトを作ってるんやけどな?」
ワイ「↑このサイトにダイアログを表示できるようにしたいんや」
「記事の投稿が完了しました。」
ワイ「↑こういうメッセージを表示するためのダイアログや」
娘「なるほどね」
ワイ「ほな、コードを書いていくで」
ワイ「まず、現状のコードは──」
<body>
<header>
<h1>やめ太郎のサイト</h1>
</header>
<main>
<section>
<h2>記事一覧</h2>
<ul>
<li>
<article>
<h3>記事タイトル</h3>
<p>記事の内容。記事の内容。記事の内容。記事の内容。記事の内容。記事の内容。記事の内容。記事の内容。</p>
</article>
</li>
<!-- 〜以下省略〜 -->
ワイ「↑こんな感じや」
ワイ「ここに、ダイアログ用のHTMLを追加するで」
<body>
<header>
<h1>やめ太郎のサイト</h1>
</header>
<main>
+ <div id="dialog-area">
+ <p>z-index完全に理解した。</p>
+ </div>
<section>
<h2>記事一覧</h2>
<ul>
<li>
<article>
<h3>記事タイトル</h3>
<p>記事の内容。記事の内容。記事の内容。記事の内容。記事の内容。記事の内容。記事の内容。記事の内容。</p>
</article>
</li>
<!-- 〜以下省略〜 -->
ワイ「↑こうやな」
ワイ「そんで、次はCSSを書くで」
#dialog-area {
+ position: fixed;
+ z-index: 1;
padding-top: 57px;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.3);
}
ワイ「↑こうや」
ワイ「ほな、ブラウザで動作確認してみるで!」
ワイ「ファッ!?」
娘「ダイアログが、ヘッダの後ろ側になっちゃってるね」
ワイ「せやな・・・」
娘「文字も10%くらい隠れちゃってる」
ワイ「ああ・・・」
ワイ「10%くらい隠れてもうてるってことは」
ワイ「90%くらいしかz-index
を理解できていなかったみたいや・・・」
娘「そうだね・・・」
よめ太郎「(そうなのか・・・!?)」
原因を探して行く
娘「あ、パパ!」
娘「分かったかも!」
header {
position: fixed;
z-index: 10;
/* 〜省略〜 */
}
娘「↑ヘッダ部分のz-index
が10
になってるでしょ?」
娘「そして──」
#dialog-area {
position: fixed;
z-index: 1;
/* 〜省略〜 */
}
娘「↑ダイアログ部分のz-index
が1
になってる!」
娘「ここが原因じゃない?」
ワイ「おお、さすが娘ちゃん!」
ワイ「ほな、ダイアログ部分のz-index
を11
にしたるで!」
#dialog-area {
position: fixed;
- z-index: 1;
+ z-index: 11;
/* 〜省略〜 */
}
ワイ「↑こうやな!」
ワイ「ほな、もう一回ブラウザで動作確認してみるで!」
ワイ「ぐぬぬ・・・」
ワイ「なんでや・・・」
ワイ「ワイはz-index
を完全に理解したはずなのに・・・!」
娘「パパ、仕方ないよ・・・!」
娘「きっと、完全に理解した期の後の」
娘「なんも分からん期に突入したんだよ!」
ワイ「おお、そういうことか・・・」
ワイ「ワイもまた一歩、成長したんやな!」
よめ太郎「いや何でやねん」
よめ太郎「まだ何も理解できてないだけやろ」
ワイ「Oh・・・」
ワイ「せやな・・・」
よめ太郎氏、解説開始
よめ太郎「z-index
はな」
よめ太郎「親要素どうしの戦いで負けてたらアカンねん」
ワイ「親要素どうしの戦い・・・どういうこと?」
よめ太郎「今回の例でいうと──」
<body>
<header>
<h1>やめ太郎のサイト</h1>
</header>
<main>
<div id="dialog-area">
<p>z-index完全に理解した。</p>
</div>
<section>
<h2>記事一覧</h2>
<!-- 〜以下省略〜 -->
よめ太郎「↑こう、header
要素とmain
要素が兄弟になってるやん」
ワイ「せやな」
よめ太郎「そんで──」
header {
position: fixed;
z-index: 10;
/* 〜省略〜 */
}
よめ太郎「↑こう、header
要素のz-index
が10
になってて」
main {
position: relative;
z-index: 0;
/* 〜省略〜 */
}
よめ太郎「↑こう、main
要素のz-index
が0
になっとる」
よめ太郎「これが原因や」
ワイ「つまり、どういうこと・・・?」
よめ太郎「つまりな──」
-
header
要素・・・z-index: 10
-
main
要素・・・z-index: 0
-
main
要素の子要素であるダイアログ部分も、header
要素に勝てない
-
よめ太郎「↑こういうことや」
ワイ「なるほど・・・!」
ワイ「親要素どうしの戦いで負けてたらアカン
っていうのは」
ワイ「こういう意味だったんか・・・!」
娘「そっか!」
娘「じゃあ、こうすればいいんだね!」
<body>
<header>
<h1>やめ太郎のサイト</h1>
</header>
+ <div id="dialog-area">
+ <p>z-index完全に理解した。</p>
+ </div>
<main>
- <div id="dialog-area">
- <p>z-index完全に理解した。</p>
- </div>
<section>
<h2>記事一覧</h2>
<!-- 〜以下省略〜 -->
娘「↑ダイアログ部分を、main
要素の外に出して」
娘「header
と兄弟になるようにしてみたよ!」
ワイ「おお」
娘「z-index
の数値は──」
header {
position: fixed;
z-index: 10;
/* 〜省略〜 */
}
#dialog-area {
position: fixed;
z-index: 11;
/* 〜省略〜 */
}
娘「ダイアログ部分の方が大きくなってるから、これでいいんじゃない!?」
ワイ「よっしゃ、ブラウザで見てみよか!」
ワイ「おお、ええ感じや!」
ワイ「これがやりたかったんや!」
まとめ
- 親要素どうしの
z-index
争いで負けていると、その子要素も負けてしまう- 負けないためには
- 自分の親要素が
z-index
争いで負けないようにする - もしくは自分自身が兄弟要素になって
z-index
争いで勝つ
- 自分の親要素が
- 負けないためには
娘「こういうことだね!」
ワイ「せやな!」
ワイ「ダイアログみたいに最前面に表示したい要素は、body
直下とかに書くのがええかもな!」
よめ太郎「せやな」
よめ太郎「出来るだけ外側のHTMLタグになって、親要素どうしの勝敗に左右されん方がええよな」
よめ太郎「Reactだったらポータルとか」
よめ太郎「VueだったらTeleport(PortalVue)を使うと」
よめ太郎「要素を外側に配置できるからいいよな」
ワイ「おお〜、なるほど」
よめ太郎「あと、z-index
を指定する場合は、position
の指定も忘れずにな」
よめ太郎「position
を指定しなかった場合は、初期値のposition: static;
扱いになってしまうからな」
よめ太郎「position: static;
の状態でz-index
を指定しても、効かへんねん」
よめ太郎「relative
とかabsolute
とかfixed
とかsticky
、そういうのを指定せなあかんねん」
ワイ「おお、そういえばせやったな」
娘「ママ、すご〜い!」
その日の夜
ワイ「いや〜、今日も勉強になったわ」
ワイ「ワイ、また成長してもうたで」
ワイ「完全に理解した を超えて」
ワイ「なんも分からん も超えて」
ワイ「チョットデキル に到達してしまったかもしれんわ!」
娘「わ〜い!」
娘「パパ、CSSチョットデキル!チョットデキル!」
よめ太郎「いやリアルにちょっとできるだけやん」
〜おしまい〜