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更改为display: table-cellWebKit 和 Gecko 会表现出相同的行为或忽略溢出。

如果display: block使用,则 WebKit 会提供所需的行为(滚动条和页脚保留在视口底部),但 Firefox 拒绝添加滚动条,而是将页脚推离屏幕底部(视口上的滚动条 - 而不是中间内容)。

我还开了一张bugzilla 票

4

4 回答 4

13

我发现有几个额外的 div 和一个关键display: inline-block是可以在 Firefox 中使用 Torben 提到的绝对定位技巧。这意味着完全灵活的页眉和页脚可以作为纯 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

我认为您在这里遇到了两个综合问题:

  1. 表格尺寸并不像您对普通 div 所期望的那样固定。表格通常随内容一起增长,如果内容太大,则不太关心其高度属性。

    因此,您必须通过绝对定位来将滚动框的内容从内容大小计算中排除。现在剩下要做的就是设置滚动框的位置和大小以填充展开的表格行的完整空间。然而,这引发了另一个问题:

  2. 直接的解决方案是position:relative;为表格行和width:100%;height:100%;滚动框设置,但这不起作用,因为大多数浏览器忽略了表格行的位置属性。您可以在表格行和滚动框之间插入另一个 div display:table-cell;position:relative;,但这仅适用于除 Firefox 之外的所有浏览器,因为 Firefox 不允许在表格中进行任何相对定位。

    然而,Firefox 允许对表格本身进行相对定位,因此诀窍是设置position:relative;table-div 并根据整个表格的尺寸设置滚动框的大小和位置。

如您所料,如果您想使用纯 CSS 解决方案,这会带来一些限制,但还是有一些限制。除此之外,还有一种用 JavaScript 解决问题的优雅方法,我也将其包含在代码中。

下面的代码包括解决问题的三种方法。两种是纯 CSS 解决方案,一种是使用 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 测试我的代码,但我认为它也应该在那里工作。

于 2012-09-27T10:35:30.637 回答
0

从这里如何让firefox显示一个div的自动水平scollbar?

Firefox 无法识别溢出-x 和溢出-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 回答