Тэги делятся на строчные и блочные. Мы это уже знаем. Блочные тэги выводятся браузером с новой строки, например P, DIV, H1-H6.
Если мы задаём стиль текста для блока, то этот стиль будет применен ко вложенному тексту. Но есть некоторые css-свойства, которые, как правило, применяют только к блокам. Например отступы (внешние), поля (внутренний отступ), фон, граница (бордюр) и т.п.
Прежде, чем мы приступим к рассмотрению блочных свойств, необходимо разобраться с т.н. блочной моделью. Тут нюанс в том, что эта модель построена нелогично для нашего повседневного восприятия. Поэтому для верстальщика необходимо просто её изучить и использовать как данность. Многие вебмастера спотыкаются именно на этом вопросе.
Блочная модель
Для экспериментов сделаем простой DIV-блок. Напомню, что в текстовом редакторе HTML-код нужно обрамлять в [html]. Здесь, для простоты, я его буду опускать.
<div style="color: red;"> текст блока </div>
Очевидно, что текст этого блока будет красным. Теперь рассмотрим свойство background - с его помощью можно указать фон блока.
<div style="color: red; background: yellow;"> текст блока </div>
В этом примере фон блока стал желтым.
Обратите внимание, как распределился блок на странице - он стал 100% ширины записи. Это одна из особенностей блоков - по-умолчанию заполнять всю ширину родительского блока.
Очень часто такое поведение не совсем то, что нужно. Поэтому для блока можно указать размеры: ширину и высоту.
<div style="color: red; background: yellow; width: 300px; height: 200px;"> текст блока </div>
В данном примере я указал фиксированную ширину в px, однако можно использовать и относительные единицы, например проценты. Скажем при «width: 50%» блок займёт ровно половину ширины своего родителя.
Отступы
Следующая, наиболее частая задача при построении блоков - задание отступов. Отступы бывают внешние (margin) и внутренние (padding). Внутренние отступы часто называют полями. Единицы измерения - стандартные.
Существует два синтаксиса указать отступы. Первый - для каждой стороны. Второй - все стороны сразу.
- margin-top - верхний отступ
- margin-right - правый отступ
- margin-bottom - нижний отступ
- margin-left - левый отступ
Аналогично и для внутреннего: padding-top, padding-right, padding-bottom и padding-left.
Такая запись довольно длинная, поэтому чаще используется упрощенный вариант:
margin: верх право низ лево padding: верх право низ лево
Например:
margin: 10px 20px 30px 40px
будет эквивалентно:
margin-top: 10px; margin-right: 20px; margin-bottom: 30px; margin-left: 40px;
Для простого запоминания порядка верх-право-низ-лево мысленно используйте циферблат часов. Значение указываются по часовой стрелке сверху. Это правило используется и в некоторых других css-свойствах.
Если верхний отступ совпадает по значению с нижним, а правый с левым, то запись можно еще больше сократить:
margin: 10px 20px
будет эквивалентно:
margin-top: 10px; margin-right: 20px; margin-bottom: 10px; margin-left: 20px;
Если же у нас совпаают правое и левое поля, то запись может быть такой:
margin: 10px 20px 30px
будет эквивалентно:
margin-top: 10px; margin-right: 20px; margin-bottom: 30px; margin-left: 20px;
В вёрстке очень часто применяются такие сокращения, поэтому сразу разберитесь с этим вопросом.
Еще один важный момент: всегда нужно указывать единицы измерения. Единственное исключение - 0.
Теперь отступы на практике:
<div style="color: red; background: yellow; width: 300px; height: 200px; margin: 50px 0 0 150px;"> текст блока </div>
Поведение вполне очевидное - у нашего блока появились отступы сверху и слева.
Теперь тоже самое, только с внутренними отступами:
<div style="color: red; background: yellow; width: 300px; height: 200px; padding: 50px 0 0 150px;"> текст блока </div>
Поведение блока немного поменялось: у нас появились поля перед внутренним текстом. Это понятно. Но заметьте, что теперь размер блока увеличился! Если померить размеры, то окажется, что они увеличились ровно на размер отступов.
В этом одна из особенностей блочной модели: width и height относятся только к «внутренней» части блока (содержимое). Реальный же размер блока в браузере будет увеличен на размер отступов.
Для снятия размеров с экрана можно воспользоваться различными программами, например PicPick.
Границы
Границы - border добавляют к блоку еще порцию размеров. Свойство border проще всего задавать сразу «скопом»:
border: цвет размер стиль
Последовательность может быть произвольной.
Для задания границ с разных сторон используются: border-top, border-right, border-bottom и border-left.
Цвет и размер указывается как обычно. Стиль определяет вид линии. Полные варианты вы посмотрите в CSS-справочнике, я лишь остановлюсь на двух вариантах.
- solid - сплошная линия
- dotted - пунктирная линия
Посмотрим на практике.
<div style="color: red; background: yellow; width: 300px; height: 200px; margin: 50px 0 0 150px; border: 10px red solid;"> текст блока </div>
Если измерить размеры блока, то убедимся, что реальная ширина не 300px, а 320px - то есть физический размер блока стал больше на ширину границы (по 10px с парных сторон).
На этом моменте спотыкаются очень многие верстальщики. При отладке верстки, чтобы визуально выделить блок, они прописывают свойство border, что в итоге увеличивает физический размер блока и вёрстка «разваливается». Поэтому одно из правил опытного верстальщика - никогда не использовать border для отладки. Если нужно выделить блок, то используется background.
Поведение блочной модели
Рассмотрим следующий пример.
<div style="background: gold; width: 350px;"> <div style="background: yellow; width: 200px; height: 200px; margin: 20px; padding: 20px; border: red 10px solid;"> текст </div> </div>
Здесь задан вложенный блок. Для визуального разделения указан разный цвет фона. У вложенного блока мы указываем все отступы и границу.
Возьмём экранную линейку и измерим размеры внешнего блока. Тут без сюрпризов: поскольку мы не указали отступы и границы, то физический размер соответствует указанному width.
Размер внутреннего блока: width (200) + padding(20*2) + border(10*2) = 260px С этим понятно. Непонятно только почему внутренний блок расположен несколько необычно. Мы видим, что верхнего отступа у нас нет, хотя должен быть за счет верхнего margin...
Этот эффект называется «схлопывающиеся отступы». Прежде, чем с ним бороться попробуем разобраться в его сути.
Сделаем три внутренних одинаковых блока.
<div style="background: gold; width: 350px;"> <div style="background: yellow; width: 200px; height: 30px; margin: 20px; padding: 20px; border: red 10px solid;"> текст </div> <div style="background: yellow; width: 200px; height: 30px; margin: 20px; padding: 20px; border: red 10px solid;"> текст </div> <div style="background: yellow; width: 200px; height: 30px; margin: 20px; padding: 20px; border: red 10px solid;"> текст </div> </div>
Глядя на код мы предполагаем, что расстояние между блоками должно быть 40px (margin-bottom верхнего + margin-top нижнего). Однако на деле мы опять видим 20px! Получается, что если «встречаются» два margin, то в результате остается только один. Какой, верхний или нижний?
Проверим. Зададим разные margin:
<div style="background: gold; width: 350px;"> <div style="background: yellow; width: 200px; height: 30px; margin: 10px 0 30px 0; padding: 20px; border: red 10px solid;"> текст </div> <div style="background: yellow; width: 200px; height: 30px; margin: 20px 0 20px 0; padding: 20px; border: red 10px solid;"> текст </div> <div style="background: yellow; width: 200px; height: 30px; margin: 40px 0 10px 0; padding: 20px; border: red 10px solid;"> текст </div> </div>
Измерив все расстояния убеждаемся, что «встречные» margin уменьшаются до одного с наибольшим значением.
Схлопывание само по себе довольно полезное свойство (для текстов), но при верстке блоков, где требуется точное позиционирование может оказаться неприятным сюрпризом. Скажем на сайте может быть блок картинки и блок меню. Если не знать о «схлопывании», то можно до бесконечности пытаться подбирать отступы между блоками, если использовать margin для первого и второго блоков одновременно.
По нашей повседневной логике отступы должны суммироваться. У блочной же модели более сложный алгоритм.
Теперь вернемся к нашему первому примеру и разберемся почему исчезает верхний и нижний отступ.
Дело в том, что между DIV родительского блока и внутренним нет никакого «буферного» блока или текста. Таким образом отступы браузер считает от вложенного блока, верх которого совпадает с верхом родительского. То есть граница, которая определяется margin-top оказывается выше родительского блока, и как бы вываливается за его пределы.
Чтобы увидеть сей эффект в действии разместим перед и после нашего блока еще по блоку, чтобы визуально увидеть отступы:
<div class="bg-red">текст</div> <div style="background: gold; width: 350px;"> <div style="background: yellow; width: 200px; height: 30px; margin: 30px; padding: 20px; border: red 10px solid;"> текст </div> </div> <div class="bg-red">текст</div>
Мы видим отступы по 30px. Теперь уберем верхний и нижний margin и убедимся, что блоки слились.
Из этого можно сделать один важный вывод: для первого вложенного блока нельзя задавать margin-top. Вместо этого необходимо использовать padding-top родительского блока.
У схлопывающихся отступов есть еще одна интересная особенность. Если указать границу у родителя, то margin-top вложенного блока начинает работать как положено. :-)
Существуют и другие способы «борьбы» со схлопыванием, но об этом речь пойдет уже в других уроках.
Выводы
Блочная модель - достаточно сложная штука со своими нюансами и особенностями. Все примеры, которые приведены в этом уроке следует обязательно проделать самостоятельно. Все они имеют непосредственное отношение к верстке шаблонов.
Комментариев: 6 RSS
1Руслан26-01-2012 10:50
Классные уроки- как раз то, что мне надо!
Как подписаться на рассылку ? - где она ?.
2Аноним26-01-2012 11:27
Сбоку в сайдбаре форму добавил.
3Аноним02-02-2012 15:11
Респект! Подробно и толково изложено про отступы. В свое время столкнулся с тем, что возникали споры по поводу корректного перевода названий, типа: margin - это поле (дословный перевод), а paddigg дескать "набивка". Я же считаю, что margin - это отсуп, а padding - поле. У вас вышло более лаконично и понятно: внутренний и внешний отступ.
Про схлопывание часто слышал, но не обращал внимания, так как сам практически не сталкивался. Интересная темка для будущего поста. Данке! :)
4Swen13-02-2012 12:44
Респект автору! Грамотно и доходчиво объяснил ситуацию со "схлопывающимися" margin. Использование border для отладки - классическая ошибка начинающего вебмастера, как справедливо заметил автор. Сам сталкивался с этими проблемами в свое время, решил методом "научного тыка")))
5Аноним08-08-2012 13:48
Замечательная статья. Еще раз перечитал. Грамотный язык изложения, все подробно и понятно. Полностью развеивается ощущение магии блочной модели.
6Сергей18-10-2012 17:49
Максим, где-то в уроках была цветной макет блоков шаблона с разбивкой на родительские и вложенные div. Сейчас не могу найти её. Случайно не удалили?