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

Коротко и по делу — есть несколько надёжных способов, в зависимости от того, должен ли футер всегда быть видим (плавающий) или просто «прижиматься» к низу, когда содержимого мало. Рекомендация: используйте flexbox или CSS Grid — они просты и корректно работают с адаптивностью.


Рекомендованный способ — Flexbox (обычно лучший выбор)

Идея: сделать контейнер страницы колонкой, а основной контент растящимся (flex: 1), тогда футер автоматически окажется внизу, если контента мало, и сдвинется ниже при скролле, если контента много.

HTML:

<body>
  <div class="page">
    <header>Шапка</header>
    <main class="content">Основной контент</main>
    <footer>Футер</footer>
  </div>
</body>

CSS:

html, body {
  height: 100%;        /* важно, чтобы flex мог посчитать 100% высоты */
  margin: 0;
}
.page {
  min-height: 100vh;   /* занимает всю высоту окна */
  display: flex;
  flex-direction: column;
}
.content {
  flex: 1;             /* занимает всё доступное пространство */
}
/* footer стилизуйте как нужно */
footer {
  padding: 20px;
  background: #222;
  color: #fff;
}

Плюсы: простота, отзывчивость, не требует JavaScript. Работает во всех современных браузерах.


CSS Grid — альтернативный современный вариант

Grid подходит, если у вас сложная сетка на странице.

html, body {
  height: 100%;
  margin: 0;
}
.page {
  min-height: 100vh;
  display: grid;
  grid-template-rows: auto 1fr auto; /* header, main, footer */
}

HTML структура та же. Поведение аналогично: main (середина) растянется, прижимая футер вниз.


Если нужно, чтобы футер был всегда виден (fixed)

Иногда хотят «плавающий» футер, который всегда виден — тогда используйте position: fixed. Важно учитывать, что он перекроет контент, поэтому добавьте отступ снизу для основного блока.

footer {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  height: 60px;
}
.content {
  padding-bottom: 60px; /* чтобы контент не скрывался под футером */
}

Плюс: всегда виден. Минус: закрывает часть контента, требует учёта высоты на мобильных устройствах и safe-area.


Плохие/устаревшие варианты (чего лучше избегать)

  • position: absolute с bottom: 0 на футере — перекрывает контент при увеличении высоты содержимого.
  • Хаки с отрицательными margin и wrapper с фиксированной высотой — громоздко и ненадёжно.
  • Таблицы для раскладки — устарело.

Частые ошибки и как их избегать

  1. Не задан height: 100% для html, body — flexbox/min-height может работать неправильно. Убедитесь, что html, body { height:100%; } или используйте min-height:100vh на корневом контейнере.
  2. Футер перекрывает контент — если футер fixed, добавьте padding-bottom у контента равный высоте футера.
  3. Mobile safe area (iPhone notch): используйте padding-bottom: env(safe-area-inset-bottom); или комбинируйте с calc, чтобы футер не «садился» на индикатор.
  4. z-index: если футер перекрывает всплывающие окна, уточните z-index.
  5. Высота футера динамическая: для fixed-футера лучше не задавать жёсткую высоту, либо динамически вычислять padding-bottom через JS — но чаще хватает CSS-подходов.

Пример с safe-area:

footer {
  padding: 16px calc(16px + env(safe-area-inset-right));
  padding-bottom: calc(16px + env(safe-area-inset-bottom));
}
.content {
  padding-bottom: calc(60px + env(safe-area-inset-bottom)); /* 60px — пример высоты футера */
}

Когда нужен JS?

Обычно не нужен. JS может понадобиться, если у вас:

  • динамически меняющаяся высота футера и вы хотите корректно установить padding-bottom у контента;
  • особые анимации/появление футера по прокрутке.

Но для подавляющего большинства задач CSS (flex/grid) — достаточно.


Итог (рекомендация)

  • Для обычной страницы: используйте flexbox: .page { display:flex; flex-direction:column; min-height:100vh } + .content { flex:1 }.
  • Для сложной раскладки — CSS Grid.
  • Для «всегда видимого» футера — position: fixed, но учитывайте отступы и safe-area.