Как прижать подвал к низу страницы

Этот способ, использующий отрицательный отступ, описан на многих сайтах. Я хочу рассказать о некоторых неочевидных моментах и проблемах, которые могут возникнуть. Для начала нам нужны два блока: основной, в котором будет всё кроме подвала, и сам подвал.

<body>
<div class="page-wrapper">

</div>
<div class="page-footer">

</div>
</body>

Высота блока page-wrapper зависит от размера body, поэтому для html и body нужно обязательно задать высоту 100%, без неё подвал к низу не прижмётся. По этой же причине вокруг page-wrapper не должно быть других тегов.

У html и body по умолчанию есть отступы (margin и padding), которые добавляются к заданной высоте, отчего появляется ненужная полоса прокрутки. Эти отступы необходимо сбросить.

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

Растягиваем блок page-wrapper на всю высоту окна при помощи свойства min-height. Нужно использовать именно min-height, а не height, чтобы не ограничивать высоту блока на длинных страницах. В IE6 эти свойства работают неправильно, поэтому ему нужна обычная высота height, заданная с помощью конструкции * html, которую игнорируют другие браузеры.

Блок page-footer оказался за нижним краем окна, и нужно сдвинуть его вверх. Логичнее всего было бы использовать для этого отрицательный margin-top, но с ним в старых версиях IE подвал вообще перестанет отображаться. Поэтому нужно использовать отрицательный нижний отступ у блока page-wrapper. Величину отступа делаем равной высоте подвала (50px в этом примере).

.page-wrapper {
    min-height: 100%;
    margin-bottom: -50px;
}
* html .page-wrapper {
    height: 100%;
}

Теперь подвал закрывает собой нижнюю часть страницы, и на длинных страницах под ним скроется часть контента. Чтобы этого не произошло, нужен отступ внизу блока page-wrapper. Но padding использовать нельзя, так как он добавится к стопроцентной высоте. Поэтому добавляем пустой блок с высотой, равной высоте подвала. Вот что получилось в итоге:

<body>
<div class="page-wrapper">

<div class="page-buffer"></div>
</div>
<div class="page-footer">

</div>
</body>
html, body {
    height: 100%;
    margin: 0;
    padding: 0;
}
.page-wrapper {
    min-height: 100%;
    margin-bottom: -50px;
}
* html .page-wrapper {
    height: 100%;
}
.page-buffer {
    height: 50px;
}

Возможно, вам показалось странным то, что высота блока page-footer так и не задана. Дело в том, что высота подвала никак не влияет на его расположение и нужна только тогда, когда низ подвала должен точно совпадать с низом страницы. Например, если у подвала есть собственный фон.

Иногда после добавления на страницу других элементов появляется непонятная полоса прокрутки. Причина в том, что у верхнего элемента (чаще всего это заголовок или абзац текста) есть margin, выступающий за край блока page-wrapper. В статье Ивана Сагалаева про границы и отступы подробно рассматривается эта проблема и способы её решения. Проще всего избавиться от прокрутки, заменив margin этого верхнего элемента на padding.