6

ヘッダーとフッターの高さを柔軟に変更できるレイアウトを構築しようとしています。中央のセクションが残りのスペースを消費します。中央にオーバーフローがあると、この中央セクションだけにスクロール バーが表示されます。

Safari と Chrome で正常に動作するコードは次のとおりです。

<!DOCTYPE html>
<html>
  <head>
    <style>
      html, body {
        margin: 0;
        padding: 0;
        height: 100%;
      }

      .l-fit-height {
        display: table;
        height: 100%;
      }

      .l-fit-height > * {
        display: table-row;
        height: 1px;
        background-color: red;
      }

      .l-fit-height-expanded {
        height: auto;
        background-color: blue;
        display: table-row;
      }

      .l-scroll-content {
        height: 100%;
        overflow-y: auto;
      }
    </style>
  </head>
  <body>
    <div class="l-fit-height">
      <section>
        Header
      </section>
      <section class="l-fit-height-expanded">
        <div class="l-scroll-content">
          <p>Foo</p>
          <p>Foo</p>
          <p>Foo</p>
          <p>Foo</p>
          <p>Foo</p>
          <p>Foo</p>
          <p>Foo</p>
          <p>Foo</p>
          <p>Foo</p>
          <p>Foo</p>
          <p>Foo</p>
          <p>Foo</p>
          <p>Foo</p>
          <p>Foo</p>
          <p>Foo</p>
        </div>
      </section>
      <section>
        Footer
      </section>
    </div>
  </body>
</html>

私の人生では、Firefoxで動作が異なる理由を理解できません。中央のコンテンツは高さを正しく拡張しますが、コンテンツの高さ以上に縮小することはありません。

何が正しい振る舞いなのかを知ることは困難です。何か案は?

編集

同様の設定例: http://jsfiddle.net/t3mZF/

興味深いことに、.l-fit-height-row-contentが then に変更されたdisplay: table-cell場合、WebKit と Gecko は同じ動作を示すか、オーバーフローを無視します。

が使用されている場合display: block、WebKit は目的の動作を提供します (スクロール バーとフッターはビュー ポートの下部に残ります) が、Firefox はスクロール バーの追加を拒否し、代わりに画面の下部からフッターを押し出します (ビュー ポートのスクロール バー - ではなく、中間内容)。

Bugzillaチケットもオープンしました

4

4 に答える 4

13

私はいくつかの余分な divdisplay: inline-blockを使用して、Torben が言及している絶対配置のトリックを Firefox でも使用できることが重要であることを発見しました。これは、純粋な CSS ソリューションとして、完全に柔軟なヘッダーとフッターが可能であることを意味します。

<!DOCTYPE html>
<html>
  <head>
    <style>
      html, body {
        margin:  0;
        padding: 0;
        height:  100%;
      }

      .l-fit-height {
        display: table;
        height:  100%;
      }

      .l-fit-height-row {
        display: table-row;
        height:  1px;
      }

      .l-fit-height-row-content {
        /* Firefox requires this */
        display: table-cell;
      }

      .l-fit-height-row-expanded {
        height:  100%;
        display: table-row;
      }

      .l-fit-height-row-expanded > .l-fit-height-row-content {
        height: 100%;
        width:  100%;
      }

      .l-scroll {
        /* Firefox requires this to do the absolute positioning correctly */
        display:    inline-block;
        overflow-y: auto;
        position:   relative;
      }

      .l-scroll-content {
        position: absolute;
        top:      0;
        bottom:   0;
      }
    </style>
  </head>
  <body>
    <div class="l-fit-height">
      <section class="l-fit-height-row">
        <div class="l-fit-height-row-content">
          Header
        </div>
      </section>
      <section class="l-fit-height-row-expanded">
        <div class="l-fit-height-row-content l-scroll">
          <div class="l-scroll-content">
            <p>Foo</p>
            <p>Foo</p>
            <p>Foo</p>
            <p>Foo</p>
            <p>Foo</p>
            <p>Foo</p>
            <p>Foo</p>
            <p>Foo</p>
            <p>Foo</p>
            <p>Foo</p>
            <p>Foo</p>
          </div>
        </div>
      </section>
      <section class="l-fit-height-row">
        <div class="l-fit-height-row-content">
          Footer
        </div>
      </section>
    </div>
  </body>
</html>

お役に立てれば

于 2012-09-27T13:38:33.453 に答える
3

ここで 2 つの複合的な問題に遭遇したと思います。

  1. テーブル ディメンションは、通常の div に期待されるほど固定されていません。テーブルは通常、コンテンツとともに大きくなり、コンテンツが大きすぎる場合、高さのプロパティはあまり気にしません。

    したがって、スクロールボックスのコンテンツを content-size 計算から完全に除外する必要があります。あとは、スクロール ボックスの位置とサイズを設定して、展開されたテーブル行のスペース全体を埋めるだけです。ただし、これにより別の問題が発生します。

  2. 簡単な解決策はposition:relative;、テーブル行とwidth:100%;height:100%;スクロール ボックスを設定することですが、ほとんどのブラウザーはテーブル行の位置プロパティを無視するため、これは機能しません。テーブル行とスクロール ボックスの間に別の div を挿入することもできdisplay:table-cell;position:relative;ますが、これは Firefox を除くすべてのブラウザーでのみ機能します。

    ただし、Firefox ではテーブル自体の相対的な配置が許可されposition:relative;ているため、テーブル div を設定し、テーブル全体の寸法に応じてスクロール ボックスのサイズと位置を設定するのがコツです。

