Как прижать футер к низу страницы (руководство к действию)

26 сентября 2010. Рубрики: Рабочие заметки; автор — Юлия Панина aka Княгиня.

Мой любимый рецепт, которым я пользуюсь, как бы не соврать, лет пять. Абсолютно кроссбраузерный. Краткое изложение рецепта:

html:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>…</head>
<body>
  <div id="header">…</div>
  <div id="wrapper">…</div>
  <div id="footer">…</div>
</body>
</html>
css:
*{
  margin:0;
  padding:0;
  border-collapse:collapse;
}
html{
  height:100%;
}
body{
  position:relative;
  min-height:100%;
}
#wrapper{
  padding-bottom:70px;
}
#footer{
  position:absolute;
  bottom:0;
  left:0;
  z-index:500;
  width:100%;
  height:50px;
  overflow:hidden;
}

Подробное изложение

Первое и главное условие, позволяющее прибить футер, он же подвал сайта к низу страницы — использование правильного доктайпа (смотрим заметку о доктайпе). Если вы хотите обойтись без него, мы с вами друг друга не поймём, а рецепт вам не поможет.

Второе: подвал страницы является отдельным блоком. Никаких лишних обёрток между футером и боди быть не должно. Возможные варианты размётки:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>…</head>
<body>
  <div id="header">…</div>
  <div id="wrapper">…</div>
  <div id="footer">…</div>
</body>
</html>

или

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>…</head>
<body>
  <div id="header">…</div>
  <table id="wrapper">
    <tr>
      <td id="left">…</td>
      <td id="content">…</td>
      <td id="right">…</td>
    </tr>
  </table>
  <div id="footer">…</div>
</body>
</html>

Третье условие: высота футера будет фиксированной. То есть, не рассчитанной на добавление неограниченного количества контента. Впрочем, я не знаю дизайнов, предполагающих свободное наполнение футера чем попало.

Задача первая: обнуляем все лишние поля и отступы:

*{
  margin:0;
  padding:0;
  border-collapse:collapse;
}

Если это противоречит вашим принципам, достаточно обнулить вертикальные поля и отступы для html и body.

Задача вторая: прижать к низу футер нам позволит абсолютное позиционирование. Однако абсолютно позиционированный элемент всегда позиционируется относительно своего контейнера, которым является (внимание!) ближайший предок, у которого свойство position отлично от static. Если такого предка нет, элемент позиционируется относительно окна, создавая неопытным верстальщикам проблему в виде прилипания поперёк страницы. Чтобы футер признал body своим контейнером и прилип к низу страницы, а не окна, делаем боди относительно позиционированным:

body{
  position:relative;
}

Теперь надо задать высоту body таким образом, чтобы при малом количестве содержания body вытягивался по высоте окна, а при большом свободно растягивался за его пределы. Сначала задаём высоту корневому элементу:

html{
  height:100%;
}

Без прямого указания высоты элемента html невозможно управлять высотой его дочернего элемента body. Теперь высота html определяется высотой окна браузера. Далее задаём минимальную высоту body:

body{
  min-height:100%;
}

Получаем то, что хотели: мало содержания — body тянется по окну, много содержания — растягивается свободно докуда надо. Тем, кто поддерживает IE6, придётся отдельно указать height:100%; только для него одного — в общий файл стилей это определение попасть не должно: body станет обрезаться по высоте окна.

Теперь, когда контейнер (дом родной) готов, можно заняться самим футером. Его позиционируем и прижимаем к нижней и к левой границам:

#footer{
  position:absolute;
  bottom:0;
  left:0;
}

Поскольку абсолютно позиционированные элементы по умолчанию имеют ширину по содержанию, назначаем ширину во всё окно (а высоту какую нам надо):

#footer{
  width:100%;
  height:50px;
}

Боковых padding у футера быть не должно — они добавятся к стопроцентной ширине и подвал вылезет за пределы экрана. Отступы надо будет задать дочерним элементам футера.

Чтобы подвал впоследствии не перекрылся бекграундом основной области, зададим подвалу z-индекс побольше (гарантируем, что он всегда будет лежать «выше» и «ближе» к зрителю, чем прочие элементы страницы):

#footer{
  z-index:500;
}

И для борьбы со случайными глюками в IE7, а также против распяливания подвала лишним содержанием добавим правило:

#footer{
  overflow:hidden;
}

Подвал прижат. Осталось «оттолкнуть» от него содержание основной области. Зададим ей нижний отступ немного больше высоты подвала:

div#wrapper{
  padding-bottom:70px;
}

Если основная область размечена трёхячеечной таблицей, то отступ надо задать всем трём ячейкам:

td#left, td#content, td#right{
  padding-bottom:70px;
}

Всё! Схема работает — футер всегда внизу страницы, и никаких излишков, вылезающих за пределы окна при малом содержании. Применено в этом блоге и на многом множестве свёрстанных мной сайтов.

