CSS Sticky Footer / Прилипающий футер

Original author: Steve Hatcher
  • Translation

Как использовать прилипающий футер


Введение


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

Решения Райана Фэйта хорошо известно и работает, но требует лишний пустой <div>. Приверженцы чистого HTML-кода могут найти это богохульство несемантичным. В нашем решении лишнего <div> нет.

Прилипающий футер, представленный здесь, основан на информации, полученной из статьи Изучаем футеры на List Apart, а так же дополненной материалом Кэмерона Адамса и вот этим кусочком с lwis.net. Он использует clearfix-хак, чтобы держать футер на своем месте в Google Chrome и других браузерах, где он может «всплыть» наверх при изменение размеров окна. Так же этот хак позволяет избежать проблем, если вы используете float для создании двух- или трехколоночных макетов. Мы протестировали его более чем в 50 браузерах, и работает он отлично.

HTML-код


Ниже представлена простейшая структура HTML-кода. Вы уже наверно заметили, что <div> с футером находится снаружи оберточного <div>'а.

<div id="wrap">

  <div id="main" class="clearfix">

  </div>

</div>

<div id="footer">

</div>



Содержимое вашей страницы можно расположить внутри <div>'а main. Например, для двухколоночного макета код будет таким:

<div id="wrap">

  <div id="main" class="clearfix">

    <div id="content">

    </div>

    <div id="side">

    </div>

  </div>

</div>

<div id="footer">

</div>



Шапку можно расположить внутри wrap, но снаружи main
<div id="wrap">

  <div id="header">

  </div>

  <div id="main" class="clearfix">

  </div>

</div>

<div id="footer">

</div>

Если вам захочется поместить какие-нибудь элементы вне этих блоков, то придется заморачиваться с абсолютным позиционированием и вычислением 100%-ной высоты.

CSS-код


Ниже — CSS-код, прижимающий футер к низу:

html, body, #wrap {height: 100%;}

body > #wrap {height: auto; min-height: 100%;}

#main {padding-bottom: 150px;}  /* отступ должен быть равен высоте футера */

#footer {position: relative;
	margin-top: -150px; /* отрицательное значение высоты футера */
	height: 150px;
	clear:both;} 

Значение высоты футера использовано здесь трижды. Важно, чтобы везде оно было одинаковым. Свойства height растягивают оберточный <div> по высоте на весь размер окна. Отрицательный отступ футера размещает его внутри отступов main-<div>'а. Посколько main находится внутри wrap, высота отступов уже включена в вышеописанную 100%-ную высоту. Таким образом футер остается в низу страницы.
Но это еще не все — надо назначить clearfix-свойства main-<div>'у.

Clearfix-хак спешит на помощь


Много CSS-дизайнеров уже знакомы с Clearfix-хаком. Он решает довольно много проблем с плавающими элементами. Здесь мы используем его, чтобы прибить футер в Google Chrome. Так же он избавит нас от проблем с «всплытием» футера в ситауции, например, когда в макете из двух колонок контент флоатится в одну сторону, а сайдбар в другую.
Поэтому добавляем в стили это:

.clearfix:after {content: ".";
	display: block;
	height: 0;
	clear: both;
	visibility: hidden;}
.clearfix {display: inline-block;}
/* Hides from IE-mac \*/
* html .clearfix { height: 1%;}
.clearfix {display: block;}
/* End hide from IE-mac */


Даже если вы используете метод Райана Фэйта с лишним <div>'ом, придется применять этот хак для многоколоночных макетов.

Известные проблемы


Высота и поля


Если использовать вертикальные отступы внутри некоторых элементов, это может толкнуть футер вниз на расстояние этих отступов, в шапке, например, или даже в wrap или main. Вместо полей снаружи (margins) лучше использовать отступы внутри (padding). Вы можете заметить, что содержимого на странице не так уж и много, а футер уползает за границы окна и появляется вертикальная полоса прокрутки: проверьте, нет ли где margin'ов, и замените их на padding.
Будьте внимательны при объявлении отступов для main<div>'а в разных местах. Если хочется добавить что-то вроде padding:0 10px 0 10px;, будьте осторожны — это может переопределить отступы внизу, которые должны быть строго определенной величины, контент может пойти поверх футера на длинных страницах (в Google Chrome).