ご想像のとおり、純粋な CSS ソリューションを使用したい場合、これにはいくつかの制限がありますが、とにかくいくつかあります。それとは別に、JavaScript で問題を解決するエレガントな方法もあり、それもコードに含めました。

以下のコードには、問題を解決する 3 つの方法が含まれています。2 つは純粋な CSS ソリューションで、1 つは JavaScript を使用します。コードをできるだけ変更しないように努め、すべての変更にコメントを付けました。まだ質問がある場合は、コメントを残してください。

<!DOCTYPE html>
<html>
  <head>
    <style>
      html, body {
        margin: 0;
        padding: 0;
        height: 100%;
      }

      .l-fit-height {
        display: table;
        height: 100%;
        /* NOTE Use the table as refernece for absolute positioning. This */
        /*      is the only place where Firefox accepts the position property */
        /*      within a table. */
        position: relative;
      }

      .l-fit-height > * {
        display: table-row;
        height: 1px;
        background-color: red;
      }

      .l-fit-height-expanded {
        /* NOTE Set the important flag to override the generic setting */
        height: auto !important;
        background-color: blue;
        display: table-row;
      }

      .l-scroll-content {
        /* NOTE We will set the height attribute later */
        /* height: 100%; */
        overflow-y: auto;
        /* INFO Prevent the table from growing in height */
        position: absolute;
        /* INFO The content should span the full width */
        width: 100%;
      }

      /* INFO Since Firefox only allows absolute positioning relative to the */
      /*      whole table, setting the correct height is a bit tricky. I've */
      /*      found two pure CSS solutions which work, but both have their */
      /*      glitches. If JavaScript is ok for you, there's another solution */
      /*      which I would recommend. */

      /* INFO Example for percentage height footer and header. This sometimes */
      /*      leaves one or two pixels between the scroll-box and the footer. */
      /* REMOVE THIS LINE TO ACTIVATE
      .l-fit-height > * {
        height: 20%;
      }
      .l-scroll-content {
        height: 60% !important;
      }
      /**/

      /* INFO Example for fixed height footer and header. Unfortunately this */
      /*      makes the header and footer-content unclickable, but I'm quite */
      /*      sure this could be solved by setting a z-index. */
      /* REMOVE THIS LINE TO ACTIVATE
      .l-fit-height > * {
         height: 40px;
      }
      .l-scroll-content {
         -moz-box-sizing: border-box;
         -webkit-box-sizing: border-box;
         box-sizing: border-box;
         height: 100%;
         border-top: 40px solid transparent;
         margin-top: -40px;
         border-bottom: 40px solid transparent;
         margin-bottom: -40px;
      }
      /**/
    </style>
    <script type="text/javascript">
        // INFO Example how to fix the problem with JavaScript. This works for
        //      all kinds of heights (flexible, percentage and fixed) and has no
        //      issues except for the need of JavaScript to see a correctly
        //      layouted page.
        //* REMOVE THE FIRST SLASH TO DEACTIVATE
        function fixScrollContentHeight() {
            var nodes = document.getElementsByClassName('l-scroll-content');
            for (var i = 0; i < nodes.length; i++)
                nodes[i].style.height = nodes[i].parentNode.offsetHeight+'px';
        }
        window.onload = fixScrollContentHeight;
        window.onresize = fixScrollContentHeight;
        //*/
    </script>
  </head>
  <body>
    <div class="l-fit-height">
      <section>
        Header
      </section>
      <section class="l-fit-height-expanded">
        <div class="l-scroll-content">
          <p>Foo</p>
          <p>Foo</p>
          <p>Foo</p>
          <p>Foo</p>
          <p>Foo</p>
          <p>Foo</p>
          <p>Foo</p>
          <p>Foo</p>
          <p>Foo</p>
          <p>Foo</p>
          <p>Foo</p>
          <p>Foo</p>
          <p>Foo</p>
          <p>Foo</p>
          <p>Foo</p>
        </div>
      </section>
      <section>
        Footer
      </section>
    </div>
  </body>
</html>

PS: IE で自分のコードをテストできませんでしたが、IE でも動作するはずです。

于 2012-09-27T10:35:30.637 に答える
0

ここからFirefoxにdivの自動水平スコルバーを表示させる方法は?

Firefoxはoverflow-xとoverflow-yを認識しません。

代わりにoverflow:-moz-scrollbars-horizontal;またはoverflow:-moz-scrollbars-vertical;

于 2012-09-26T16:08:05.493 に答える
-1

私の更新を確認してください。

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Untitled Document</title>
<style>

html, body {
height:99.9%;
margin:0;
padding:0;
}

#wrapper {
    margin: auto;
    overflow: hidden;
    position: relative;
    width: 99.9%;
}

#main {
    margin-bottom: 67px;
    margin-top: 77px;
    overflow: auto;
    padding-bottom: 80px;
}

#footer {
    bottom: 0;
    clear: both !important;
    height: 75px !important;
    margin-top: -68px !important;
    position: fixed !important;
}

#header {
    background: none repeat scroll 0 0 #FFFFFF;
    border: 1px solid #000000;
    height: 75px !important;
    margin-top: -77px;
    overflow: hidden;
    position: fixed;
    width: 100%;
}
</style>

</head>

<body>

     <div id="wrapper">
         <div id="main">
            <div id="header">header contents goes here</div>

            <div id="content">
                main contents
            </div>
         </div>
     </div>
     <div id="footer" style="width:99.9%; margin:auto; border:solid 1px #666; ">
      Footer content goes here
     </div>

</body>
</html>
于 2012-09-26T16:19:31.937 に答える