Отзывы (66) на «Как прижать футер к низу страницы (руководство к действию)»
  1. Serge

    «отступ надо задать всем трём ячейкам:» — а не проще задать нижний марджин всей таблице?

    Ответить на этот комментарий
    • Княгиня (650 комментариев)

      Это не во всех браузерах работает. Кажется, в ие8 не действует. Если бы после таблицы был блок в нормальном потоке, то перед ним было бы поле-margin, но когда таблица упирается в нижнюю кромку body, margin не действует, по крайней мере, видимым образом не действует.

      Ответить на этот комментарий
  2. JeckyChan

    А почему нельзя прижать с помощью position fixed? Его только шестой осёл не понимал, а в нормальных браузерах работает. И никаких проблем с подвисанием.

    Ответить на этот комментарий
    • Княгиня (650 комментариев)

      Это совсем другая задача, которая требует другого дизайна. Обычный подвал должен быть прижат внизу всей страницы, визуально он часто связан с дизайном так, что не разорвёшь, и никакого «скольжения» по странице не допускает. Фиксированно можно позиционировать специальные панели и меню, которые задуманы «висящими» над сайтом.

      Потом, подвал может быть весьма высоким — и что, какую часть окна он займёт? А если всё его полезное содержание — копирайты создателей, то зачем его вешать фикседом? Нет, обычный футер, если дизайном не оговорено особо, надо прижимать к низу абсолютным позиционированием. Фиксированное — для других задач.

      Ответить на этот комментарий
  3. Дмитрий (1 комментарий)

    Спасибо за ваш метод. Но у меня он не работает, когда высота футера больше размера окна браузера. Как мне быть в такой случаи?

    Ответить на этот комментарий
    • Княгиня (650 комментариев)

      А как именно «не работает»? Строго говоря, футер такого размера прижимать и не требуется: у вас не будет случая, когда высота страницы короче высоты окна.

      Ответить на этот комментарий
  4. Лев (3 комментария)

    Прочитал, ничего не понял :). Давно уже хочу прижать футер к низу страницы в своем блоге, но не знаю, как это правильно сделать :(. Может, подскажете? Буду премного благодарен. Сайт: eb-school.ru , сделан на Blogger.

    Ответить на этот комментарий
    • Княгиня (650 комментариев)

      А как вы собираетесь узнать мой ответ, если не подписались на комментарии?

      Чтобы совсем ничего не понять, надо надо совсем не знать html и css. Если вы совсем не знаете, то я вам не помогу. Если вы не поняли что-то конкретное, то опишите, что именно. Но сначала попробуйте сверстать по моему рецепту на локале тестовый шаблон. Обычно это помогает.

      Ответить на этот комментарий
      • Лев (3 комментария)

        Я подписался на комментарии. У меня есть блог на Blogger, есть полный код шаблона в HTML. Я не понял, куда там нужно вставлять указанный код? :(. В частности мне непонятно, куда вставлять CSS. Небольшие изменения я делал, но тут много всего надо перекроить. Может я на почту скину код шаблона, посмотрите? Вы правы я в html и css плохо соображаю :(.

        Ответить на этот комментарий
        • Княгиня (650 комментариев)

          А, вот оно что. Мой рецепт не предназначен для того, чтобы его «куда-то вставить». Это базовая схема вёрстки будущего шаблона страницы, который потом будет посажен на движок, будь то Блоггер или любая cms.

          Вы сначала попробуйте создать файл html на своём компьютере и разметить его по моему рецепту, подключив описанный css. (Естественно, в колонках и подвале напишите какой-нибудь текст для наглядности.) Когда начнёт получаться, возьмите шаблон с Блоггера, найдите в нём колонки (или блок основной области) и подвал и перестройте по моему образцу (естественно, сначала всё тестим на локале и не забываем делать бекап).

          Насчёт подписки на комментарии — это мини-тест на спамера.

          Ответить на этот комментарий
          • Лев (3 комментария)

            ясно :). Ладно, попробую позже разобраться. Как-то сложно все. В любом случае спасибо за рецепт, доктор ;)).

            Ответить на этот комментарий
            • Княгиня (650 комментариев)

              Как говорил мой отец, будет просто, как попробуешь раз до ста. Другого пока не придумано. ;)

              Ответить на этот комментарий
  5. Luigi Epazzo (1 комментарий)

    интересный метод. в одной из работ использовал нечто похожее, только с применением «блока-посредника». приведённый способ кажется проще, надо будет опробовать :)

    Ответить на этот комментарий
  6. Александр (1 комментарий)

    А я решил этот вопрос с пижатием футера совершенно проще — написал javascript код, который сам сделает всю грязгую работу с прижиманием к низу футера.

    Принцип работы кода совершенно отличается от работы CSS способом.

    Ответить на этот комментарий
    • Княгиня (650 комментариев)

      Всё, что делается скриптом, не может называться словом «проще».

      Ответить на этот комментарий
    • Дмитрий (5 комментариев)

      Когда есть решение на CSS, решение на javascript априори хуже.

      Ответить на этот комментарий
    • Master-It (9 комментариев)

      Это одна из общепринятых норм (нормальной) CSS верстки.
      Если же используется JavaScript для реализации этой задачи, то необходимо помнить о том, что у пользователя он вообще может быть отключен!
      И на что тогда будет похож ваш сайт?
      Лично я Javascript использую в основном для редиректа, или дополнительной проверки корректности вводимых пользователем данных, на стороне клиента, для того, чтобы лишний раз не нагружать сервер PHP сценариями.

      Ответить на этот комментарий
  7. Иван

    В опере 11.11 не работает

    Ответить на этот комментарий
    • Княгиня (650 комментариев)

      У меня стоит опера 11.11. В ней работает. Проверьте код, который пишете. Обратите внимание, как задаётся высота для body и html.

      Ответить на этот комментарий

Есть что сказать? Не молчим!

Используйте теги: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" code=""> <ul> <li> <ol> .

Комментарии короче 200 символов публикуются без активной ссылки. Пробелы не учитываются.

Ссылки с комментариев dofollow. Ознакомьтесь, пожалуйста, с правилами dofollow-комментирования. Кто не читает, тот сам себе враг.