Размеры шрифтов


Устанавливая размер шрифтов в относительных величинах, помните, что пользователи могут увеличивать их. В некоторых элементах, хотя бы даже в футере, это может испортить настройки высоты и получится разрыв, если тексту не хватает места. Используйте абсолютные величины (pt или px), или просто сделайте футер побольше.

Платформа .NET


При разработке сайтов на ASP.net, где каждая страница находится внутри <form>, не забудьте добавить height:100% для form, например так:

html, body, form, #wrap {height: 100%;}


UPD от переводчика. Считаю нужным прояснить для вас, господа, несколько моментов:
1. Это топик-перевод. Все вопросы и возмущения по поводу методов можете направить автору, его зовут Стив Хэтчер, ссылка прилагалась с самого начала
2. По-поводу IE-Mac, неработы в Хроме и прочего: ребята, неизвестно когда писался этот метод, но он обновлялся и пересматривался, а кроме этого он работает в подавляющем большинстве браузеров. «Не работает в Хроме» может значить, что футер уплывал куда-то в ранних билдах этого браузера. Ну и что, что у вас стоит последний апдейт? Есть люди, которые браузер не обновляют просто потому, что не знают о такой возможности, или просто не видят необходимости в этом. Вам хуже станет от того, что этот способ работает везде? Ну правда?
3. pt vs. em vs. px vs. %. Используйте у себя на сайте что хотите. Автор предложил ДВА метода решения проблемы с разъезжающимися пропорциями, вам никто не запрещает и не навязывает использовать любой из них. Мы все здесь не маленькие и знаем, что такое хорошо, а что такое плохо.
Share post

Similar posts

AdBlock has stolen the banner, but banners are not teeth — they will be back

More
Ads

