На главную

Библиотека Интернет Индустрии I2R.ru

Rambler's Top100

Малобюджетные сайты...

Продвижение веб-сайта...

Контент и авторское право...

Забобрить эту страницу! Забобрить! Блог Библиотека Сайтостроительства на toodoo
  Поиск:   
Рассылки для занятых...»
I2R » Сайтостроительство » CSS

Резиновая раскладка

Продолжение. Предыдущие материалы:

14.06.06
Автор статьи, Иван Сагалаев предупреждает, что данный материал предоставляет собой текущие заметки по теме, а не законченную работу.
Ваши комментарии и дополнения к статье приветствуются в авторском блоге Маниакальный Веблог

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

Тем не менее, я подумал, что такой пример все же будет полезен, потому что наглядно показывает, на какие ухищрения надо идти при использовании неподходящих инструментов. То есть это будет скорее отрицательный пример. Больше того, в этой статье будет пример сразу двух вариантов: один другого кривее :-).

Общий принцип

Сам по себе предыдущий макет, в общем-то, уже сверстан достаточно гибко. Ширины всех колонок заданы в процентах, а единственное, что его держит в рамках — это явно проставленная в пикселах ширина <body>. Если ее убрать, то раскладка должна нормально тянуться.

Но наступлению счастья, к сожалению, мешает фоновая картинка, которая визуально представляет колонки. Она, конечно, тянуться не будет и весь колоночный вид собьет. Поэтому с фоном надо что-то придумать.

Решение усложняется тем, что колонок в макете — три. В случае двух колонок фон достаточно было бы сделать пошире и повесить на странице в нужном месте, как я описывал в комментарии к статье про float’ы. С тремя же колонками картинку эту надо как-то разорвать на две, потому что тянуться она не может.

Итак, приступим…

Растягивание

Начниаем с того, что убираем у <body> его ширину в 700px. А чтобы оно не занимало всю ширину окна, закрывая мой любимый фоновый узор, надо дать margin’ы справа и слева:

body {
  padding:0;
  margin:0 50px;
  min-height:100%;
  position:relative;
}

Значения padding, min-height и position — это не что-то новое, они остались из предыдущей раскладки.

Есть одна проблема, тем не менее. Если подвигать ширину окна в IE, то можно заметить, что колонка новостей хаотично скачет вниз и обратно. Это от того, что при некоторых размерах что-то там не так округляется и 20% + 55% + 25% оказываются больше 100% буквально на 1 пиксел, и колонка не влезает. Чтобы это починить можно, например, добавить центральной колонке справа отрицательный margin, который и будет давать нужный люфт. Для этой колонки как раз уже есть специально для IE правило, исправляющее один из предыдущих багов, добавим margin туда:

* html #main {
  margin-left:10%;
  margin-right:-1px;
}

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

Вариант 1: картинки в колонках

Первый способ разделить картинку — это снять цельную у <body>, разделить на две части, которые находятся непосредственно под колонками, и назначить их самим колонкам:

body {
  background:white;
  color:black;
}
#sections {
  background:url(left-col-bg.png) #A6BDFF right top repeat-y;
}
#news {
  background:url(right-col-bg.png) white left top repeat-y;
  color:#293499;
}

Про картинки тут стоит сказать отдельно. Обе они не бесконечной ширины, вот левая:

… и правая:

Они прижаты к внутренним краям колонок, и когда те становятся шире фона, надо проследить, чтобы цвет, который будет проглядывать из под картинки сливался с ней красиво. Это оттенок голубого с правого края картинки для левой колонки и белый — для правой. Задаются они, как видно, в тех же правилах, что и сам фон.

Дальше нужно сделать так, чтобы фон продолжался дальше, а не обрывался сразу после текста колонок. Для этого подойдет способ с очень длинными padding’ами, который я описывал в статье про float’ы. Добавим это к правилам раскладки колонок:

#sections {
  float:left; width:20%; margin-left:-75%;
  padding-bottom:32767px; margin-bottom:-32767px;
}
#news {
  float:right; width:25%;
  padding-bottom:32767px; margin-bottom:-32767px;
}

И вот как это выглядит.

Теперь колонки заканчиваются на одной высоте, но продолжаются не до конца, а обрываются по самой высокой из них. Это происходит потому, что их обрезает там блок #content, который имеет автоматическую высоту и overflow:hidden. Отказаться от этого нельзя, потому что иначе все длинные хвосты колонок будут отображаться и страница приобретет довольно длинный скроллер :-).

Ему также нельзя поставить min-height:100%, потому что у его контейнера (<body>) четкая высота не задана, а, напомню, 100% от незаданного браузер посчитать не может. Да и все равно это бы выглядело плохо, потому что будь #content в точности высоты окна, из-за того, что он начинается не сверху, а под блоком заголовка, он бы заталкивал подвал ниже нижнего края.

