overflow: overlay;

Google Chrome の Developer Tools で要素のスタイルをいじっていたら、overflow プロパティに overlay なる値があることを知った。インターネットをざっと検索した感じだとどうやら Webkit 系のみで使えるようだ。

Developer Toolsでoverlay値を表示したキャプチャ

W3C の overflow の仕様(CSS2.1 Visual EffectsCSS Overflow Module Level 3CSS basic box model)を見ても overlay 値に関する記述はない。

検索結果を追っていくと、2009 年に Webkit Bugzilla に投稿されたoverlay 値に対する提案が見つかる。標準仕様になく Webkit でしか動かないなら削除するか-webkit-overlay のようにプリフィックスをつけてはどうかという主旨だが、やりとりの中で2006 年に-webkit-overlay をアンプリフィックスしたよというコメントがあって驚いた。8年前!えっじゃあ-webkit-overlay が実装されたのいつなんだろう。さらに、overlay はスクロールバーが発生しないので、イベントをトリガーしないという興味深いコメントもある。

Webkit Bugzilla では 2009 年の投稿から 2013 年まで放置されてて、その後JSFiddle にデモが置かれたのがきっかけかわからないけど、W3C のスタイルのフォーラムにもoverlay の話題が投稿された。

W3C のフォーラムではなかなか盛り上がっていたようでマイクロソフトの独自実装のことも紹介されている(これも知らなかった!)。イベントのトリガーの件も議論されそうになったものの、overflow プロパティだけじゃなく他の仕様のことも併せて考えたほうがいいのではみたいな流れになって、最後にスクロールバーの計算方法についての提案のリンクが貼られてスレッドは終わっている。それから1年半ほど経つが、結局 overlay 値が標準化するでもなく、Webkit から削除されるでもリネームされるでもなく、現在も指定可能になっているという状況のようだ。

ブラウザで確認

さっそく一通りのブラウザで表示確認する。前提として、標準設定の Mac OS とモバイルブラウザはスクロールバーがデフォルトで非表示であり、コンテンツがスクロール可能な場合はスクロールするとオーバーレイでスクロールバーが表示される。なのでそちらのキャプチャは撮っていない。Mac で確認したい場合は環境設定 -> 一般からスクロールバーを「常に表示」にすると良い。

JSFiddle の最初のデモはあまり見やすくないので、フォークしたもので確認した。左のボックスが overlay、右は auto 値が指定されている。JSFiddle の埋め込みが何も表示されていない場合は Result のタブを押せば出てくるはず。

OS / ブラウザ別の様子。左のボックスがoverflow: overlay、右はoverflow: autoを指定している。
Mac / Safari 7.0.5 Mac / Safari 7.0.5でのキャプチャ
Mac / Google Chrome 35 Mac / Google Chrome 35でのキャプチャ
Mac / Firefox 30 Mac / Firefox 30でのキャプチャ
Win / IE11 Win / IE11でのキャプチャ
Win / Google Chrome 35 Win / Google Chrome 35でのキャプチャ
Win / Firefox 30 Win / Firefox 30でのキャプチャ

Mac Chrome 35 のキャプチャが一番わかりやすい。通常、overflow のスクロールバーはその要素幅の内側に表示されて、コンテンツ部分の幅が狭まる。しかし overlay 値を指定するとスクロールバーがコンテンツにかぶさるようになる。Safari や Win Chrome のキャプチャでは一見わかりにくいが、改行された数字が1つ飛んでいるので、スクロールバーにかぶさった分が隠れていると推測できる。上記に埋め込んだ jsfiddle のデモでは resize をつけているので、左右に動かしてみるとコンテンツにスクロールバーがかぶさる様子がわかると思う。

Firefox と IE では適応されていないが、その場合の挙動は auto ではなく visible のようだ。overflow の初期値になるのではなく、無効なプロパティと解釈されて overflow が宣言されていない状態かつ高さは 100px なのでコンテンツは下にはみ出る状態になる。規定のレンダリング。

ついでに-ms-autohiding-scrollbar も書いてみた。IE11 で見たキャプチャは割愛するが、スクロールバーは出ずに visible 値と同じように表示されているように思う。これが正しい描画なのかわからない……。

イベントをトリガーしない?

イベントの件はどうだろうか。そもそも何のイベントについてなのかわからない。おそらく resize だろうとあたりをつけてコードを書いたけど resize イベントは window(viewport)しか持てないようで検出できなかった。そこで overflow している div の中にもう1つ div を用意して Developer Tools で確認したところ、auto 値の方はスクロールバーが出現すると内包している div の width は小さくなり、overlay 値の方は overlay がない時と width が変わらなかった。

となれば、overlay を指定した要素は内包物の変化で width と height が変わらないことになり、ブラウザレンダーのレベルで描画コストが低いと言えるような気がする。

任意の要素で resize イベントが取れれば検証も簡単なのに。都度サイズを調査する関数を呼んでもいいけどなんか微妙な感じがするので書くのをやめた。

そもそも Webkit 系のみ

overflow: overlay;があって嬉しい人はあまりいない気がする。現状ではすでにデフォルト設定の Mac、iPhone や Android ではすでにスクロールバーは非表示だし、スクロールバーが表示される環境の Chrome や Safari でもコンテンツ幅が狭まらないとは言え、要素がその分だけ隠れてしまう。隠れていても横スクロールも発生しないし、領域をマウスデバイスなどでドラッグしても隠れている部分を見ることはできず、閲覧者に優しくない。いったいどういう理由でこの値は生まれたんだろうか。

overlay 値は 2006 年にすでに使用可能だったわけだが、その頃は Mac もまだスクロールバーはオーバーレイ表示ではなかった頃だったと思う。となるとスクロールバーを表示しなければならなくたった時にコンテンツ幅に不都合が生じる状況に対応するために都合主義的に実装されたのかもしれない。


効果と現状から言って overlay 値が W3C で標準化されることはなさそう。今回ふとしたきっかけでプロパティの値についての議論を追ってみたが、けっこう面白かったので何かでまたやりたい。