Rewish

包容要素にoverflow:hidden;を使う際の注意点メモ

高さの異なるカラムを揃えるスタイルシートで包容要素にoverflow:hidden;を指定する際、その中身に対してページ内リンクを使うと移動された部分より上が非表示になります。

問題のサンプル

HTMLサンプルコード

<div class="example-wrap">
  <div class="example-main">
    <div id="example-section1"></div>
    <div id="example-section2"></div>
  </div>

  <div class="example-navi">
    <p><a href="#example-section2">第二セクションへ移動</a></p>
  </div>
</div>

CSSサンプルコード

.example-wrap {
  width: 500px;
  overflow: hidden;
}

.example-main {
  float: right;
  width: 350px;
}

#example-section1 {
  background: #FCC;
  height: 250px;  /* 消える領域表現の為の高さ */
}

#example-section2 {
  background: #CCF;
  height: 250px;  /* デモなので中身無しで高さだけ */
}

.example-navi {
  float: left;
  width: 150px;
  margin-bottom: -32768px;  /* 高さを揃える */
  padding-bottom: 32768px;
  background: #CFC;
}

動作サンプル

原因

まず、下方向へのpaddingにより .example-naviのheight + 32768px の領域が確保され、Negative margin と overflow:hidden により .example-mainの高さ - .example-naviのheight - 32768px の領域が切り取られ、非表示になります。

ここで大事なのは、切り取られた部分が 見えていないだけで存在する と言う点。

この状態でページ内リンクを使って移動すると、見えていないだけで存在する領域も合わせて移動するため、フラグメント識別子で指定したセクションより上の領域が、はみ出した領域として扱われ非表示になってしまいます。

iframeで考えるとイメージし易いと思います。

※この問題に対する画期的な回避方法は特にありませんが、IEではzoom:1;を使うことで回避出来たりします。

まとめ

どうしてもページ内リンクを使いたい場合は、カラムの高さ合わせには包容要素に背景を指定する方法など、従来どおりの方法を使う。

理解してても、横着するとたまにやってしまったりするかも。なメモ。