Пользователь
0,0
рейтинг
11 августа 2009 в 19:47

Разработка → CSS Sticky Footer / Прилипающий футер перевод

CSS*

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


Введение


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

Решения Райана Фэйта хорошо известно и работает, но требует лишний пустой <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. %. Используйте у себя на сайте что хотите. Автор предложил ДВА метода решения проблемы с разъезжающимися пропорциями, вам никто не запрещает и не навязывает использовать любой из них. Мы все здесь не маленькие и знаем, что такое хорошо, а что такое плохо.
Перевод: Steve Hatcher
Максим @waitekk
карма
169,3
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (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> я имел в виду. Код, надеюсь, приводить не надо?
  • НЛО прилетело и опубликовало эту надпись здесь
  • +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 раз лучше ;)
    • НЛО прилетело и опубликовало эту надпись здесь
  • 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» и сразу становится ясно че он делает и зачем призван на страницу, так малость логичнее и семантичнее ;)
  • НЛО прилетело и опубликовало эту надпись здесь
    • 0
      ну на самом деле прелесть метода помоему в том, что он подходит абсолютно везде (ну по крайней мере я себе такой макет не представляю где он не подойдет), тянучка не исключение ;)
  • 0
    столкнулся с подобной задачей, только есть нюанс. весь контент лежит на листе бумаги с отступами по 50 пикселей от верха и низа. лист тянется по высоте. соответственно футер должен плавать. кроме листа бумаги у страницы есть свой бэк. может кто сталкиваться, как сформировать эти отступы?
  • 0
    в гуглохроме футер утыкается вниз, причем более чем — появляется вертикальная полоса прокрутки. Не пойму пока, в чем проблема.
    • 0
      ступил, сорри) все работает!
      • +1
        спустя три года кто-то еще комментирует… я определенно пришел к успеху.

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