Comments 74

    –6
    Хорошо, попробуем. Но у меня просьба, можно сказать для себя. Если вы div закрываете, напишите рядом что-то типа А то сходу и не поймёшь, что где закрывается.
      –3
      чорт. хабрапарсер всё скушал:

      <./div><.!-- #main -->
        +5
        ну это-то здесь причем, делайте у себя в коде что хотите. исходники очищены от всего лишнего, чтобы дать наглядное и схематичное представление
          +4
          Я думал, комментирование исходников — есть хорошая привычка. Но, раз вы так говорите, то я приму как есть. Вам виднее, что делать с вашим кодом ;-)

          Просто табуляция в пробел не даёт такой наглядности, как табуляция в четыре.
            0
            1. если вы не заметили — это топик перевод. из чего вытекает
            2. исходники авторские
            3. все что я с ними сделал — прогнал через подсветку кода
              –2
              Не имею ничего против… Я же сразу написал, что это лишь моя маленькая просьба :-)

              Просто я долго смотрел на код, не раз путался, что открылось, что закрылось и бегал глазами туда-сюда, вот и подумалось мне, что просто я идиот.
                +2
                там кода и 10 строк нету, неужто не умещается в голове?
          +1
          view-source:http://smileg.akmedia.ru/html/teplo/
            0
            да ну чушь какая :)
        0
        Даже когда подвал находится внутри обертки, пустой не обязателен
          0
          <div> я имел в виду. Код, надеюсь, приводить не надо?
        • UFO just landed and posted this here
            +4
            Честно говоря, этот способ не сильно отличается от тех, что в топе гугла.
            У всех них один большой недостаток — фиксированная высота.
            Прибить футер к низу можно вложив его во wrap, дать position: absolute; bottom: 0px; height: 150px;
            И main сказать margin-bottom: 150px;
            И в хроме без лишних clear: both всё работает.
              –7
              а для чего, кстати, делать футер резиновым по высоте? у меня вообще версий нет… сколько сайтов пересмотрел — везде фикс
                +2
                Заказчики они такие бывают… :)
                +1
                Кстати, вроде бы при таком варианте в IE6 если не задать clear:both для подвала, он не отображается.
                  0
                  я верю Вам на слово, что Вы нормально распорядитесь своими знаниями и навыками, но личной мой опыт переверстки чужих версток говорит о том, что большинство людей абсолютно позиционирующих блоки на странице — просто извращенцы, предлагаю не пропагандировать такой метод, дабы их ряды не пополнялись ;)
                  не, конечно, пока такие люди есть — у меня есть работа, которая стоит дороже обычной верстки, но все же я за то, чтобы в нашей стране научились верстать…
                    0
                    Возможно. Я не позиционирую себя как верстальщик.
                    Буду рад услышать недостатки position:absolute в данном случае.
                      0
                      ну дело в том, что верстка блоков абсолютами — это все равно что демонизм и поклонение сотоне.
                      как правило в таком макете открыв html код не можешь сразу понять что к чему, как это все работает, сетки они для того и придумывались, чтобы упорядочить расположение блоков, если верстка хорошая, то лично мне достаточно взглянуть только на её html-код и я уже в подробностях представляю себе всю сетку сайта, а если сверстать абсолютами, то футер в коде может спокойно идти между центральной и левой колонкой, а колонки вообще распологаться в обратном порядке и т.д. вообще хаос, к тому же как показывает опыт абсолютные верстки пишутся одними id'шками вместо вложенности и наследования классов, что также ухудшает читаемость и самый главный минус: абсолютами никогда не сделаешь действительно кроссбраузерную предсказуемую растяжку… вообще такой метод можно критиковать ещё очень долго, он ещё увеличивает css-код примерно в 1.5 раза и ещё много чего.
                      Хотя грамотный верстальщик даже абсолютами сделает все аккуратно и понятно, но я не встречал грамотных верстальщиков использующих абсолют
                        0
                        absolute это всего-лишь инструмент и весьма удобный когда нужно распологать блоки соответсвенно логике — «это всегда должно быть здесь а не обтекать (float) предыдущий элемент»

                        расположение блоков в html (логика) может несоответсвовать расположению визуально (презентация) в целях SEO + удобства мобильного сёрфинга.

                        я вот ужасаюсь когда float-left, float-left, float-left — как кирпичами стенку строят, по аналогии с td-td-td
                          0
                          на малых экранах абсолютно-позиционированный футер начнёт есть даже небольшой контент.
                  +5
                  Ага, баян неизвестно сколько летней давности, находится в Гугле на первой странице, смысл то его переводить?

                  p.s. Вы правда думаете, имеет смысл ориентироваться на IE 5.5 for Mac?
                    +2
                    что значит «смысл то его переводить»? вы знаете об этом методе? хорошо, а но другие-то нет.
                    есть люди, которые об этом не слышали.
                    которым ну вот просто не приходилось решать такую задачу, как прибитый футер средствами CSS. зайти на хабр, вбить желанное в поиск, получить кроссбраузернейшее решение (на сайте есть полный список), подробно описанное на русском, и еще вдовесок с десяток потенциально полезных комментов и уточнений — это ли не то, ради чего создавался хабр? У топик на данный момент на пятнадцать плюсов всего один минус — о чем это да говорит, задумайтесь
                      +3
                      HTML и CSS — интернациональные языки, перевода не требуют ;)
                      0
                      успешно пользуюсь уже давным-давно одним и тем же широко известным методом с абсолютным позиционированием «футера» относительно body. не стал бы давать ссылку, да вот не все знают, что этот метод в чистом его виде имеет проблему в IE при наличии динамического содержимого на странице. поэтому ссылка www.webcocktail.ru/coding/positioning-footer-at-the-bottom/ на статью с описанием проблемы и её решением.
                        –5
                        #footer {position: relative;
                        	margin-top: -150px; /* отрицательное значение высоты футера */
                        	height: 150px;
                        	clear:both;} 

                        *зануда-mode=on*
                        По-моему «высота футера» — это атрибут «height», а «margin-top» это верхний отступ или что-то вроде того ;)
                          +1
                          это не перевод «margin-top», а разъяснение того, какое ему нужно задать значение
                            0
                            Ясно. Я просто неверно истолковал комментарий к той строчке.

                            Если честно, то без разъяснения было бы понятнее, а так оно просто запутывает и может быть понято двояко. Вот как, к примеру, понял его я: «вот у нас строчка „margin-top: -150px“, в ней задаётся высота футера со значением -150». Что не совсем так, о чём и был мой предыдущий комментарий.

                            Если было бы что-то вроде «отступ равен высоте со знаком „-“» или «высота футера, помноженая на -1» или хотя бы «height * -1» — было бы слегка понятнее.

                            P.S.: я знаю, что это прямой перевод с оригинала, я просто высказываю своё личное мнение и своё личное восприятие. Минусуйте дальше.
                          +1
                          Метод совсем не новый, это понятно. Не указан один важный недостаток, в IE6 при таком методе, при ресайзе окна, может появляться отступ в 1px снизу.
                            0
                            Сколько помню такое в ие6 только при использовании позиционирования. Пруфлинк, или не появляется.
                            Метод не новый, согласен.
                            +6
                            csstool.ru вам в помощь. у них вроде подобная методика используется.
                            Да и вообще ресурс маст юз для верстальщика

                            (сам кроме как пользователь к ресурсу отношения не имею)
                              0
                              Спасибо, классная тулза!
                                +1
                                так он футер к низу вообще прижимать не умеет ;) да и мусор какой-то в коде нереальный, ручками такую сетку с css-clear'ом написать 5-10 минут, зато получится в 10 раз лучше ;)
                                • UFO just landed and posted this here
                                  0
                                  Лично я стараюсь избегать фиксированного позиционирования и высоты блоков при верстке.
                                  А с футером, если он есть, обычно вообще сплошной геморрой =(
                                  За метод спасибо. Правда, подобный веловипед я уже изобретал :)
                                    0
                                    Насмешили, молодцы: /* Hides from IE-mac \*/
                                      0
                                      чем position: absolute для футера не устраивает? никаких clearfix хаков не нужно.

                                      Устанавливая размер шрифтов в относительных величинах, помните, что пользователи могут увеличивать их. В некоторых элементах, хотя бы даже в футере, это может испортить настройки высоты и получится разрыв, если тексту не хватает места. Используйте абсолютные величины (pt или px), или просто сделайте футер побольше.

                                      ну вот Вы думаете что пишете? ведь прочтут и так и будут делать. в px шрифт вообще задавать нельзя (когда уже эту возможность уберут из стандарта?), в pt только в крайних случаях. и это не тот случай.
                                      вместо задания шрифта в абсолютных величинах, лучше задать высоту футера в относительных, наприер в ex;
                                        +1
                                        причем тут я? я перевел статью. все вопросы по поводу уместности использования величин направляйте, пожалуйста, к автору, ссылка на него указана
                                          0
                                          не заметил, извините.
                                          0
                                          полностью согласен на счет px, но здесь не прокатят относительные величины для высоты футера, т.к. отрицательный отступ сверху должен быть равен высоте футера, может в нормальных браузерах это и прокатет (что тоже не факт) но осел точно умрет на месте ;)
                                            +1
                                            не знаю насчет отрицательного отступа — всегда пользовался position: absolute; — никаких проблем с относительными величинами.
                                          0
                                          Буквально 2 недели назад делал именно эту нарезку для ASP.
                                          Для прилипающего футера типичная ASP конструкция … content… — не работает…
                                          Пришлось сам футер выносить из формы…
                                            0
                                            прошу прощения, сожрало код…

                                            <fоrm><bоdy>… content…</fоrm></bоdy>
                                              0
                                              %)) да что такое… откуда такая невнимательность с утра…
                                              <bоdy><fоrm>… content…</fоrm></bоdy>
                                            0
                                            Используйте абсолютные величины (pt или px)

                                            Вы уверены, что pt уместно использовать в вебе???
                                              +1
                                              идеологически нет, но это лучше чем px и тем более лучше писать css в строку :) чем бы дитя не тешилось лишь бы не гранатой ;)
                                                0
                                                Пожалуйста, поясните.
                                                Как мне представляется, pt — это хуже, чем em, в плане прогнозируемости результата… Речь о том, что, как правило, страница представляет жесткий или не очень, но пиксельный каркас, в который заливаются плавающие тексты. Поэтому px — это самый надежный способ обезопасить себя от некоторых моментов, таких как вылезание подписи из подложки фиксированного размера.
                                                  +1
                                                  это хуже чем em, но начнем с того, что нормальный браузер сориентируется в любой ситуации адекватно, а выползание надписи за границы зоны не такой уж и страшный грех (ну кроме тех случаев когда цвет шрифта близок к цвету бэкграунда окружения).
                                                  Но если вести идеологическую войну, стучать тапком по-столу и кричать что так правильно, а так нет, то px использовать для шрифтов принципиально неправильно, это единица измерения растровых изображений, а шрифт имеет свойства увеличиваться, которое заложенно в самой сути шрифта :)

                                                  Для шрифтов я пользуюсь исключительно em, но меня не напугаешь pt или px в графе font-size или line-height ;)
                                                    0
                                                    а line-height чем не угодил-то? ))))) вот его в пикселах-то задавать на мой взгляд можно (т.к. используется не только для корректирования вида текста). ну лан…
                                                    em, конечно, правильно (хотя % могут даже красивее выглядеть, дело вкуса), но и в пикселах не вижу ничего криминального. Есть задачи, которые решать em'ами — тоже изврат))))
                                                      0
                                                      да извращенцы кругом и рядом, сам постоянно сталкиваюсь с задачи переверстки чужих извратов и честно говоря такие проблемы и проблемами не являются, недавно был резиновый сайт (1000px-1400px) в котором все на странице позиционировалось на странице при помощи position: absolute, position: relative; но зато, бля, все дивами написано, хотелось плюнуть в лицо этому человеку :)
                                                      Лучше верстать портал таблицами и не пользоваться при этом colspan, rowspan, но без садизма =)
                                                        0
                                                        вот его в пикселах-то задавать на мой взгляд можно
                                                        как же можно? а если шрифт у пользователя получится больше заданного line-height?
                                                        em, конечно, правильно (хотя % могут даже красивее выглядеть, дело вкуса)
                                                        а есть какая-то разница между 1.1em и 101%?
                                                        Есть задачи, которые решать em'ами — тоже изврат))))
                                                        если эти задачи связаны с текстом — прошу примеры.
                                                          0
                                                          * 110%
                                                            0
                                                            1. если интерльньяж используется для смещения надписи, и это кореллирует с некоторым пиксельно-постоянным элементом
                                                            2. конечно)) 110%. если серьезно, то целые мне кажется лучше выглядят, чем float
                                                            3. если нужно обозначить относительно точно очень крупный шрифт. em (если рассчитывать его от defaul_font_size) может привести к сильному разбросу
                                                              0
                                                              3.
                                                              в принципе, наверное, я с Вами согласен. сейчас подумал — сам этим пользовался. если шрифт «заведомо крупный», то можно задать ему абсолютный размер, чтобы он не стал совсем гигантским при увеличении размера шрифта пользователем.
                                                          +1
                                                          Ой ли? Если уж быть точным pt — типографская мера и уместна она лишь в одном случае — для установки размеров шрифтов через css при подготовке html-документа для печати. Не надо путать лист формата A4 c окном браузера.
                                                            0
                                                            так точно, если подходить с другой стороны к этому вопросу, то так и получается.
                                                    0
                                                    Буквально пару дней назад ровно также прижимал футер…
                                                      +2
                                                      Если взглянете на мои верстки последнего года не найдете ни одной сделаной по-другому =)

                                                      на самом деле
                                                      position: relative;
                                                      clear:both;
                                                      совершенно излишни ;) я никогда так не писал, работает во всех браузерах отлично, а самое главное исходя из спецификаций оно так и должно работать, так что это метод на много-много лет вперед

                                                      и ещё чуть-чуть:
                                                      html, body, #wrap {height: 100%;}
                                                      body > #wrap {height: auto; min-height: 100%;}
                                                      помоему код не достаточно прочитать и сразу все становится понятно

                                                      я предпочитаю писать
                                                      html, body {height: 100%;}
                                                      #wrap {_height: 100%; min-height: 100%;}
                                                      эффект точно такой же, только несмотря на кашунственный хак для ie6 код как-то сразу становится понятнее и последовательнее
                                                        0
                                                        >> Вместо полей снаружи (margins) лучше использовать отступы внутри (padding)
                                                          0
                                                          Прошу прощения, первый коммент ушёл случайно.

                                                          >> Вместо полей снаружи (margins) лучше использовать отступы внутри (padding)

                                                          И вместо одного лишнего div'а получим по одному дополнительному div'у везде, где нужно сделать border+margin?
                                                            0
                                                            а я чета не совсем туда коммент впихнул =)
                                                            не, на самом деле мы получаем точно такой же один дополнительный див, но в нашем случае он не пустой, он служит оберткой для всего кроме футера, я обычно называю его class=«not_footer» и сразу становится ясно че он делает и зачем призван на страницу, так малость логичнее и семантичнее ;)
                                                              0
                                                              Гмм… Ну так автор говорит, что если указать внутри контейнера margin футер может уплыть вниз на величину этого margin'а и предлагает заменить его padding'ом. Лично я не знаю способов нарисовать border по краю блока с внешним отступом не используя margin или дополнительный контейнер (а-ля .outer { padding: 10px } .outer > .inner { border: 1px solid red })
                                                                0
                                                                а я знаю, сделать это верхним бордером футера :) футер-то как раз познимится на эти 150px ;)
                                                                  0
                                                                  :)))

                                                                  во-первых, это будет граница ниже отступа, а нужно границу выше отступа

                                                                  во-вторых, если нужны границы у 3 колонок, между которыми по 10рх отступ — тогда как? нет, можно, конечно, добавить div'ы с бордерами, но это опять-таки лишние элементы. то есть, «кто чего боится, то с тем и случится» :)

                                                                  зы: способ, конечно, хорош и применим в некоторых условиях… но применять нужно с опаской :) «вдруг завтра заказчик захочет бордер» :)
                                                                    0
                                                                    не, подождите, помоему Вы сами запутались, если Вам нужно отсупить ещё на 10px и там сделать бордер, то конечно прийдется использовать ещё один оберточный див, но за больше чем год моей работы с такой техникой подобных задач не встречал, а вот задачу чтобы НА ГРАНИЦЕ между футером и контентом был бордер — были.
                                                                    Предположим что футер 100px в высоту тогда просто делаем
                                                                    .outer {
                                                                    padding-bottom: 100px;
                                                                    }
                                                                    .footer {
                                                                    height: 100px;
                                                                    margin-top: -100px;
                                                                    border-top: 1px solid red;
                                                                    }
                                                                    и все, линия получается точно на грнице между ними, кстати есть ещё версия:
                                                                    .outer {
                                                                    padding-bottom: 100px;
                                                                    }
                                                                    .footer {
                                                                    height: 100px;
                                                                    margin-top: -110px;
                                                                    padding-top: 10px;
                                                                    border-top: 1px solid red;
                                                                    }
                                                                    тогда линия залезет на 10px вверх на контент, на самом деле Ваша задача легко решается нужно только искать решения ;)
                                                                  0
                                                                  а ещё если у Вас не одноколоночный сайт, то Вы вложите в обертку колонки, у них теоретически тоже можно указывать бордер… все зависит от задачи ;)
                                                            0
                                                            не, на самом деле мы получаем точно такой же один дополнительный див, но в нашем случае он не пустой, он служит оберткой для всего кроме футера, я обычно называю его class=«not_footer» и сразу становится ясно че он делает и зачем призван на страницу, так малость логичнее и семантичнее ;)
                                                            • UFO just landed and posted this here
                                                                0
                                                                ну на самом деле прелесть метода помоему в том, что он подходит абсолютно везде (ну по крайней мере я себе такой макет не представляю где он не подойдет), тянучка не исключение ;)
                                                                0
                                                                столкнулся с подобной задачей, только есть нюанс. весь контент лежит на листе бумаги с отступами по 50 пикселей от верха и низа. лист тянется по высоте. соответственно футер должен плавать. кроме листа бумаги у страницы есть свой бэк. может кто сталкиваться, как сформировать эти отступы?
                                                                  0
                                                                  в гуглохроме футер утыкается вниз, причем более чем — появляется вертикальная полоса прокрутки. Не пойму пока, в чем проблема.
                                                                    0
                                                                    ступил, сорри) все работает!
                                                                      +1
                                                                      спустя три года кто-то еще комментирует… я определенно пришел к успеху.

                                                                  Only users with full accounts can post comments. Log in, please.