Получите div, чтобы принять 100% рост, минус фиксированная высота и нижний колонтитул

Из моего исследования это, кажется, абсолютно классический вопрос CSS, но я не могу найти окончательный ответ - так StackOverflow это.

Как настроить содержание div на 100% высоты тела, минус высота, занимаемая заголовком и нижним колонтитулом с фиксированной высотой?

<body>
  <header>title etc</header>
  <div id="content">body content</div>
  <footer>copyright etc</footer>
</body>

//CSS
html, body { 
  height: 100%;
}
header { 
  height: 50px;
}
footer { 
  height: 50px;
}
#content { 
  height: 100% of the body height, minus header & footer
}

Я хотел бы использовать чистый CSS, а для ответа - пуленепробиваемый в браузерах.

Ответ 1

эта версия будет работать во всех последних браузерах и ie8, если у вас есть modernizr script (если не просто изменить header и footer на div s):

Fiddle

html,
body {
  min-height: 100%;
  padding: 0;
  margin: 0;
}

#wrapper {
  padding: 50px 0;
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
}

#content {
  min-height: 100%;
  background-color: green;
}

header {
  margin-top: -50px;
  height: 50px;
  background-color: red;
}

footer {
  margin-bottom: -50px;
  height: 50px;
  background-color: red;
}

p {
  margin: 0;
  padding: 0 0 1em 0;
}
<div id="wrapper">
  <header>dfs</header>
  <div id="content">
  </div>
  <footer>sdf</footer>
</div>

Ответ 2

Насколько это не кросс-браузерное решение, вы можете использовать calc(expression) для достижения этого.

html, body { 
 height: 100%;
}
header {        
 height: 50px;
 background-color: tomato
}

#content { 
 height: -moz-calc(100% - 100px); /* Firefox */
 height: -webkit-calc(100% - 100px); /* Chrome, Safari */
 height: calc(100% - 100px); /* IE9+ and future browsers */
 background-color: yellow 
}
footer { 
 height: 50px;
 background-color: grey;
}

Пример в JsFiddle

Если вы хотите узнать больше о calc(expression), вам лучше посетить этот сайт.

Ответ 3

Это все-таки показалось лучшим результатом Google, когда я пытался найти ответ на этот вопрос. Мне не нужно было поддерживать старые браузеры в моем проекте, и я чувствую, что нашел лучшее, более простое решение в flex-box. Ниже приведен фрагмент CSS ниже.

Я также показал, как сделать основной контент прокручиваемым, если высота экрана слишком мала.

html,
body {
  height: 100%;
}
body {
  display: flex;
  flex-direction: column;
}
header {
  min-height: 60px;
}
main {
  flex-grow: 1;
  overflow: auto;
}
footer {
  min-height: 30px;
}
<body style="margin: 0px; font-family: Helvetica; font-size: 18px;">
  <header style="background-color: lightsteelblue; padding: 2px;">Hello</header>
  <main style="overflow: auto; background-color: lightgrey; padding: 2px;">
    <article style="height: 400px;">
      Goodbye
    </article>
  </main>
  <footer style="background-color: lightsteelblue; padding: 2px;">I don't know why you say, "Goodbye"; I say, "Hello."</footer>
</body>

Ответ 4

Новый, современный способ сделать это - рассчитать вертикальную высоту, вычитая высоту как заголовка, так и нижнего колонтитула с вертикальной высоты окна просмотра.

//CSS
header { 
  height: 50px;
}
footer { 
  height: 50px;
}
#content { 
  height: calc(100vh - 50px - 50px);
}

Ответ 5

Вы можете использовать атрибут css Размер окна.

#content { 
    height: 100%;
    -webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */
    -moz-box-sizing: border-box;    /* Firefox, other Gecko */
    box-sizing: border-box;         /* Opera/IE 8+ */
    padding-top: 50px;
    margin-top: -50px;
    padding-bottom: 50px;
    margin-bottom: -50px;
}

Смотрите JsFiddle.

Ответ 6

