CSSのz-indexの値はcalc(Infinity)のほうが良いと思った

z-indexの値のinfinityとは

先週、z-indexについての以下の投稿が話題になっていました。

いつの時代にも z-index の管理には頭を悩ませます。z-index の値には 1 以外の値を許可しないなどの管理方法がありますが、外部のライブラリを使用してる場合に勝つことができません。

そこで z-index の値に calc(infinity) を指定すると、絶対に最前面に表示させることができます。

CSS で絶対に最前面に表示したい要素には z-index: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)」を使用することをオススメします。

カテゴリーcss