Нижний колонтитул внизу страницы или содержимого, в зависимости от того, что ниже

94

У меня такая структура:

<body>
    <div id="main-wrapper">
        <header>
        </header>
        <nav>
        </nav>
        <article>
        </article>
        <footer>
        </footer>
    </div>
</body>

Я динамически загружаю контент с <article>помощью javascript. Из-за этого <article>может меняться высота блока.

Я хочу, чтобы <footer>блок находился внизу страницы, когда есть много контента, или внизу окна браузера, когда существует только несколько строк контента.

На данный момент я могу сделать то или другое ... но не то и другое.

Кто-нибудь знает, как я могу это сделать - заставить <footer>придерживаться нижней части страницы / содержимого или нижней части экрана, в зависимости от того, что ниже.

Будет
источник
Не хотели бы люди прокомментировать, почему они проголосовали против вопроса двухлетней давности?
Will
Да ладно, прошло уже почти 6 лет ...
Уилл

Ответы:

101

Липкий нижний колонтитул Райана Фейта очень хорош, однако я считаю, что его основная структура отсутствует *.


Версия Flexbox

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

Уловка, чтобы нижние колонтитулы прилипали к основанию с помощью flexbox, заключается в том, чтобы другие элементы в том же контейнере сгибались вертикально. Все, что для этого требуется, - это полноразмерный элемент-оболочка display: flexи хотя бы один родственный элемент со flexзначением больше, чем 0:

CSS:
html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}

#main-wrapper {
  display: flex;
  flex-direction: column;
  min-height: 100%;
}

article {
  flex: 1;
}


Если вы не можете использовать flexbox, я выберу базовую структуру:

<div class="page">
  <div class="page__inner">
    <header class="header">
      <div class="header__inner">
      </div>
    </header>
    <nav class="nav">
      <div class="nav__inner">
      </div>
    </nav>
    <main class="wrapper">
      <div class="wrapper__inner">
        <div class="content">
          <div class="content__inner">
          </div>
        </div>
        <div class="sidebar">
          <div class="sidebar__inner">
          </div>
        </div>
      </div>
    </main>
    <footer class="footer">
      <div class="footer__inner">
      </div>
    </footer>
  </div>
</div>

Что не так уж и далеко от:

<div id="main-wrapper">
    <header>
    </header>
    <nav>
    </nav>
    <article>
    </article>
    <footer>
    </footer>
</div>

Уловка для закрепления нижнего колонтитула заключается в том, чтобы нижний колонтитул был привязан к нижнему отступу содержащего его элемента. Для этого требуется , чтобы высота нижнего колонтитула была статической, но я обнаружил, что нижние колонтитулы обычно имеют статическую высоту.

HTML:
<div id="main-wrapper">
    ...
    <footer>
    </footer>
</div>
CSS:
#main-wrapper {
    padding: 0 0 100px;
    position: relative;
}

footer {
    bottom: 0;
    height: 100px;
    left: 0;
    position: absolute;
    width: 100%;
}

Теперь, когда нижний колонтитул привязан к нему #main-wrapper, вы должны #main-wrapperбыть не меньше высоты страницы, если только ее дочерние элементы не длиннее. Это делается путем #main-wrapperесть min-heightиз 100%. Вы также должны помнить , что его родители, htmlи bodyнужно быть таким же высоким , как страницы , а также.

CSS:
html,
body {
    height: 100%;
    margin: 0;
    padding: 0;
}

#main-wrapper {
    min-height: 100%;
    padding: 0 0 100px;
    position: relative;
}

footer {
    bottom: 0;
    height: 100px;
    left: 0;
    position: absolute;
    width: 100%;
}

Конечно, вы должны подвергнуть сомнению мое мнение, поскольку этот код заставляет нижний колонтитул отрываться от нижней части страницы, даже когда нет содержимого. Последняя Хитрость заключается в том, чтобы изменить модель коробки , используемую #main-wrapperтаким образом , что min-heightиз 100%включает в себя 100pxзаполнение.

CSS:
html,
body {
    height: 100%;
    margin: 0;
    padding: 0;
}

#main-wrapper {
    box-sizing: border-box;
    min-height: 100%;
    padding: 0 0 100px;
    position: relative;
}

footer {
    bottom: 0;
    height: 100px;
    left: 0;
    position: absolute;
    width: 100%;
}

