Много занимаюсь версткой, потому возникают разные интересные задачи. Решил не оставлять без внимания этот интересный опыт.
Одна из таких задач, которая нередко возникают при верстке сайтов, желание заказчика «прибить» футер шаблона к нижнему краю окна браузера. Иначе, когда на странице мало контента, нижняя часть шаблона (футер) болтается как одна субстанция в проруби.
Дальше я показываю целых три способа как разместить футер у нижнего края экрана.
Для предметного разговора глянем на скелет HTML документа.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<html> ... <body> <div id="header"> ... </div> <div id="content"> ... </div> <div id="footer"> ... </div> </body> </html> |
Условно документ разделен на три части — есть шапка (div#header), содержательная часть (div#content) и футер (div#footer).
Фиксированное позиционирование (fixed).
Один из вариантов, который не решает задачу, но маскирует проблему — установка фиксированного позиционирования. Чаще всего фиксируется позиция как шапки так и футера, превращая документ в аналог свитка. Мы всегда видим верх и низ шаблона, а содержание прокручивается скроллингом, заходя под них.
Для фиксирования сверху мы пишем стили для шапки:
1 2 3 4 |
#header { position: fixed; top: 0; } |
А для футера это будет так:
1 2 3 4 |
#footer { position: fixed; bottom: 0; } |
Единственной проблемой будет то, что часть содержания будет скрыта шапкой и футером. Что можно решить, добавив соответствующий padding или margin для контейнера #content. На картинке ниже пример позиционирования для нашего случая.
В левой части — мы просто зафиксировали шапку и футер (их роль играют синие квадраты 100×100). Содержание оказалось перерытым шапкой. В правой части мы добавили padding для зеленого прямоугольника, играющего роль содержимого. Теперь отступы не дают перекрываться содержимому, и мы получили т.н. свиток — прокручивать контент можно скроллингом, если документ не умещается в видимой области.
Вот HTML код примера.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
<html> <style> #header { position: fixed; top: 0; background-color: #88F; height: 100px; width: 100px; } #content { background-color: #8F8; min-height: 300px; width: 150px; /* padding: 100px 0; */ } #footer { position: fixed; bottom: 0; background-color: #88F; height: 100px; width: 100px; } </style> <body> <div id="header">...</div> <div id="content"> <pre> 0000 0001 0002 0003 0004 0005 0006 0007 0008 0009 0010 0011 0012 0013 0014 </pre> </div> <div id="footer">...</div> </body> </html> |
Табличная магия. Позиционирование таблицей.
Таблица — это по истине чудесный элемент верстки. Он позволяет просто делать то, что нужно без лишних размышлений. Применительно к нашему случаю, роль всех трех элементов (шапки, содержания и футера) будет играть строки таблицы.
Так как таблица — это непрерывный объект (строки идут одна за другой), то проблем с перекрытием одного из трех элементов двумя другими не будет. Здесь мы получаем решение нашей задачи, но только для «нормальных» браузеров. А нормальные это все, кроме IE, как вы уже догадались.
На рисунке поверх Opera, результат рендеринга в IE Edge c эмуляцией 9й версии IE. В IE версий 10-11, результат аналогичен Opera.
Вот исходный пример (HTML код), который я тестировал.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
<html> <style> #total-wrapper { height: 100%; } #header { background-color: #88F; height: 100px; } #content { background-color: #8F8; } #footer { background-color: #88F; height: 100px; } #total-wrapper tr { vertical-align: top; } pre { width: 100px; margin: 0} </style> <body> <table id="total-wrapper" cellpadding=0 cellspacing=0 border=0> <tr id="header"><td>...</td></tr> <tr id="content"><td> <pre> 0000 0001 0002 0003 0004 0005 0006 0007 0008 0009 0010 0011 0012 0013 0014 </pre></td></tr> <tr id="footer"><td>...</td></tr> </table> </body> </html> |
Совместимость с IE можно повысить аж до 7 версии добавлением следующих стилей, задающих явно высоту родительских контейнеров:
1 |
html, body { height: 100%; } |
Впрочем, в 7 й версии нужно будет сделать ещё ряд манипуляций, чтобы привести таблицу к точно такому же виду. В последнее время проблема с IE не так остра, как ранее, доля старых версии этого браузера малозначительна, так что выпад в сторону IE — скорее моё нытье :), а не реальная проблема.
Снова элементы div. «Шаг назад».
Здесь мы возвращаемся к верстке с помощью div. Идея следующая — задать общий контейнер (#total-wrapper) 100% высотой — куда в нашем случае входят шапка и содержание, а футер разместить следом за ним с позиционированием absolute. При этом сделать как бы шаг назад — т.е. с помощью margin сместить футер вверх.
Здесь возникнет снова проблема с наложением футера на содержание, но мы уже знаем как с этим бороться.
В итоге получаем нужное нам свойство для футера — он прилипает к нижнему краю, если контента мало и нет полосы прокрутки, и сдвигается ниже, когда возникает вертикальная полоса прокрутки.
HTML для этого примера:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
<html> <style> html, body { height: 100%; margin: 0; } pre { margin: 0; } #wrapper-total { min-height: 100%; } #header { background-color: #88F; height: 100px; width: 100px; } #content { background-color: #8F8; width: 150px; padding-bottom: 100px; } #footer { position: absolute; margin-top: -100px; background-color: #88F; height: 100px; width: 100px; } </style> <body> <div id="wrapper-total"> <div id="header">...</div> <div id="content"> <pre> 0000 0001 0002 0003 0004 0005 0006 0007 0008 0009 0010 0011 0012 0013 0014 </pre> </div> </div> <div id="footer">...</div> </body> </html> |
Так как футер у нас 100 точек в высоту, то нужно вернуться на 100 точек вверх (margin-top: -100px). Ровно столько же надо зарезервировать места в контейнере содержимого (padding-bottom: 100px). Данный пример работает даже в эмуляции IE7.
Возможно, вы обратили внимание, что вместо height: 100%, я использую min-height: 100% для div#wrapper-total. В нашем случае оба варианта будут работать, но есть ещё кое что, о чем я расскажу в следующий раз :).