В этом состоит минус первого варианта: придется отказаться от эффекта “страница не короче окна”. Для этого все правила для позиционирования подвала нужно удалить:

body {
  padding:0;
  margin:0 50px;
  min-height:100%;
  position:relative;
}
 
* html body {
  height:100%;
}
#meta {
  position:absolute; bottom:0;
  height:40px; width:100%;
  padding:1px 0;
}
 
#content {
  padding-bottom:42px;
}

Получится так.

Еще один маленький штрих. Если посмотреть на плашки меню слева и на заголовок “Новости” справа, то видно, что они залезают на пунктирные линии, чего не было в изначальном фиксированном варианте. Теперь это происходит от того, что фоновые картинки лежат в блоках колонок, и все их содержимое, конечно же, лежит сверху фона. Самое естественное решение отодвигания содержимого от края — это padding. Но если его добавить, то увеличится и размер блока, колонки станут шире и не уместятся в раскладку. Поэтому, чтобы это компенсировать, надо добавить к padding’у отрицательный margin такого же размера:

#sections {
  float:left; width:20%; margin-left:-75%;
  padding-bottom:32767px; margin-bottom:-32767px;
  padding-right:1px; margin-right:-1px;
}
#news {
  float:right; width:25%;
  padding-bottom:32767px; margin-bottom:-32767px;
  padding-left:1px; margin-left:-1px;
}

Вот теперь этот вариант готов.

Вариант 2: плавающие фоны

Итак, размещение фона в колонках с очень длинными хвостами заставляет их жестко обрезать, и убивает идею о минимальной высоте раскладки. Чтобы этот эффект сохранить, надо вернуться к первоначальной идее: размещать фон в общем для всей раскладки контейнере.

Таким контейнером в фиксированной раскладке работал <body>, но сейчас этого не хватит, потому что в один блок в текущей версии CSS можно положить только один фон. А нам их нужно два, которые будут разъезжаться в разные стороны. Поэтому придется добавить еще один блок, чтобы держать вторую часть фона.

Здесь я хочу сделать паузу и для важного замечания. К сожалению, большинство верстальщиков, которые начинают изучать CSS’ную верстку, воспринимают ее как просто другой синтаксис верстки “вместо таблиц”, полностью игнорируя сам смысл подхода с разделением структуры содержимого и оформления, о котором я писал в первой статье про “компот и мух“. Поэтому идея добавить в HTML пару лишних <div>ов не вызывает даже секундного раздумья.

Нет в CSS-верстке хаков хуже тех, которые изменяют структуру HTML-документа для чисто оформительских целей.

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

Ну да ладно. Представим, что у вас дома семья из пяти голодных ребятишек, а заказчик обещает заплатить 3 миллиона долларов за трехколоночный макет с прижатым к низу подвалом. Займемся.

Для начала уберем все предыдущие правила для предыдущего варианта с фоном в колонках и уберем фон у <body>. Получится такая отправная точка.

Теперь дополнительный контейнер. Обычно его вкладывают внутрь существующего на манер матрешки:

<body>
  <div id="container">
    <остальной контент>
  </div>
</body>

Но нам этот способ не подойдет. Наша цель, чтобы он имел ту же высоту, что и <body>, но, как я уже упоминал раньше, для <body> у нас высота не задана, а значит никакие height:100% и min-height:100% работать не будут, внутренний контейнер не будет дотягиваться до низа. Написать <body> четкую высоту тоже, очевидно, нельзя, потому что тогда оно перестанет тянуться вниз, когда текста много. Что делать?

Наверное есть какие-то нерадикальные способы, но я не нашел другого, кроме такого вот… хм… извращения (по-другому и не назвать):

  1. <body> назначается position:absolute и min-height:100%. Оно в этом случае визуально никак не изменится, останется висеть на том же месте.
  2. Дополнительный контейнер, делается просто пустым блоком в начале <body>, не заключающим в себя остальное содержимое. Он тоже позиционируется абсолютно, ему назначаются высота и ширина в 100%. А дальше он перемещается под <body> с помощью отрицательного z-index’а.

Таким образом достигается то, что и <body>, и дополнительный контейнер полностью совпадают геометрически. В коде это выглядит так.

HTML:

<body>
  <div id="body2"></div>
  ...

CSS:

body {
  padding:0;
  margin:0 50px;
  min-height:100%;
  position:absolute; z-index:0;
}
#body2 {
  position:absolute;
  height:100%; width:100%; z-index:-1;
}

Внимательные читатели, у которых к этому месту еще не болит голова, заметят одну странность. Я говорил, что невозможно расположенному внутри <body> контейнеру сделать высоту 100%, потому что у <body> высота не задана. Однако здесь сделано именно так.

