Расставляем точки над прижатым футером: возвращаясь к истокам
Начнем с примера №1 (смотреть в браузерах, понимающих CSS2.1 — IE8, Опере 7.5+, FF1+, любом Webkit-based и т.п.).
Классическая структура с тремя блоками. Всё валидно. Основной контент
идет раньше других блоков в коде — частое требование к современной
верстке ради доступности (скринридеры и т.п.), SEO и кучи других
резонов. Ни грамма JS. Никаких отрицательных отступов и фиксированной
высоты — высота «шапки» и «подвала» определяется их содержимым, а
основной контент занимает все оставшееся место (если хватает).
Семантично? На мой взгляд, вполне. А визуально — да, это самая что ни
на есть CSS-таблица, специально предназначенная (опять же, на мой
взгляд) для случаев, когда положения блоков зависят друг от друга и от
контейнера. За «магическую телепортацию» блоков к краям окна отвечают
два значения свойства display — table-header-group и table-footer-group. Я тоже практически не слыхал о них, пока коллега Fragster не показал мне чудесный пример… из которого со временем и вырос этот топик :)
Как видим, это поддерживается давно и прочно. Вот если б не IE7 и ниже, не понимающие «экзотических» значений display… Оказывается, поведение, задаваемое этими свойствами, доступно и этим «динозаврам»! Это демонстрирует пример №2.
Для «правильных» браузеров в нем ничего не изменилось по сравнению с предыдущим. Лишь комментарии (в head
и между блоками), не влияющие на семантику кода (поисковики,
скринридеры и т.д. их проигнорируют). А вот в старых IE произошла
«изящная деградация» к… старой доброй табличной разметке! И при этом
порядок блоков в коде остался тем же, семантичным. Возникает крамольная мысль, что антисемантичность табличной разметки сильно преувелиупс… я этого не говорил :)
Надо признаться, код, который в предыдущем примере получает IE7-, невалиден: по стандарту thead и tfoot (чье поведение имитируют table-header-group и table-footer-group) должны идти перед элементом tbody,
а не после. К счастью, для «всеядного» IEшного парсера это неважно. Но
иногда порядок табличных (с точки зрения визуальному отображения)
элементов бывает существенным для браузерного рендерера. Так, если в
примере №1 поменять местами .header и .footer, ломается отображение в Опере 9.2x и ниже: .footer выводится непосредственно под .header-ом.
В современных версиях Оперы (9.5 и выше) отображение уже не зависит от
порядка блоков (как и в других браузерах), но, поскольку Опера 9.2х
кое-где еще занимает существенный процент, приходится учитывать эту ее
особенность.
Внимательные читатели могли заметить, что в примере №2 используется expression.
Единственная его роль — растянуть среднюю строку на всю свободную
высоту таблицы (обход известного глюка IE7- в стандартном режиме,
игнорирующего заданную высоту строк «резиновой» таблицы и всегда
растягивающего их пропорционально). Поэтому даже при отключенном JS .footer останется прижатым — лишь основной контент немного «уползет» вниз от .header-а.
Принципиально обойтись без expression возможно. Например, так, как в примере №3
(там изменен порядок блоков, что вызовет упомянутую проблему в старых
Операх, но для некоторых аудиторий — напр., американской — это не
критично). «Экстремалы» прогресса могут вообще перевести старые IE в
Quirks mode (который там умеет нормально распределять высоту в
резиновых таблицах — парадокс!), а различия в боксовой модели
нивелировать CSS3-свойством box-sizing:border-box, поддерживаемым всеми современными браузерами (к тому же эта боксовая модель для многих удобнее). Лично я считаю один некритичный expression «допустимым злом». Зато в этом способе заведомо не возникнет других проблем, всплывших по ходу обсуждения исходного топика — конфликтов z-index-ов, «застревания» футера при ресайзе окна в Опере и т.п. Ну а чем в итоге пользоваться — решать, конечно же, вам!