Как с помощью CSS прижать footer к низу окна браузера

Вступление

Помнится мне, в тот момент, когда я стал переходить с таблиц на верстку дивами, одной из трудностей, с которыми я столкнулся, была следующая – как прижать подвал сайта (footer) в самый низ окна браузера, чтобы страница при этом выглядела вытянутой на всю высоту, вне зависимости от объема текста, а при высоте страницы, большей, чем высота окна браузера (при появлении скролла), футер оставался бы на положенном ему месте.

Если с помощью таблиц сия задача решается лишь за счет указания высоты для таблицы и/или вложенной в нее ячейки, то при использовании CSS в блочной верстке применяется совсем иной подход.

В процессе практики я выделил для себя 5 способов прижимания футера к низу окна браузера с помощью CSS.

HTML-код всех представленных способов имеет следующую структуру (отличие лишь в CSS-коде):

<html>
<body>

<div class="wrapper">

	<div class="content"></div>

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

</div>

</body>
</html>

В CSS-код, приведенный ниже, включены только те свойства, которые минимально необходимы для реализации соответствующего способа. По каждому из них вы можете посмотреть живой пример.

Первый способ

Footer прижимается вниз путем его абсолютного позиционирования и вытягивания высоты родительских блоков (html, body и .wrapper) на 100%. При этом контентному блоку .content нужно указать нижний отступ, который равен или больше высоты подвала, иначе последний закроет часть контента.

CSS-код:

* {
	margin: 0;
	padding: 0;
}
html,
body {
	height: 100%;
}
.wrapper {
	position: relative;
	min-height: 100%;
}
.content {
	padding-bottom: 90px;
}
.footer {
	position: absolute;
	left: 0;
	bottom: 0;
	width: 100%;
	height: 80px;
}

Живой пример 1-го способа

Второй способ

Footer прижимается вниз за счет вытягивания блока контента и его “родителей” на всю высоту окна браузера и подъема футера вверх через отрицательный отступ (margin-top) для избавления от появляющегося при этом вертикального скролла. В данном случае необходимо обязательно указать высоту подвала, и она должна быть равна величине отступа.

CSS-код:

* {
	margin: 0;
	padding: 0;
}
html,
body,
.wrapper {
	height: 100%;
}
.content {
	box-sizing: border-box;
	min-height: 100%;
	padding-bottom: 90px;
}
.footer {
	height: 80px;
	margin-top: -80px;
}

Благодаря свойству box-sizing: border-box, мы не позволяем блоку с классом .content превысить высоту 100%. То есть в данном случае min-height: 100% + padding-bottom: 90px равняется 100% высоты окна браузера.

Живой пример 2-го способа

Третий способ

Он хорош тем, что, в отличие от остальных способов (кроме 5-го), высота футера значения не имеет.

CSS-код:

* {
	margin: 0;
	padding: 0;
}
html,
body {
	height: 100%;
}
.wrapper {
	display: table;
	height: 100%;
}
.content {
	display: table-row;
	height: 100%;
}

Здесь мы эмулируем поведение таблицы, превратив блок .wrapper в таблицу, а блок .content в строку таблицы (свойства display: table и display: table-row соответственно). Благодаря этому, а также тому, что блоку .content и всем его родительским контейнерам задана высота 100%, контент растягивается на всю высоту, но за минусом высоты футера, которая определяется автоматически – эмуляция таблицы не дает подвалу вылезть за пределы высоты окна браузера.

В результате footer прижат к низу.

Живой пример 3-го способа

Четвертый способ

Данный способ не похож ни на один из предыдущих, и его особенность заключается в использовании CSS-функции calc() и единицы измерения vh, которые поддерживаются только современными браузерами. Здесь необходимо знать точную высоту подвала.

CSS-код:

* {
	margin: 0;
	padding: 0;
}
.content {
	min-height: calc(100vh - 80px);
}

100vh – это высота окна браузера, а 80px – это высота футера. И с помощью функции calc() мы вычитаем вторую величину из первой, тем самым прижимая футер к низу.

Узнать, какие браузеры поддерживают calc() и vh, вы можете на сайте caniuse.com по следующим ссылкам: поддержка функции calc(), поддержка единицы измерения vh.

Живой пример 4-го способа

Пятый способ (самый актуальный)

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

CSS-код:

* {
	margin: 0;
	padding: 0;
}
html,
body {
	height: 100%;
}
.wrapper {
	display: flex;
	flex-direction: column;
	min-height: 100%;
}
.content {
	flex: 1 0 auto;
}
.footer {
	flex: 0 0 auto;
}

Узнать про поддержку браузерами свойства flex можно здесь.

Живой пример 5-го способа

