Высота CSS: заполнение доступного пространства. Нет фиксированных высот

Итак, у меня есть следующая структура

<div id="container">
  <div id="head"></div>
  <div id="body"></div>
  <div id="foot"></div>
</div>

Я использую только идентификаторы для иллюстрации, поэтому это не обязательно для полной страницы.

Я хочу, чтобы мой контейнер указывал фиксированный размер... или относительный размер, не имеет значения. Позволяет ради аргумента сказать высоту 300px. Также overflow: hidden

Я хочу, чтобы head/foot расширялся, чтобы соответствовать содержимому внутри себя, поэтому height: auto достаточно.

Я хочу, чтобы тело расширялось, чтобы соответствовать оставшемуся пространству между головой и ногой. Если содержимое слишком велико, то прокрутите (overflow: auto).

height: 100% on #body не работает, потому что тогда он получает высоту 300 пикселей, как родительский, и выталкивает часть себя и нижний колонтитул из родителя.

Наличие головы и ноги position: absolute не работает, потому что, вынимая их из потока документа, содержимое #body скрыто. Чтобы исправить это, мы можем использовать padding-top/bottom, но мы не можем установить padding-top: xxpx/padding-bottom: xxpx на #body, потому что мы не знаем необходимую высоту головы/ноги, поэтому почему они height: auto.

Edit:

Я попытался преобразовать контейнер /head/body/foot в таблицу, где #body - height: 100%. Это отлично работает, за исключением того, что #body не будет прокручиваться, если содержимое становится слишком большим, вместо этого вся таблица расширяется, чтобы показать весь контент. Это не желаемое поведение, поскольку мне нужно #body прокручивать, а не #content или его родительский.

Любые предложения?

Ответы

Ответ 1

Единственное решение, которое сразу приходит в голову, это display: table-cell, хотя вы столкнулись с проблемой отсутствия поддержки в ie6 и ie7. Возможно, это правило для хороших браузеров и некоторый javascript для расчета различий в высоте, т.е.?

Изменить:

Здесь другой подход - использование jQuery для вычисления смещения. Имейте в виду, что это всего лишь быстрая и грязная попытка - она ​​должна быть проверена браузером, и вам понадобится простая обработка ошибок и т.д., Но это может быть отправной точкой.

Не уверен, что javascript - это то, как вы хотите идти, но я не вижу, как это делается в чистом css.

Я изменил идентификаторы на классы, чтобы вы могли иметь несколько полей fixedHeight:

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Untitled Document</title>
<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js'></script>

<script>

$(function() {   
   $(".fixedHeight").each(function() {
    var head = $(this).find(".head");
    var body = $(this).find(".body");
    var foot = $(this).find(".foot");   
    body.css("margin-top", head.height()).css("margin-bottom", foot.height());      
   });   
 });


</script>

<style>

.head {
    background-color: red;
    position: absolute;
    top: 0;
    width:100%;
}
.body {
    background-color: blue;
    color: white;
    overflow: auto;
    position:absolute;
    top:0;
    bottom:0;
    width:100%;
    margin:2.5em 0;
}
.foot {
    background-color: green;    
    position: absolute;
    bottom: 0;
    width:100%;
}
.container {
    background-color: #aaa; 
    border: 10px solid orange; 
    height: 300px; 
    width: 30%;
    position: absolute;
}


</style>

</head>

<body>

<div class="container fixedHeight">
  <div class="head">
    <h1>Header Content</h1>
  </div>
  <div class="body">
    <p>Body Content</p>
    <p>Body Content</p>
    <p>Body Content</p>
    <p>Body Content</p>
    <p>Body Content</p>
    <p>Body Content</p>
  </div>
  <div class="foot">
    <p>Footer Content</p>
  </div>
</div>


</body>
</html>

Ответ 2

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

#head {
    background-color: red;
    width: 100%;
    position: absolute;
    top: 0;
    left: 0;
}
#body {
    background-color: blue;
    color: white;
    border: 0 none;
    overflow: auto;
    height: 100%;
    padding-top: 2.5em;
    padding-bottom: 2.5em;
    box-sizing: border-box; 
    webkit-box-sizing: border-box; 
    -moz-box-sizing: border-box; 
}
#foot {
    background-color: green;
    width: 100%;
    position: absolute;
    bottom: 0;
    left: 0;
}
#container {
    background-color: #aaa; 
    border: 10px solid orange; 
    height: 300px; 
    width: 30%;
    overflow: show;
    position: absolute;
}

Это предполагает, что я могу рассчитать размеры #head и #foot и установить общий размер в дополнение к соответствующему местоположению #body. Это вытолкнет содержимое тела из области, которую занимает # head/# foot из-за их абсолютного позиционирования. Проблема здесь в том, что полоса прокрутки завершается частично срезанной сверху/снизу, потому что только содержимое сдвинуто, полоса прокрутки отсутствует.

Для ширины это не проблема.

Ответ 3

Недавно я столкнулся с этой проблемой в ситуации, когда я также не знал общую высоту контейнера (например, ответ Дмитрия предполагает). Пусть говорят, что высота #head и #foot равна 50 и 25 соответственно. Вот как я это решил:

#body {
  top: 25px;
  bottom: 50px;
  position: absolute;
}

#foot {
  position: absolute;
  bottom: 0;
}