Липкие гибкие нижние колонтитулы и заголовки CSS отлично работают в WebKit, но не в Gecko

Я пытаюсь построить макет, который позволяет гибкую высоту верхнего и нижнего колонтитула, с разделом в середине, потребляющим оставшееся пространство. Любое переполнение в середине должно давать полосу прокрутки только для этого среднего раздела.

у меня есть код, который отлично работает для 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-cell затем WebKit и Gecko демонстрируют одинаковое поведение или игнорируют переполнение.

если display: block используется тогда WebKit дает желаемое поведение (полоса прокрутки и нижний колонтитул остается внизу порта просмотра), но Firefox отказывается добавлять полосы прокрутки и вместо этого отталкивает нижний колонтитул от нижней части экрана (полоса прокрутки на порту просмотра - не среднее содержимое).

Я также открыл билет bugzilla

4 ответов


я обнаружил с парой дополнительных div и решающим display: inline-block можно использовать абсолютный трюк позиционирования Торбен упоминает, в 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>

надеюсь, что это помогает


Я думаю, что вы столкнулись с двумя комбинированными проблемами здесь:

  1. таблица-размеры не так фиксированы, как можно было бы ожидать от обычного div. Таблицы обычно растут с их содержимым и не заботятся об их свойстве высоты, если содержимое слишком велико.

    поэтому вы должны исключить содержимое окна прокрутки из расчета размера содержимого по положению его абсолютно. Все, что осталось сделать, это установить положение и размер окна прокрутки заполните все пространство развернутой строки таблицы. Однако возникает еще один вопрос:

  2. простым решением было бы установить position:relative; для таблицы-строка и width:100%;height:100%; для прокрутки, но это не сработает, потому что большинство браузеров игнорируют свойство position строк таблицы. Вы можете вставить другой div с display:table-cell;position:relative; между строкой таблицы и полем прокрутки, но это будет работать только для всех браузеров, кроме Firefox, так как Firefox не разрешает никаких относительных позиционирование внутри стола.

    Firefox, однако, позволяет относительное позиционирование для самой таблицы, поэтому трюк состоит в том, чтобы установить position:relative; для таблицы-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, но я думаю, что он тоже должен работать.


отсюда как заставить firefox показать автоматический горизонтальный scollbar для div?

Firefox не распознает overflow-x и overflow-y.

вместо того, чтобы использовать overflow:-moz-scrollbars-horizontal; или overflow:-moz-scrollbars-vertical;


пожалуйста, проверьте мои обновления.

<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>