Прижатый подвал, 5 способов

Крис Койер

Оригинал: css-tricks.com/couple-takes-sticky-footer
Перевод: Влад Мержевич

Краткая история, если хотите.

Смысл прижатого подвала заключается в том, что он «прилипает» к нижней части окна браузера. Но не всегда; если на странице достаточно содержимого, чтобы сдвинуть подвал вниз, то это будет сделано. Если содержимого на странице мало, тогда подвал прижмётся к нижней части окна браузера.

Прижатый подвал

Способ 1. Отрицательный margin-bottom для обёртки

Мы используем элемент .wrapper, в который помещаем всё, за исключением подвала. Затем устанавливаем для обёртки отрицательный margin-bottom, равный высоте подвала (пример 1).

Пример 1. Использование отрицательного margin-bottom

<!DOCTYPE html>
<html>
 <head>
  <meta charset="utf-8">
  <title>Подвал</title>
  <style>
   html, body {
    height: 100%;
    margin: 0;
   }
   .wrapper {
    min-height: 100%;
    /* Равно высоте подвала, */
    /* но с учётом margin-bottom у последнего дочернего элемента */
    margin-bottom: -50px;
   }
   .footer,
   .push {
    height: 50px;
   }
  </style>
 </head>
 <body>
  <div class="wrapper">
   Содержимое
   <div class="push"></div>
  </div>
  <footer class="footer">Подвал</footer>
 </body>
</html>

See the Pen Sticky Footer with Negative Margin 1 by Chris Coyier (@chriscoyier) on CodePen.

Нам потребуется дополнительный элемент внутри области содержимого (.push), он гарантирует что отрицательный margin не потянет подвал вверх и не перекроет собой содержимое. У .push, скорее всего, нет своего отрицательного margin, поэтому использование сдвига оправданно. Если это не так, то надо учесть значение в отрицательных margin и скоординировать два числа, чтобы выглядело хорошо.

Способ 2. Отрицательный margin-top у подвала

Данный метод не требует использования элемента .push, вместо этого нужно обернуть содержимое в дополнительный элемент, к которому следует применить соответствующий padding-bottom. Это делается, опять же, для того, чтобы избежать поднятия подвала над любым содержимым из-за отрицательного margin-top (пример 2).

Пример 2. Использование отрицательного margin-top

<!DOCTYPE html>
<html>
 <head>
  <meta charset="utf-8">
  <title>Подвал</title>
  <style>
   html, body {
    height: 100%;
    margin: 0;
   }
   .content {
    min-height: 100%;
   }
   .content-inside {
    padding: 20px;
    padding-bottom: 50px;
   }
   .footer {
    height: 50px;
    margin-top: -50px;
   }
  </style>
 </head>
 <body>
  <div class="content">
   <div class="content-inside">
    Содержимое
   </div>
  </div>
  <footer class="footer">Подвал</footer>
 </body>
</html>

See the Pen Sticky Footer with Negative Margins 2 by Chris Coyier (@chriscoyier) on CodePen.

Оба метода требуют дополнительных ненужных элементов HTML.

Способ 3. Использование calc() для уменьшения высоты обёртки

Один из способов не включать лишние элементы — это отрегулировать высоту обёртки с помощью calc() (пример 3). Тогда никакого перекрытия не будет, просто два элемента складываются друг с другом на общую высоту 100%.

Пример 3. Использование calc()

<!DOCTYPE html>
<html>
 <head>
  <meta charset="utf-8">
  <title>Подвал</title>
  <style>
   .content {
    min-height: calc(100vh - 70px);
   }
   .footer {
    height: 50px;
   }
  </style>
 </head>
 <body>
  <div class="content">
   Содержимое
  </div>
  <footer class="footer">Подвал</footer>
 </body>
</html>

See the Pen Sticky Footer with calc(); by Chris Coyier (@chriscoyier) on CodePen.

Обратите внимание на 70px в calc() и фиксированную высоту подвала 50px. Можно предположить, что в содержимом у последнего элемента margin-bottom равен 20px. Именно это значение нужно сложить с высотой подвала, чтобы полученную сумму вычесть из высоты области просмотра. И да, мы используем единицы vh как небольшой трюк, чтобы не устанавливать 100% у body и обёртки.

Способ 4. Использование флексбоксов

Большая проблема у перечисленных трёх методов состоит в том, что они требуют подвала фиксированной высоты, а это довольно неприятно. Содержимое может измениться. Элементы гибкие. Фиксированная высота — опасная территория. Использование флексбоксов для прижимания подвала не только не потребует дополнительных элементов, но и позволяет установить подвал произвольной высоты (пример 4).

Пример 4. Использование flex

<!DOCTYPE html>
<html>
 <head>
  <meta charset="utf-8">
  <title>Подвал</title>
  <style>
   html, body {
    height: 100%;
   }
   body {
    display: flex;
    flex-direction: column;
   }
   .content {
    flex: 1 0 auto;
   }
   .footer {
    flex-shrink: 0;
   }
  </style>
 </head>
 <body>
  <div class="content">
   Содержимое
  </div>
  <footer class="footer">Подвал</footer>
 </body>
</html>

See the Pen Sticky Footer with Flexbox by Chris Coyier (@chriscoyier) on CodePen.

Вы можете даже добавить заголовок выше или ниже материала. Вот пара хитростей.

  • flex: 1 для дочернего элемента, который будет расти для заполнения пространства (содержимое в нашем случае).
  • или margin-top: auto, чтобы сдвинуть дочерний элемент от соседа (или другой margin, в зависимости от направления).

Помните, у нас есть полное руководство по флексбоксам.

Способ 5. Использование Grid

Разметка с помощью Grid более новая (и менее поддерживаемая), чем флексбоксы. У нас есть также по нему есть полное руководство. Вы также можете довольно легко использовать Grid для прижимания подвала (пример 5).

Пример 5. Использование grid

<!DOCTYPE html>
<html>
 <head>
  <meta charset="utf-8">
  <title>Подвал</title>
  <style>
   body { margin: 0; }
   html {
    height: 100%;
   }
   body {
    min-height: 100%;
    display: grid;
    grid-template-rows: 1fr auto;
   }
   .footer {
    grid-row-start: 2;
    grid-row-end: 3;
   }
  </style>
 </head>
 <body>
  <div class="content">
   Содержимое
  </div>
  <footer class="footer">Подвал</footer>
 </body>
</html>

See the Pen Sticky Footer with Grid by Chris Coyier (@chriscoyier) on CodePen.

Не выкладывайте свой код напрямую в комментариях, он отображается некорректно. Воспользуйтесь сервисом cssdeck.com или jsfiddle.net, сохраните код и в комментариях дайте на него ссылку. Так и результат сразу увидят.