CSS для закрепления подвала страницы внизу с минимальной высотой, без перекрытия содержания страницы
У меня есть следующая страница (нерабочая ссылка: http://www.workingstorage.com/Sample.htm
), на которой есть подвал (footer), который я не могу заставить находиться внизу страницы.
Я хочу, чтобы подвал:
- прикреплялся к нижней части окна, когда страница короткая и экран не заполнен,
- оставался в конце документа и двигался вниз, как обычно, когда содержимое превышает высоту экрана (вместо того чтобы накладываться на содержимое).
CSS унаследован, и он сбивает меня с толку. Мне не удается правильно изменить его, чтобы установить минимальную высоту для содержания или заставить подвал находиться внизу.
5 ответ(ов)
Вот перевод на русский в стиле ответа на StackOverflow:
Ниже представлены 4 различных метода:
В каждом примере тексты можно редактировать, чтобы продемонстрировать, как контент будет отображаться в различных сценариях.
1) Flexbox
body {
min-height: 100vh;
margin: 0;
}
header {
min-height: 50px;
background: lightcyan;
}
footer {
min-height: 50px;
background: PapayaWhip;
}
/* Статья занимает все пространство между header и footer */
body {
display: flex;
flex-direction: column;
}
main {
flex: 1;
}
<header contentEditable>Заголовок</header>
<main contentEditable>Содержание</main>
<footer contentEditable>Футер</footer>
2) Grid
Думаю, это лучшее решение, так как оно предоставляет максимальный контроль с минимальными ограничениями.
body {
min-height: 100vh;
margin: 0;
display: grid;
grid-template-rows: auto 1fr auto;
}
header {
min-height: 50px;
background: lightcyan;
}
footer {
min-height: 50px;
background: PapayaWhip;
}
<header contentEditable>Заголовок</header>
<main contentEditable>Содержание</main>
<footer contentEditable>Футер</footer>
3) position:absolute
(без динамической высоты футера)
Данный метод использует "трюк" с размещением псевдоэлемента ::after
на body
, задавая ему точную высоту футера, чтобы он занимал то же пространство, что и футер. Таким образом, когда футер позиционируется абсолютно, он будет выглядеть так, будто футер действительно занимает место, устраняя негативные последствия абсолютного позиционирования (например, перекрытие контента тела).
body {
min-height: 100vh;
margin: 0;
position: relative;
}
header {
min-height: 50px;
background: lightcyan;
}
footer {
background: PapayaWhip;
}
/* Трюк: */
body {
position: relative;
}
body::after {
content: '';
display: block;
height: 50px; /* Задайте такую же высоту, как у футера */
}
footer {
position: absolute;
bottom: 0;
width: 100%;
height: 50px;
}
<header contentEditable>Заголовок</header>
<article contentEditable>Содержание</article>
<footer contentEditable>Футер</footer>
4) Table-layout
html { height: 100%; }
body { min-height: 100%; margin: 0; }
header {
height: 50px;
background: lightcyan;
}
main {
height: 1%;
}
footer {
height: 50px;
background: PapayaWhip;
}
/**** Трюк: ****/
body {
display: table;
width: 100%;
}
body > footer {
display: table-row;
}
<body>
<header contentEditable>Заголовок</header>
<main contentEditable>Содержание</main>
<footer contentEditable>Футер</footer>
</body>
5) Calc()
Это решение, хоть и работает, имеет свои недостатки:
- Высоты для заголовка и футера должны задаваться только через CSS-переменные, и следовательно, они не могут иметь динамическую высоту, соответствующую их содержимому.
- Расчет может быть не совсем точным, что может привести к небольшой щели или переполнению (что может вызвать видимую полосу прокрутки).
Я привел этот метод, потому что хотел перечислить все возможные решения, как хорошие, так и плохие.
:root {
--header-height: 50px;
--footer-height: 50px;
}
/* минимальный сброс */
body { margin: 0; }
header {
height: var(--header-height);
background: lightcyan;
}
main {
min-height: calc(100vh - var(--header-height) - var(--footer-height));
}
footer {
height: var(--footer-height);
background: PapayaWhip;
}
<header contentEditable>Заголовок</header>
<main contentEditable>Содержание</main>
<footer contentEditable>Футер</footer>
Если нужны дополнительные разъяснения по каждому методу, не стесняйтесь задавать вопросы!
Чтобы получить желаемый результат, можно использовать простое решение, сделав элемент <body>
высотой 100%
страницы, при этом также установив min-height
на 100%
. Эта техника хорошо работает, если высота вашего футера остается неизменной.
Для размещения футера внизу страницы можно задать ему отрицательный верхний отступ:
footer {
clear: both;
position: relative;
height: 200px; /* Задайте нужную высоту футера */
margin-top: -200px; /* Отрицательный отступ равен высоте футера */
}
Однако стоит помнить, что если высота футера изменится, вам потребуется обновить значение отрицательного отступа.
Вот очень простое решение с использованием Flexbox, которое не предполагает фиксированных высот или изменения положения элементов.
HTML
<div class="container">
<header></header>
<main></main>
<footer></footer>
</div>
CSS
.container {
display: flex;
flex-direction: column;
min-height: 100vh;
}
main {
flex: 1;
}
С помощью этого кода main
автоматически займет всё доступное пространство между header
и footer
, который всегда будет внизу контейнера.
Если у вас есть секции с фиксированной высотой, вы можете добавить их, например, так:
body,
html {
margin: 0;
padding: 0;
}
header,
main,
footer {
margin: 0;
display: block;
}
header {
height: 40px;
background-color: #ccc;
}
footer {
height: 80px;
background-color: orange;
}
main {
background-color: #f4f4f4;
}
Теперь у вас будет статический header
высотой 40px и фиксированный footer
высотой 80px, а main
займет оставшееся пространство. Таким образом, весь макет будет отзывчивым и займёт всю высоту окна браузера благодаря свойству min-height: 100vh
.
Очень простой подход, который отлично работает во всех браузерах, выглядит следующим образом:
html,
body {
margin:0;
padding:0;
height:100%;
}
#container {
min-height:100%;
position:relative;
}
#header {
background:#ff0;
padding:10px;
}
#body {
padding:10px;
padding-bottom:60px; /* Высота подвала */
}
#footer {
position:absolute;
bottom:0;
width:100%;
height:60px; /* Высота подвала */
background:#6cf;
}
<div id="container">
<div id="header">header</div>
<div id="body">body</div>
<div id="footer">footer</div>
</div>
Таким образом, вы легко сможете сохранить подвал внизу страницы, даже если контент не заполняет всю высоту. В приведенном коде используется CSS для создания контейнера, который занимает всю высоту, а подвал фиксируется внизу с помощью абсолютного позиционирования.
Я использовал следующий подход, чтобы "приклеить" свой футер внизу страницы, и у меня все заработало:
HTML
<body>
<div class="allButFooter">
<!-- Здесь размещайте содержимое страницы, включая заголовок, навигацию, боковую панель и т.д. -->
</div>
<footer>
<!-- Содержимое футера -->
</footer>
</body>
Единственное изменение, которое нужно внести в HTML — это добавить div
с классом "allButFooter"
. Я применил это на всех страницах: как на тех, которые были короткими и футер не крепился внизу, так и на длинных, где я знал, что потребуется прокрутка. Я сделал это, чтобы убедиться, что все работает нормально, даже если содержимое страницы динамическое.
CSS
.allButFooter {
min-height: calc(100vh - 40px);
}
Класс "allButFooter"
имеет значение min-height
, которое зависит от высоты окна просмотра (100vh
означает 100% высоты окна) и высоты футера, которую я заранее знал — 40px.
Это все, что я сделал, и у меня получилось отлично. Я не проверял во всех браузерах, только в Firefox, Chrome и Edge — и результаты оказались такими, как я хотел. Футер крепится внизу, и вам не нужно заморачиваться с z-index
, position
или какими-либо другими свойствами. Позиция каждого элемента в моем документе была по умолчанию, я не менял ее на absolute
, fixed
или что-то еще.
Работа с адаптивным дизайном
Хочу внести ясность. Это решение с футером высотой 40px не работало так, как я ожидал, когда я работал над адаптивным дизайном с использованием Twitter-Bootstrap
. Мне пришлось изменить значение, которое я вычитал в функции:
.allButFooter {
min-height: calc(100vh - 95px);
}
Это, вероятно, связано с тем, что Twitter-Bootstrap
использует свои маргины и паддинги, поэтому мне нужно было отрегулировать это значение.
Какова разница между SCSS и Sass?
Как сделать так, чтобы div не был больше своего содержимого?
Как выровнять содержимое div по нижнему краю
Как центрировать элемент с "position: absolute"
Что означает селектор CSS "+" (плюс)?