z-indexの値のinfinityとは
先週、z-indexについての以下の投稿が話題になっていました。
いつの時代にも z-index の管理には頭を悩ませます。z-index の値には 1 以外の値を許可しないなどの管理方法がありますが、外部のライブラリを使用してる場合に勝つことができません。
そこで z-index の値に
CSS で絶対に最前面に表示したい要素には z-index:calc(infinity) を指定するcalc(infinity)
を指定すると、絶対に最前面に表示させることができます。
CSSのz-indexプロパティは、HTML要素の重なり順(奥行きの位置)を制御するために使用されます。
z-indexは整数値で指定し、以下のように値が大きい要素ほど前面に表示されます。
/*
<div class="box red"></div>
<div class="box green"></div>
<div class="box blue"></div>
*/
.box {
position: absolute;
width: 100px;
height: 100px;
}
.red {
top: 10px;
left: 10px;
background: red;
z-index: 2;
}
.green {
top: 30px;
left: 30px;
background: rgba(0, 255, 0, 0.5);
z-index: 3;
}
.blue {
top: 50px;
left: 50px;
background: blue;
z-index: 1;
}
モーダルなどの要素の場合、なるべく最前面に表示させたいため、なるべく大きな値を指定しますが、人によって9999だったり、10000だったりして、z-indexの値にバラつきが出やすいです。
しかし、calc(infinity)を指定すれば、z-indexの最大値の2147483647 (32ビットの最大値)を指定しているのと同じことになるので、この値を使用すればバラつきがなくなります。
ちなみに2147483648以上の値を指定しても、2147483647と同等の扱いになるため、以下のようにz-indexの値が2147483648と2147483647の要素があっても、どちらも2147483647と判定されて、後続の要素のほうが前面に表示されます。
.box {
position: absolute;
width: 100px;
height: 100px;
}
.red {
top: 10px;
left: 10px;
background: red;
z-index: 2147483648;
}
.blue {
top: 50px;
left: 50px;
background: blue;
z-index: 2147483647;
}
突然ですが、ここで問題です。
以下のCSSを各要素に指定した場合の順番はどうなるでしょうか?
/*
<div class="box red"></div>
<div class="box green"></div>
<div class="box blue"></div>
*/
.box {
position: absolute;
width: 100px;
height: 100px;
}
.red {
top: 10px;
left: 10px;
background: red;
z-index: calc(infinity);
}
.green {
top: 30px;
left: 30px;
background: rgba(0, 255, 0, 0.5);
z-index: calc(1 / 0);
}
.blue {
top: 50px;
left: 50px;
background: blue;
z-index: calc(2 ** 31 - 1);
}
※ 1 / 0 は Infinity です。
※ 2 ** 31 - 1 は32ビットの最大値で2147483647です。
正解は以下のように最前面が.greenで、.red、.blueの順番になります。
「1 / 0」は「Infinity」で、calc(infinity)と2147483647が等価で、「2 ** 31 - 1」は「2147483647」なのだから、.red, .green, .blueの記述なら.blueが最前面だと思った人も多いでしょう。
しかし、calc()で使えるのは四則演算のみで、べき乗( ** )は使用できないため、前述のような結果となります。
べき乗 (** ) ではなく「*」で演算していれば、.red, .green, .blueのように記述した場合、あとに書いたものが最前面に表示されます。
.red {
top: 10px;
left: 10px;
background: red;
z-index: calc(infinity);
}
.green {
top: 30px;
left: 30px;
background: rgba(0, 255, 0, 0.5);
z-index: calc(1 / 0);
}
.blue {
top: 50px;
left: 50px;
background: blue;
z-index: calc(2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 - 1);
}
calc(infinity)ではなくcalc(Infinity)と書くべき
ところで元記事などはcalc(infinity)と書いてありますが、JavaScriptではinfinityは無効で、正しくはInfinityです。
「1 / 0」の結果もJavaScriptでは「infinity」ではなく「Infinity」になります。
CSSのcalcでは大文字と小文字を区別しないので、「infinity」「Infinity」「INFINITY」のいずれも同じ結果になります。
.red {
top: 10px;
left: 10px;
background: red;
z-index: calc(infinity);
}
.green {
top: 30px;
left: 30px;
background: rgba(0, 255, 0, 0.5);
z-index: calc(Infinity);
}
.blue {
top: 50px;
left: 50px;
background: blue;
z-index: calc(INFINITY);
}
calc(infinity)のほうで記述していると、変な癖がついてJavaScriptのほうでもinfinityと書いてしまう可能性があります。
iwb.jpでは表記揺れの防止のためにも「calc(Infinity)」を使用することをオススメします。