Попытка рассчитать верхний и нижний колонтитулы плоха:( Дизайн должен быть простым, самоочевидным. Простое вычисление просто... нелегко. Нелегко для человека и немного сложно на машинах.

То, что вы ищете, является подмножеством проекта Holy Grail.

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

<!DOCTYPE html>
<html style="height: 100%">
  <head>
    <meta charset=utf-8 />
    <title>Holy Grail</title>
    <!-- Reset browser defaults -->
    <link rel="stylesheet" href="reset.css">
  </head>
  <body style="display: flex; height: 100%; flex-direction: column">
    <div>HEADER<br/>------------
    </div>
    <!-- No need for 'flex-direction: row' because it the default value -->
    <div style="display: flex; flex: 1">
      <div>NAV|</div>
      <div style="flex: 1; overflow: auto">
        CONTENT - START<br/>
        <script>
        for (var i=0 ; i<1000 ; ++i) {
          document.write(" Very long content!");
        }
        </script>
        <br/>CONTENT - END
      </div>
      <div>|SIDE</div>
    </div>
    <div>------------<br/>FOOTER</div>
  </body>
</html>

Ответ 7

На этот вопрос довольно хорошо ответил, но я беру на себя смелость добавить javascript-решение. Просто дайте элементу, что вы хотите "развернуть" id footerspacerdiv, и этот фрагмент javascript расширит этот div до тех пор, пока страница не займет всю высоту окна браузера.

Он работает на основе наблюдения, что, когда страница меньше, чем полная высота окна браузера, document.body.scrollHeight равно document.body.clientHeight. Цикл while увеличивает высоту footerspacerdiv, пока document.body.scrollHeight больше, чем document.body.clientHeight. На данный момент footerspacerdiv будет на самом деле иметь один пиксель слишком высокий, а браузер отобразит вертикальную полосу прокрутки. Таким образом, последняя строка script уменьшает высоту footerspacerdiv на один пиксель, чтобы высота страницы была точно высотой окна браузера.

Поместив footerspacerdiv чуть выше "нижнего колонтитула" страницы, этот script можно использовать для "нажатия нижнего колонтитула вниз" в нижнюю часть страницы, так что на коротких страницах нижний колонтитул заподлицо с в нижней части окна браузера.

<script>    
//expand footerspacer div so that footer goes to bottom of page on short pages        
  var objSpacerDiv=document.getElementById('footerspacer');          
  var bresize=0;   

  while(document.body.scrollHeight<=document.body.clientHeight) {
    objSpacerDiv.style.height=(objSpacerDiv.clientHeight+1)+"px";
    bresize=1;
  }             
  if(bresize) { objSpacerDiv.style.height=(objSpacerDiv.clientHeight-1)+"px"; }               
 </script>

Ответ 8

Здесь есть решение, которое не использует отрицательные поля или calc. Запустите снимок ниже, чтобы увидеть окончательный результат.

Объяснение

Мы даем заголовку, а нижний колонтитул - фиксированной высотой 30px и позиционируем их абсолютно сверху и снизу соответственно. Чтобы предотвратить падение содержимого, мы используем два класса: below-header и above-footer, чтобы заполнить div сверху и снизу с помощью 30px.

Все содержимое обернуто в div position: relative, так что верхний и нижний колонтитулы верхнего и нижнего уровня содержимого, а не окна.

Мы используем классы fit-to-parent и min-fit-to-parent, чтобы содержимое заполнило страницу. Это дает нам липкий нижний колонтитул, который по крайней мере такой же низкий, как и окно, но скрыт, если содержимое больше, чем окно.

Внутри верхнего и нижнего колонтитула мы используем стили display: table и display: table-cell, чтобы дать верхнему и нижнему колонтитулам некоторые вертикальные отступы, не нарушая качество усадки на странице. (Предоставление им реального дополнения может привести к тому, что общая высота страницы будет больше, чем 100%, что приведет к появлению полосы прокрутки, когда она действительно не нужна.)

.fit-parent {
    height: 100%;
    margin: 0;
    padding: 0;
}
.min-fit-parent {
    min-height: 100%;
    margin: 0;
    padding: 0;
}
.below-header {
    padding-top: 30px;
}
.above-footer {
    padding-bottom: 30px;
}
.header {
    position: absolute;
    top: 0;
    height: 30px;
    width: 100%;
}
.footer {
    position: absolute;
    bottom: 0;
    height: 30px;
    width: 100%;
}

/* helper classes */

.padding-lr-small {
    padding: 0 5px;
}
.relative {
    position: relative;
}
.auto-scroll {
  overflow: auto;
}
/* these two classes work together to create vertical centering */
.valign-outer {
    display: table;
}
.valign-inner {
    display: table-cell;
    vertical-align: middle;
}
<html class='fit-parent'>
  <body class='fit-parent'>
<div class='min-fit-parent auto-scroll relative' style='background-color: lightblue'>
<div class='header valign-outer' style='background-color: black; color: white;'>
        <div class='valign-inner padding-lr-small'>
            My webpage
        </div>
    </div>
    <div class='fit-parent above-footer below-header'>
        <div class='fit-parent' id='main-inner'>
          Lorem ipsum doloris finding dory Lorem ipsum doloris finding
          dory Lorem ipsum doloris finding dory Lorem ipsum doloris
          finding dory Lorem ipsum doloris finding dory Lorem ipsum
          doloris finding dory Lorem ipsum doloris finding dory Lorem
          ipsum doloris finding dory Lorem ipsum doloris finding dory
          Lorem ipsum doloris finding dory Lorem ipsum doloris finding
          dory Lorem ipsum doloris finding dory Lorem ipsum doloris
          finding dory Lorem ipsum doloris finding dory Lorem ipsum
          doloris finding dory Lorem ipsum doloris finding dory Lorem
          ipsum doloris finding dory Lorem ipsum doloris finding dory
          Lorem ipsum doloris finding dory Lorem ipsum doloris finding
          dory Lorem ipsum doloris finding dory Lorem ipsum doloris
          finding dory Lorem ipsum doloris finding dory Lorem ipsum
          doloris finding dory Lorem ipsum doloris finding dory Lorem
          ipsum doloris finding dory Lorem ipsum doloris finding dory
          Lorem ipsum doloris finding dory Lorem ipsum doloris finding
          dory Lorem ipsum doloris finding dory Lorem ipsum doloris
          finding dory Lorem ipsum doloris finding dory Lorem ipsum
          doloris finding dory Lorem ipsum doloris finding dory Lorem
          ipsum doloris finding dory Lorem ipsum doloris finding dory
          Lorem ipsum doloris finding dory Lorem ipsum doloris finding
          dory Lorem ipsum doloris finding dory Lorem ipsum doloris
          finding dory Lorem ipsum doloris finding dory Lorem ipsum
          doloris finding dory Lorem ipsum doloris finding dory Lorem
          ipsum doloris finding dory Lorem ipsum doloris finding dory
          Lorem ipsum doloris finding dory Lorem ipsum doloris finding
          dory Lorem ipsum doloris finding dory Lorem ipsum doloris
          finding dory Lorem ipsum doloris finding dory Lorem ipsum
          doloris finding dory Lorem ipsum doloris finding dory Lorem
          ipsum doloris finding dory Lorem ipsum doloris finding dory
          Lorem ipsum doloris finding dory Lorem ipsum doloris finding
          dory Lorem ipsum doloris finding dory Lorem ipsum doloris
          finding dory Lorem ipsum doloris finding dory Lorem ipsum
          doloris finding dory Lorem ipsum doloris finding dory Lorem
          ipsum doloris finding dory Lorem ipsum doloris finding dory
        </div>
    </div>
    <div class='footer valign-outer' style='background-color: white'>
        <div class='valign-inner padding-lr-small'>
            &copy; 2005 Old Web Design
        </div>
    </div>
</div>
    </body>
  </html>