6

CSS для закрепления подвала страницы внизу с минимальной высотой, без перекрытия содержания страницы

6

У меня есть следующая страница (нерабочая ссылка: http://www.workingstorage.com/Sample.htm), на которой есть подвал (footer), который я не могу заставить находиться внизу страницы.

Я хочу, чтобы подвал:

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

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

5 ответ(ов)

6

Вот перевод на русский в стиле ответа на 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()

Это решение, хоть и работает, имеет свои недостатки:

  1. Высоты для заголовка и футера должны задаваться только через CSS-переменные, и следовательно, они не могут иметь динамическую высоту, соответствующую их содержимому.
  2. Расчет может быть не совсем точным, что может привести к небольшой щели или переполнению (что может вызвать видимую полосу прокрутки).

Я привел этот метод, потому что хотел перечислить все возможные решения, как хорошие, так и плохие.

: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>

Если нужны дополнительные разъяснения по каждому методу, не стесняйтесь задавать вопросы!

3

Чтобы получить желаемый результат, можно использовать простое решение, сделав элемент <body> высотой 100% страницы, при этом также установив min-height на 100%. Эта техника хорошо работает, если высота вашего футера остается неизменной.

Для размещения футера внизу страницы можно задать ему отрицательный верхний отступ:

footer {
    clear: both;
    position: relative;
    height: 200px; /* Задайте нужную высоту футера */
    margin-top: -200px; /* Отрицательный отступ равен высоте футера */
}

Однако стоит помнить, что если высота футера изменится, вам потребуется обновить значение отрицательного отступа.

1

Вот очень простое решение с использованием 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.

0

Очень простой подход, который отлично работает во всех браузерах, выглядит следующим образом:

Источник

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 для создания контейнера, который занимает всю высоту, а подвал фиксируется внизу с помощью абсолютного позиционирования.

0

Я использовал следующий подход, чтобы "приклеить" свой футер внизу страницы, и у меня все заработало:

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 использует свои маргины и паддинги, поэтому мне нужно было отрегулировать это значение.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь