Прижатый подвал, 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.