Комментарии (161)

  1. Дмитрий
    24 марта 2017 г. в 11:12

    Спасибо! 4-й помог!

  2. Николай
    4 июня 2017 г. в 22:44

    Спасибо автору! Помог 4-й способ.

  3. Дарья
    1 августа 2017 г. в 22:45

    Огромное спасибо!!
    Пятый способ – супер!

  4. SerW
    13 сентября 2017 г. в 12:45

    https://philipwalton.github.io/solved-by-flexbox/demos/sticky-footer/ – по мне так один из лучших способов

    1. 20 сентября 2017 г. в 00:29 / ответ на коммент SerW

      там фиксация при прокрутке

    2. 18 февраля 2018 г. в 10:19 / ответ на коммент SerW

      Здравствуйте!

      Благодарю! Правда, простое и эффективное решение.

      Всего доброго.

    3. Алексей
      28 декабря 2018 г. в 13:46 / ответ на коммент SerW

      Супер, спасибо. (в 5 способе футер всегда под экраном, даже если контента нет)

    4. Анна
      17 января 2020 г. в 23:57 / ответ на коммент SerW

      Большое спасибо!!!
      Отлично подошёл способ, указанный в ссылке. Самый идеальный. Хорошо что нет фиксированной высоты.

  5. Вася
    11 февраля 2018 г. в 11:44
    <div style="position: relevate; background-color:#00F; padding:0">
    	<div id="content"style="height: auto;  background-color: #F00; padding: 12px  ">
    		100% резиновый без проблемный блок.<br>
    	  Комбинируя position relevate и absolute <br>
      - можно выровнять как угодно и что угодно.
    	</div>
    	<div id="content" style="position:absolute; bottom:0; height:50px;width:100%;  background-color: #0FA; padding: 10px;text-align:center;   ">
    	Прижатый к боттому блок. Высотой 50px. 
    	</div>
    </div>
    1. Коля
      9 декабря 2020 г. в 13:29 / ответ на коммент Вася

      это яркий пример говнокода, не делайте так!

  6. Роман
    28 июля 2018 г. в 10:38

    Я сделал по-другому. Wrapper поставил 100vh и display: grid. И всё.

  7. 24 августа 2018 г. в 11:15

    Добрый день.

    Спасибо огромное!!!

    В случае с iPad Wi-Fi (Safari & Chrome) помог 3-й способ. Причем, 3-й способ решил вопрос не только с футером, пофиксался неприятный баг с высотой DIV-ов (верстка на флекс боксе).

    С уважением,
    Игорь

  8. Николай
    9 ноября 2018 г. в 21:40

    Способ с гридами:

    html,
    body {
      height: 100%;
    }
    .wrapper {
      height: 100%;
      display: grid;
      grid-template-rows: 1fr auto;
    }
    
  9. Игорь
    25 декабря 2018 г. в 10:32

    Люди которые пишут про гриды, вы вообще в курсе что гриды вообще не поддерживает IE на котором сидит около 20% пользователей.

  10. Марат
    16 февраля 2019 г. в 12:10

    Доля IE вместе с Edge около 8-9%, забудьте про них.

  11. Александр
    8 июля 2019 г. в 12:45

    Спасибо! Флекс прямо то, что нужно. Интересно, почему его так поздно добавили, ведь интерфейсы на HTML делались всё время

  12. Дмитрий
    18 июля 2019 г. в 12:48

    В последнем методе, который САМЫЙ АКТУАЛЬНЫЙ – явная ошибка. Для wrapper необходимо указать min-height, а не height, что бы он тянулся вниз, при необходимости.

    1. Действительно. Спасибо, исправил.

  13. vital72
    23 августа 2019 г. в 16:21

    нужен футер, который всегда на экране, скроллировался только контент, но не футер. “position: fixed” не подходит по объективной причине — футер с ним вываливается из общего потока, совсем, а мне необходимо, чтоб ширина футера зависела от ширина родителя, задавать дважды ширину — для родителя и футера, — не комильфо. в этом плане подошел бы “position: sticky”, но при малом контенте он никуда не приливает.

    1. vital72
      23 августа 2019 г. в 16:34 / ответ на коммент vital72

      кароче. написал и сам же через 5 минут нашёл решение. “position: sticky” — то, что нужно, но чтобы работало при малом контенте: родитель “display: flex; flex-direction: column;”, а футер “margin-top: auto”

  14. Mickey
    5 ноября 2019 г. в 04:25

    при наличии других элементов типа form, div, p все идет наперекосяк, т.е. футер прилипает к контенту

  15. Жан
    27 ноября 2019 г. в 12:24

    Отлично! Эту статью и искал. Как раз интересовало, как прижать футер к низу, не используя flex (способы 1-4). Спасибо большое!

  16. SinGlEBW
    10 июня 2020 г. в 22:40

    Не знаю почему, но с обычным блоками коряво работает. Выставляя html и body в 100%, размер блока занимал размер окна. Стоило залить контентом почему-то контент вылазил за этот блок. Пока контента нет футер внизу, как появляется контент и имеется скрол то при скроле футер поднимается, вообщем блок body не захватывал контент. display: grid решил проблему

  17. Zoff74
    4 марта 2021 г. в 15:17

    Еще один способ.

    .clear { clear: both;}

    #footer {
    background: #A9A9A9;/*меняем по желанию*/
    width: auto;
    height: 50px;/*меняем по желанию*/
    color: #ffc;/*меняем по желанию*/
    padding-top: 2px;
    border-radius: 10px;/*меняем по желанию*/
    border-style: double;/*меняем по желанию*/
    margin-top: 5px;/*меняем по желанию*/
    }

  18. Виктор
    28 мая 2021 г. в 20:01

    Отличное решение (то, что №5). Спасибо.

  19. Алексей
    19 июля 2021 г. в 11:49

    5 способ помог. Спасибо.

  20. Mike
    27 сентября 2022 г. в 17:13

    Помог 4й способ, спасибо! Но я не вычитал высоту футера,
    а просто поставил min-height: 60vh; ну или сколько кому нужно.

Ваш комментарий

Жирный текст

Ссылка

Цитата

Внутристрочный код

CSS-код

HTML-код

JavaScript-код

PHP-код