ひだまりソケットは壊れない

ソフトウェア開発に関する話を書きます。 最近は主に Android アプリ、Windows アプリ (UWP アプリ)、Java 関係です。

まじめなことを書くつもりでやっています。 適当なことは 「一角獣は夜に啼く」 に書いています。

IE 6 と IE 7 において絶対配置の要素を relative 配置に変更すると中身のレンダリング位置がおかしくなる問題

ある要素の CSS position プロパティを fixed から relative に変更した時、Internet Explorer 7 (IE7) でその要素の中身が画面上から消えてしまうという事案が発生。 詳しく動作を追ってみたところ、その要素の中身は本来あるべき位置とは全然違う位置にレンダリングされていて、画面上に表示されないという感じになっていました。

Internet Explorer 6 (IE6) で確認したところ、こちらも同様の現象が発生しました。 (IE 6 では "position: fixed" は無効なため、"position: absolute" から "position: relative" に変更した場合のみ確認。)

サンプル

以下、バグを再現させるサンプル。 ドキュメントをクリックすると赤いボーダーで囲まれた要素の position プロパティの値が absolute と relative でトグルするのですが、IE 6, 7 で実行すると absolute → relative の変化の際に中身の要素が見えなくなると思います。

原因と解決策

下記ページに原因っぽいことが書いてありました。

Note that position: relative does not trigger hasLayout, which leads to some rendering errors, mostly disappearing or misplaced content. Inconsistencies might be encountered by page reload, window sizing and scrolling, selecting. With this property, IE offsets the element, but seems to forget to send a “redraw” to its layout child elements (as a layout element would have sent correctly in the signal chain of redraw events).

On having layout — the concept of hasLayout in IE/Win

あんまり IE の hasLayout プロパティに関しては詳しくない (し、「今更調べても...」 って感じなので深追いしてない) のですが、絶対配置 (position プロパティが fixed か absolute) の要素は "has layout" となるのに対して、"position: relative" の要素は必ずしも "has layout" ではないのでレンダリングにミスって中身が表示されなかったりあるべき位置ではない位置に表示されたりしてしまう、ということのようです。

そんなわけなので、"position: relative" にするときにその要素を "has layout" 状態にすれば良いようです。 "has layout" 状態にする方法は 「On having layout — the concept of hasLayout in IE/Win」 に書いていますが、例えば "zoom: 1" を指定するとか、"overflow: hidden" を指定する (IE 6 では無効) などの方法があります。