И вот он, липкий нижний колонтитул с исходной структурой HTML. Просто убедитесь, что footer's heightравно #main-wrapper' s padding-bottom, и вы должны быть установлены.


* Причина я придраться со структурой FAIT является потому , что он устанавливает .footerи .headerэлементы на различных уровнях иерархии при добавлении ненужного .pushэлемента.

zzzzBov
источник
Мне нужно было добавить #main-wrapper *:first-child { margin-top: 0; }, иначе страница будет слишком длинной по сравнению с верхним полем первого дочернего элемента (что приведет к ненужной полосе прокрутки на коротких страницах).
Флориан Брукер,
Спасибо, @zzzzBov за это подробное объяснение, и особенно за упоминание flex-direction (если бы я нашел это раньше - сэкономил бы мне пару часов! :)
ea0723
Версия Flexbox у меня не работает в IE11, но мне подходит другой подход! Спасибо и +1!
Мэтт
@Matt, вам нужно использовать префиксы браузера, чтобы flexbox работал в IE11. используйте такой инструмент, как autoprefixer, и вам никогда не придется беспокоиться о добавлении их вручную.
zzzzBov
2
Ссылка в липком нижнем колонтитуле, по-видимому, не работает из-за того, что его сайт был преобразован в уведомление In Memoriam для него. К тому же нет кешированных версий из-за настроек robots.txt
tzrlk
13

Липкий нижний колонтитул Райана Фейта - это простое решение, которое я использовал несколько раз в прошлом.

Базовый HTML :

<div class="wrapper">
    <div class="header">
        <h1>CSS Sticky Footer</h1>
    </div>
    <div class="content"></div>
    <div class="push"></div>
</div>
<div class="footer"></div>

CSS :

* {
    margin: 0;
}
html, body {
    height: 100%;
}
.wrapper {
    min-height: 100%;
    height: auto !important;
    height: 100%;
    margin: 0 auto -142px; /* the bottom margin is the negative value of the footer's height */
}
.footer, .push {
    height: 142px; /* .push must be the same height as .footer */
}

/*

Sticky Footer by Ryan Fait
http://ryanfait.com/

*/

Переведем это так, чтобы оно было похоже на то, что у вас уже есть, с чем-то в этом роде:

HTML :

<body>
    <div class="wrapper">
        <header>
        </header>
        <nav>
        </nav>
        <article>
        </article>
        <div class="push"></div>
    </div>
    <footer>
    </footer>
</body>

CSS:

* {
    margin: 0;
}
html, body {
    height: 100%;
}
.wrapper {
    min-height: 100%;
    height: auto !important;
    height: 100%;
    margin: 0 auto -142px; /* the bottom margin is the negative value of the footer's height */
}
footer, .push {
    height: 142px; /* .push must be the same height as .footer */
}

Только не забудьте обновить негатив на поле оболочки, чтобы он соответствовал высоте вашего нижнего колонтитула, и нажмите div. Удачи!

Джош Майн
источник
4
Мне нравится, как он поместил комментарий внизу, подходящий для решения нижнего колонтитула: D
Призрак Мадары
Нет необходимости изменять разметку для этого конкретного стиля.
zzzzBov 02
@zzzzBov У меня сейчас нет времени разбираться в этом подробнее, но что именно вы имеете в виду?
Джош Мейн
Я использую мобильный банкомат, поэтому я не могу написать полный ответ, иначе я бы уже это сделал. Комментарий был больше, чтобы я не забыл добавить ответ позже.
zzzzBov 02
@JoshMein, я добавил ответ, в котором объясняется, как сделать нижний колонтитул приклеиваемым, не вмешиваясь в предоставленную структуру.
zzzzBov 03
0

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

article {
  min-height: calc(100vh - 150px); /* deduct the height or margins of any other elements within wrapping container*/
}

footer {
  height: 50px;
}

header {
   height: 50px;
}

nav {
  height: 50px;
}
<body>
  <div id="main-wrapper">
    <header>
    </header>
    <nav>
    </nav>
    <article>
    </article>
    <footer>
    </footer>
  </div>
</body>

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

Вы можете найти это и другие решения, опубликованные выше здесь: https://css-tricks.com/couple-takes-sticky-footer/

Галина Е
источник