Почему? Я не знаю :-). Судя по всему, абсолютно позиционированные блоки ведут в этом отношении себя чуть менее привередливо, чем статические. Я попробую порыться в спецификации CSS, но не уверен, что что-нибудь найду. Возможно, это просто синхронный баг Firefox’а и IE, в других браузерах я не смотрел.

Теперь дело за малым: повесить плавающие фоны, имитирующие каждую из колонок. Плавающий фон представляет собой очень длинную горизонтальную картинку, такую, чтобы она была шире любых разумных разрешений экрана. Пусть будет 4000 пикселов. Дальше эта картинка делится по ширине в том же отношении, что и ширина колонки: например левая колонка имеет ширину 20%, значит картинка для нее разделится на части 800 пикселов слева и 3200 — справа. Для правой колонки — аналогично.

И дальше их крайние части зарисовываются фоном колонок, а оставшееся оставляется прозрачным (обозначено серым фоном):

Картинки, кстати, в формате png, хотя считается, что прозрачность в этом формате не поддерживает IE. На самом деле, он не поддерживает только переменную прозрачность. Если же картинки перевести в индексированную палитру из 256 цветов, то все работает.

Теперь прикрепим их в нужные точки:

body {
  background:url(left-body-bg.png) 20% 0 repeat-y;
  color:black;
}
#body2 {
  background:url(right-body-bg.png) 75% 0 repeat-y;
}

… и получим практически то, что надо.

“Секрет” правильного расположения фонов заключается в том, что цифра позиции фона (20% и 75%) означает точку и в ширине контейнера, и в ширине самой картинки. Именно поэтому “0″ означает помещение левой стороны картинки к левому краю, “50%” — середины картинки в середину, а “100%” — правой стороны к правому краю. И при сжимании и разжимании окна картинка всегда будет “ездить”, прицепившись своими 20% или 75% к тем же позициям.

Остался фон внутри средней колонки, который я специально оставил отдельно. Сейчас два фона лежат один под другим: <body> выше, #body2 ниже. И чтобы достигнуть нужного эффекта, по идее, достаточно было бы закрасить белым то пространство, которое у нижней картинки прозрачное. Если бы не Internet Explorer :-).

Я затрудняюсь это объяснить понятным способом, но получается так, что z-index:-1, назначенный дополнительному контейнеру #body2, действительно уводит его под <body>, но не до конца, а только под содержимое. Фон же <body> остается все равно в самом низу. Таким образом, если картинку “как-бы-нижнего” блока зарисовать белым, то в IE она перекроет картинку левой колонки.

Исправляется это очередным хаком (последним на сегодня). Мы зарисуем просто белым цветом фон <body> для IE, и фон нижнего контейнера — для остальных:

html>body #body2 {
  background-color:white;
}
* html body {
  background-color:white;
}

Хак html>body обладает эффектом, обратным * html. Так сложилось, что IE игнорирует этот селектор, а остальные нормально его применяют.

Готово.

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

Резюме

Помимо того, что я уже много раз сказал о том, что имитация колонок CSS’ом — неблагодарное занятие, я хочу сделать еще одно важное замечание.

Не существует никакого Универсального Способа Трехколоночной Раскладки. Те решения, которые я описал выше, оказались бы непригодными, для, скажем, другого фона или для непроцентного поведения колонок или подвала с нефиксированной высотой. Там не возникло бы описанных трудностей, но возникли бы совершенно другие. Поэтому я все время ставлю ссылки на предыдущие статьи “Учебника” и призываю читать их и понимать (и спрашивать).


Предыдущие материалы:

 

 

Эта статья - часть находящегося в процессе написания цикла под рабочим названием “Учебник”. Я рекомендую ознакомиться и с другими статьями, которые можно найти в категории “Учебник“, где они сейчас собраны в обратном хронологическом порядке.

Статьи по теме:

Автор: Иван Сагалаев
Источник: Маниакальный Веблог

Спонсор раздела

Рассылки Subscribe.ru:

Библиотека сайтостроительства - новости, статьи, обзоры
Дискуссионный лист для web-разработчиков
Подписка на MailList.Ru
Автор: NunDesign
Другие разделы
Оптимизация сайтов
Web-студии
» Новое в разделе
Web-дизайн
Web-программирование
Интернет-реклама
Раскрутка сайта
Web-графика
Flash
Adobe Photoshop
Рассылка
Инструменты вебмастера
Контент для сайта
HTML/DHTML
Управление web-проектами
CSS
I2R-Журналы
I2R Business
I2R Web Creation
I2R Computer
рассылки библиотеки +
И2Р Программы
Всё о Windows
Программирование
Софт
Мир Linux
Галерея Попова
Каталог I2R
Партнеры
Amicus Studio
NunDesign
Горящие путевки, идеи путешествийMegaTIS.Ru

2000-2008 г.   
Все авторские права соблюдены.
Rambler's Top100