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

Сущность бокса

Все элементы веб-страницы — фактически все, что ограничено какими-либо тегами — представляется в CSS прямоугольными областями, которые как раз и называются боксами. Например, в такой вот страничке:

<body>
<h1>Заголовок</h1>
<p>Абзац</p>
</body>

... элемент body составляет один бокс, в него вкладываются боксы элементов h1 и p.

На самом деле, даже внутри h1 и p организуются свои боксы для каждой строчки текста, но это дебри, и сейчас я про это распространяться не буду.

Боксы обладают двумя очевидными свойствами:

Вложение боксов друг в друга, а также изъятие одних из других будет обсуждаться в следующих статьях про раскладку, а вот по поводу размеров я как раз и хочу поговорить особо.

Размер любого бокса складывается из ширины и высоты области содержимого, отступов, толщины рамок и границ. Наглядно это выглядит так:

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

По-русскиПо-английскиСмысл
область содержимого content area здесь располагается содержимое бокса: текст и другие вложенные в него боксы
ширинаwidth-
высотаheight-
отступы padding отступ от невидимых границ содержимого до рамки, на него, кстати, распространяется фон бокса, если он есть
рамка border рамка вокруг содержимого, которая, помимо декоративного эффекта, тоже влияет на размер всего бокса из-за своей толщины
границы margin отступы от рамки до других, внешних боксов

Засада

В CSS принято, что при задании размеров областей бокса отступы, толщина рамки и границы добавляются к размерам области содержимого. Звучит логично? Вроде того... Возьмем такой кусок HTML'а:

<body>
  <h1>Красивый заголовок на синем фоне</h1>

И теперь мы хотим, чтобы заголовок был, собственно, на синем фоне, занимал по ширине все доступное пространство, а вокруг него было белое пространство, скажем, в 10 пикселов:

h1 {
  width:100%;
  margin:10px;
  color:white; background-color:blue;
}

Синтаксис, думаю, объяснять, не надо, он очевиден. Так вот, если мы посмотрим на результат в браузере, который правильно обрабатывает эти самые боксы, то увидим такое:

Явно не то, что хотелось: заголовок зачем-то уехал за правый край, да еще и скроллбар появился, который не убирается, как окно ни растягивай. Это не глюк. Это происходит как раз от того, что границы — по 10 пикселов с каждой стороны — добавились к той ширине, которую мы указали — 100%. И общий размер всего бокса теперь всегда будет по ширине на 20 пикселов больше того, в котором он лежит ("контейнера").

Об этом эффекте необходимо помнить все время, когда вы раскладываете что-то CSS'ом, потому что он, вообще-то, не совсем интуитивно понятен. Мне, помнится, гораздо чаще хотелось, чтобы было можно наоборот: задать граничные размеры какого-то бокса, чтобы он точно вместился, куда надо, а уж внутрь делать всяческие отступы. Однако, это, все же, не ошибка разработчиков стандарта. Есть также немало случаев, когда такое поведение необходимо. Например, если у вас есть картинка с заданными размерами, и вы хотите вокруг нее небольшой отступ и рамочку, то вы хотите их именно вокруг, а не чтобы они влезли внутрь картинки и сжали изображение.

Практический нюанс

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

Просто лишь помнить о таком поведении размеров бокса мало. На практике приходится еще и бороться с браузером Internet Explorer (для Windows) версий 5 и 6. Исторически сложилось так, что разработчики 5-й версии IE реализовали расчет размеров бокса исходя именно из человеческой интуиции, а не из стандарта (и в этой версии пример с синим заголовком выглядит именно как задумывалось). К 6-й же версии они эту ошибку исправили, но исправили не кардинально, а сделали два режима работы браузера: один, совместимый со своей старой версией, а другой — совместимый со стандартом. Все же новые браузеры (насколько я знаю, без исключений) работают именно по стандартному алгоритму.

Как вы уже поняли, для дизайнера это означает необходимость что-то где-то подхачивать, что не может не огорчать. Но такова жизнь. Я для этого пользуюсь такими подходами:

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

    Остается еще IE6. Все, что нужно сделать, чтобы перевести его в стандартный режим - это написать первой строкой HTML-файла такую штуку:

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
    

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

  2. Не использовать margin'ы, border'ы и padding'и одновременно с заданием размера через width и height. К этому правилу, на самом деле, приходится часто прибегать и вне зависимости от IE5. Например, если вы делаете боковушку с навигационными меню шириной 100 пикселов и вам хочется, чтобы у ней был красивый отступ внутри в 5 пикселов, то вы просто не можете его поставить, потому что тогда боковушка будет занимать 110 пикселов в ширину и наедет на какой-нибудь другой бокс, находящийся рядом с ней.

    Для этих вещей есть другие подходы, на них я еще остановлюсь подробно, когда буду описывать конкретные примеры раскладок.

  3. Если все же очень нужно заставить IE5 отображать раскладку верно, то можно прибегнуть к известному хаку: Box Model Hack. Здесь его приводить не буду. Вкратце суть его заключается в том, что сначала пишется больший размер бокса (с учетом поведения IE5), потом некая хитрая бессмыслица, а потом размеры бокса для стандартных браузеров. Фокус в том, что эта самая бессмыслица воспринимается IE5 (и только им - это другой его баг) как начало комментария, и повторное задание размеров он пропускает. Остальные же браузеры его видят и переопределяют первое, неправильное.


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

Комментарии: 18

  1. slaff

    Мне это не в новинку, но написал отлично! на 5+

    Заношу в мемориз.

  2. Andy

    Написано отлично
    ЗЫ. Посмотри как отображается RSS в частности в Abilone

  3. raymond

    Тема интересна. Жду продолжения.

  4. Никита
  5. Alex

    Очень грамотно и доходчиво

  6. Kildor

    box-sizing: — для оперы
    -\moz-box-sizing — для гекконов.
    позволяет переключаться между стандартным/w3c-модель (content-box) и квиркмодом/традиционная модель (border-box)
    http://www.quirksmode.org/css/box.html

  7. Xansen

    Классно написано! Давно искал эту информацию во всяких учебниках, но у тебя всё написано просто ИДЕАЛЬНО! Так держать. Автору РЕСПЕКТ!

  8. Константин

    http://www.umade.ru/resources/css/boxmodelhack/boxmodelhack.html

    К сожалению, куча грубых смысловых ошибок при переводе.

  9. Gallina

    ОТЛИЧНО!!! Для начинающего веб дизайнера то что надо! все выложено просто и понятно

  10. этнический друпал

    Ещё один перевод Box Model Hack:
    http://www.webmascon.com/topics/coding/38a.asp

  11. Inna

    Спасибо! Очень нужная вещь!
    Кое-что было известно, но теперь такие вещи буду знать наверняка=)

  12. all

    жаль вот только то что css3 еще нескоро будет общеюзерно супортитцо

  13. Dr.AKULAvich

    За доступную подачу материала отдельное спасибо.
    Буду читать весь цикл :-)

  14. vayme

    Все просто и доходчиво. Давно пытаюсь разобраться с CSS, да все руки на доходили. Спасибо!

  15. nika

    Здорово написано! Спасибо!
    Начинаю структурировать свои хаотические знания css с целью создания своего сайта, надеюсь ваши статейки по верстке мне помогут!

  16. Kunin

    Хорошая статья. В верстке новичок. Занимаюсь дизайном, пришло время научиться верстать смоделированое )). Спасибо за хороший ресурс. Однозначно в закладки.

  17. charnad

    Спасибо, буквально недавно столкнулся с этим. Но как я понял стоит заранее расчитывать ширину с учетом margin.

  18. Сергей

    Сейчас такой тип вёрстки называют не боксовым, а блочным.
    PS: Прошу прощения за устаревший на 4,5 года комментарий.

Добавить комментарий