包容要素にoverflow:hidden;を使う際の注意点メモ
高さの異なるカラムを揃えるスタイルシートで包容要素にoverflow:hidden;を指定する際、その中身に対してページ内リンクを使うと移動された部分より上が非表示になります。
具体的な内容は以下に記します。
HTMLサンプル
<div id="wrap"> <div id="main"> <div id="section1"> <!-- 内容 --> </section> <div id="section2"> <!-- 内容 --> </section> </section> <div id="navi"> <p><a href="#section2">第二セクション</a></p> </section> </section>
CSSサンプル
#wrap {
width: 750px;
margin: 0 auto;
overflow: hidden;
}
#main {
float: right;
width: 550px;
}
div#section1 {
background: #FCC;
height: 500px; /* 消える領域表現の為の高さ */
}
div#section2 {
background: #CCF;
height: 500px; /* デモなので中身無しで高さだけ */
}
#navi {
float: left;
width: 200px;
margin-bottom: -32768px; /* 高さを揃える */
padding-bottom: 32768px;
background: #CFC;
}
デモと補足
ちょっとデモ用に要らない部分を付け足しすぎた感がありますが、そんなに難しい内容では無いので消えることだけ覚えておいて下さい。
Firefox2.0 , Safari3.1 , IE6 , IE7 で消える現象を確認。
※2008-04-16 09:15 修正 : デモページのstyle内のコメントアウトが正しく無かったため、IEとOperaで表示出来ない不具合を修正しました。ご指摘感謝いたします。
原因
抽象的だった部分を具体的に記述しました。
まず、下方向へのpaddingにより [#naviのheight + 32768] pxの領域が確保され、Negative margin と overflow:hidden により [#mainの高さ - #naviのheight - 32768] pxの領域が切り取られ、非表示になります。
ここで大事なのは、切り取られた部分が見えていないだけで存在すると言う点。
この状態でページ内リンクを使って移動すると、見えていないだけで存在する領域も合わせて移動するため、フラグメント識別子で指定したセクションより上の領域が、はみ出した領域として扱われ非表示になってしまいます。
iframeで考えるとイメージし易いと思います。
※この問題に対する画期的な回避方法は特にありませんが、IEではzoom:1;を使うことで回避出来たりします。
wuさんのコメントも大変参考になりますので、是非ご覧下さい。
まとめ
どうしてもページ内リンクを使いたい場合は、カラムの高さ合わせには包容要素に背景を指定する方法など、従来どおりの方法を使う。
理解してても、横着するとたまにやってしまったりするかも。なメモ。
こんばんは。
高さを揃えられる!と喜んで使ってこの現象にはまり、よく考えるとソッカ…ってことがありました。
ラグメント識別子へとページが移動する際、overflow の指定のあるボックスでスクロールを内部ボックスへと切り替え、overflow: hidden のボックスが強制的にスクロールされ、内容物が見えない領域に移動されてしまうのが原因なので、ネガティブマージンは直接関係ないと思います。
以下のようなシンプルなものでも再現できました。
<p><a href="#link">1</a></p>
<div id="box1">
<p id="an">2</p>
<p id="link">3</p>
</div>
–
#an {
margin-bottom: 500px;
}
#box1 {
height: 200px;
background-color: #ccc;
width: 300px;
overflow: hidden;
}
つまるところ、overflow:hiddenで隠れてる領域があるとき、そこがスクロールされると見えてた領域が見えない領域にとんじゃうってことですかね。
ご指摘ありがとうございます。
おっしゃる通り、ネガティブマージンは直接の原因では無いですね。
今回の(カラムの高さを合わせる)例で言うと、直接の原因は下方向へのパディングで、ネガティブマージンはパディングの引き立て役に過ぎません。
包容要素の高さが固定では無い場合、ネガティブマージンを指定しなければこの現象は発生しないと思い、"ネガティブマージン辺り" と言う物凄く曖昧な表現を使用するに至りましたが、よく考えればコレもまた、誤解を生みそうな言葉ですよね。
ご指摘頂いた内容を参考に、記事を修正させて頂きます。ありがとうございました!
> overflow:hiddenで隠れてる領域があるとき、そこがスクロールされると見えてた領域が見えない領域にとんじゃう
この説明がシンプルで解り易いですね。今後、説明の際には使わせて頂きます:-)