С каждым годом мониторы становятся всё больше и больше; как следствие, растёт и разрешение экрана. И страницы с небольшим количеством контента на таких мониторах смотрятся некрасиво — особенно, когда нижний колонтитул (aka подвал aka footer) плавает где-то в верхней части экрана
Многие сайты решают эту проблему при помощи табличной верстки (<table height="100%">) с теми или иными вариациями. Но это не наш метод, ибо это противоречит WCAG 1.0. Поэтому для решения задачи будем использовать семантически корректную разметку и CSS.
На первый взгляд кажется, что прижать футер (так вот будем величать нижний колонтитул для краткости) к нижнему краю окна очень просто: #footer {position: absolute; bottom: 0;}. Но есть один маленький нюанс: если высота содержимого страницы (основного контента) превышает высоту окна, то футер будет прижат к нижнему краю окна, а не контента. Иными словами, футер будет перекрывать какую-то часть контента.
Очень часто проблему позиционирования блоков решают (к сожалению!) при помощи JavaScript (например, вычисляется высота контента и футер абсолютно позиционируется под контент; есть и другие способы).
Начнём с разметки:
<h1 id="#header">Header</h1>
<div id="#content">
<p>Lorem ipsum dolor sit amet…</p>
</div>
<div id="#footer">Footer</div>
</body>
Для начала нужно указать, что минимальная высота body должна быть не менее 100%:
height: auto;
min-height: 100%;
margin: 0;
padding: 0;
}
Есть два "но":
- Если высота задаётся в процентах (как в данном случае), в режиме соответствия стандартам (когда присутствует нормальный
!DOCTYPE), высота рассчитывается в процентах от высоты родительского элемента; - Internet Explorer 6 имеет трудности с пониманием
min-height.
Первое "но" обходится довольно просто: для body родительским элементом является html, поэтому html и задаем высоту в 100% (html является корнем дерева, поэтому его процентная высота будет вычисляться от высоты окна).
Со вторым "но" особых проблем тоже не вознкает: хоть IE6 и не поддерживает min-height/min-width, зато он интерпретирует height/width как min-height/min-width
Удобно, не правда ли?
Получаем:
margin: 0;
padding: 0;
border: 0;
width: 100%;
}
html {
height: 100%;
overflow: auto; /* Иначе у IE6 начинаются проблемки с вертикальной полосой прокрутки */
}
* html body {
height: 100%; /* IE 6 */
}
html > body { /* Все остальные */
min-height: 100%;
height: auto;
}
Теперь осталось составить стили для заголовка, основного блока и футера.
Есть один маленький нюанс: так как мы хотим прижать футер к самому нижнему краю экрана, нам нужно знать заранее его (футера) высоту. Обычно это не является проблемой, так как в футере содержатся копирайты и несколько ссылок, и размер футера обычно заранее известен. Для заголовка высота не имеет значения (данный макет вытерпит любую разумную высоту
), но для удобства мы её всё же зададим.
position: relative; /* Так как #footer мы планируем позиционировать относительно body */
}
#header {
margin: 0;
padding: 0;
height: 3em;
}
#footer {
position: absolute;
left: 0;
bottom: 0;
height: 2em;
padding: .5em 0;
width: 100%;
}
#content {
width: 100%;
padding-top: 1px; /* чтобы предотвратить "схлопывание" границ, если у первого дочернего элемента не нулевой margin-top */
padding-bottom: 4em /* #footer.offsetHeight + #content.desired-paddingBottom */
}
Под offsetHeight мы здесь понимаем сумму высоты элемента, верхнего и нижнего отступов (padding), верхней и нижней границ (margin) и верхнего и нижнего бордюров (border).
desired-paddingBottom — желаемый нижний отступ для контента (т.е. отступ, который будет присутствовать всегда).
Маленькое замечание: если текста на странице мало (т.е. блок #content имеет маленькую высоту), то его (блока) размер будет больше на #footer.offsetHeight (это может быть важно при задании фоновых картинок). При этом при увеличении блока #content #footer в конце концов "съест" это лишнее пространство.
Собственно, всё.
В ситуации, когда нужно, чтобы все пространство от заголовка до подвала было одного цвета, добавляется еще один контейнер и немного меняется CSS:
<head><title>Title</title></head>
<body>
<div id="container">
<h1 id="header">Header</h1>
<div id="content">Lorem ipsum</div>
<div id="footer">Footer</div>
</div>
</body>
</html>
margin: 0;
padding: 0;
border: 0;
}
html {
overflow: auto;
}
html, body {
height: 100%; /* все предки #container должны иметь высоту */
}
html > body #container {
height: auto;
min-height: 100%;
}
* html #container {
height: 100%;
}
#container {
position: relative;
}
#header {
height: 1em;
}
#footer {
height: 1em;
position: absolute;
left: 0;
bottom: 0;
}
#content {
padding-bottom: 1.1em;
}
Или можно сделать проще — задать фон body и убрать фон #content. Будет работать, если у #header/#footer нет лишних границ.
Dictum sapienti sat est…

Меня зовут Владимир, я программист-фрилансер, специализирующийся на Web-программировании и програмировании под Linux.
По совместительству занимаюсь администрированием LAMP/LNMP-серверов и техническим переводом.





По последним данным (с тех пор, как у меня появился Konqueror), правило
html { overflow: auto; }нужно делать видимым только для IE. В противном случае Konqueror 3.5.9 (на K4 еще не тестировал) некорректно отображает страницу (появляется еще одна вертикальная полоса прокрутки по высоте окна (последствияheight: auto; min-height: 100%) , а “основная” полоса прокрутки не скрывается, а работает так, как если бы контент отображался по всей высоте).А что делать, если все элементы страницы имеют абсолютное позиционирование? Тогда ваш способ не работает.
Роман, этот как? Можно прмер, пожалуйста?
Вообще, если у Вас #content спозиционирован абсолютно, и при этом Вы не задали ему высоту, то, возможно, Вам стоит подумать о рефакторинге дизайна
На мой взгляд, использование абсолютного позиционирования везде, где только можно — это не есть хорошо.
Хочу предложить вам не плохой способ для прижатия футера. Он находиться здесь, там есть примеры и коментарии к коду.
При добавлении во второй пример текста (так чтобы он занимал больше видимой области экрана) нижний колонтитул (aka подвал aka footer) плавает где-то в верхней части экрана
Firefox 2.0.0.14
Сергей, Вы первый, кто это заметил, спасибо. Причина заключается в моей невнимательности — я забыл добавить
position: relativeв объявление#container(29 строка). А в самой статье разметка правильная.я вродибы хтмл харашо знаю, но и автор вроди как не глупый, обьясните что за * {…} и html > body. интерисует звездочка (и к чему тогда стиль применяется) и знак “>” что значит?
также скажите или дайте линку, как поступить в этой ситуации для табличного способа
*применяется к любому селектору.Знак > означает, что, например, в записи
a > b,bдолжен быть непосредственным потомкомa.Я бы порекомендовал к прочтению следующие статьи: