古い CSS を読んでいると、zoom: 1; という指定を見かけることがあります。見た目は何も変えないこの指定は、Internet Explorer 7 までの表示の不具合を直すために使われていました。ただし、何にでも付けると、かえって別の不具合を招くことがありました。その代表が、番号付きリストの番号がすべて「1」になる現象です。

hasLayout とは

Internet Explorer 7 までは、要素ごとに「hasLayout」という内部の状態を持っていました。hasLayout が true の要素は、自分の大きさや中身の配置を自分で決めます。false の要素は、親要素に配置を任せます。

この状態によって表示が変わるため、float の回り込みが解除されない、背景が途中で切れる、といった不具合の多くは「hasLayout が false だったから」起きていました。

hasLayout は、次のような指定で true になります。

  • width や height に auto 以外の値を指定する
  • float: left や float: right
  • position: absolute
  • display: inline-block
  • zoom に normal 以外の値を指定する (IE 独自のプロパティ)

zoom: 1 は「等倍に拡大する」という意味なので、見た目を変えずに hasLayout だけを true にできます。そのため、不具合を直す決まり文句として広く使われました。

すべての要素に付けると起きること

手軽さから、次のようにすべての要素へ一括で指定する書き方も見られました。

* {
  zoom: 1;
}

ol li {
  width: 200px;
}

この状態で番号付きリストを表示すると、IE6・IE7 では、項目の番号がすべて「1.」になってしまいます。

<ol>
  <li>一つ目</li>
  <li>二つ目</li>
  <li>三つ目</li>
</ol>

原因は、li 要素の hasLayout が true になったことです。IE7 までは、hasLayout が true の li が、それぞれ別のリストのように番号を数え直してしまいました。zoom: 1 だけでなく、li に width を指定した場合も同じことが起きます。

このように hasLayout は表示を直すこともあれば、壊すこともありました。不具合のある要素にだけ付け、まとめて付けないのが当時の基本でした。

今の CSS での考え方

hasLayout は IE8 の標準モードで廃止され、Internet Explorer 自体もサポートが終わっています。今のブラウザー向けの CSS に、hasLayout のための zoom: 1 は必要ありません。古い CSS を手入れするときは、IE 向けの指定を整理するとよいでしょう。

  • float の回り込みを内側で解除する目的なら、display: flow-root を使う
  • 横並びのレイアウトそのものは、float ではなく Flexbox や Grid で組む
  • リストの番号の見た目を変えたいときは、list-style や ::marker、CSS カウンターを使う
/* 中の float を親要素の高さに含める */
.media {
  display: flow-root;
}

なお、zoom プロパティは、今では主要なブラウザーがそろって対応しています。zoom: 1 は等倍なので見た目は変わりませんが、1 以外の値が残っていると、要素がそのまま拡大・縮小されます。古い CSS に残っている zoom の指定は、意図を確かめてから消してください。

まとめ

  • zoom: 1 は、IE7 までの hasLayout を true にするための指定だった
  • hasLayout が true の li は番号を数え直すため、すべての要素に付けると番号付きリストが崩れた
  • 今のブラウザー向けには不要。回り込みの解除は display: flow-root、レイアウトは Flexbox や Grid で行う

参考