Box-модель в CSS

Box-модель в CSS - это ключевой момент. Каждый элемент на странице определяется прямоугольником, покрывающим этот элемент. Понимание того, как это работает - основа успешной вёрстки. Давайте рассмотрим как элемент влияет на элементы, лежащие вокруг него, а также обсудим вопросы отображения различными браузерами.

В первую очередь, рассмотрим как точно рассчитывается размер элемента. Взгляните на диаграмму:

Если вы пользуетесь firebug-ом, то вы уже использовали похожую диаграмму:

Обратите внимание, что в обоих примерах внешние отступы (margin) зарисованы белым цветом. Внешние отступы уникальны тем, что они не влияют на размер самого элемента, но зато оказывают влияние на соседние, и тем самым составляют важную часть box-модели.

Размеры самого элемента рассчитываются следующим образом:

Width width + padding-left + padding-right + border-left + border-right
Height height + padding-top + padding-bottom + border-top + border-bottom

Что если значение не указаны?

Если вы используете CSS reset, то значения для внутренних отступов и границ будут нулевыми, иначе они будут равны значениям по умолчанию для используемого браузера (которое не обязательно является нулевым).

Если ширина элемента не указана (а элемент является блочным), то всё немного проще. Давайте начнём с этого, а затем перейдём к другим вопросам, которые необходимо знать о box-модели.

Ширина по умолчанию для блочных элементов.

В случае если вы не объявили ширину, а элемент имеет статичное (static) или относительное (relative) позиционирование, то ширина будет 100%, а внутренние отступы и границы будут считаться частью этой ширины. Однако если вы явно укажите ширину равной 100%, то внутренние отступы будут добавляться к основной ширине.

Смысл в том, что в этом случае ширина элемента на самом деле не 100%, а то что осталось после обработки внутренних отступов и границ. Это особенно полезно знать, поскольку существует множество случаев когда удобно либо установить ширину, либо не устанавливать её.

Самым неприятным моментом я нахожу то, что для элемента textarea, которому очень часто необходимо установить ширину, необходимо указывать атрибут col. Таким образом у нас не получится сделать его ширину равной 100%. В статической вёрстке мы, конечно можем подогнать окружающие элементы, но как поступать при плавающей разметке?

Элементы с абсолютным позиционированием

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

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

Обтекаемые элементы

Такое же точно поведение наблюдается у элементов с установленным свойством float. Элементу устанавливается ширина, минимально необходимая для того чтобы вместить контент, расширяется до ширины родительского элемента (хотя относительное позиционирование уже необязательно). Из-за хрупкой природы этих "бесширинных" элементов, они практически не используются в критически важных сценариях. Если вы, например, сделали сайдбар, указав для div какой-нибудь float, и не установили ширину, то каждый элемент внутри него ответственный за размер этого сайдбара.

Строчные элементы тоже прямоугольники.

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

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

Особенность обработки в IE6

В Internet Explorer 6.0, при неустановленном doctype, есть одна существенная разница при расчёте размеров элементов. Если во всех браузерах под шириной подразумевается ширина контента, то в IE6 - это ширина вместе с внутренними отступами и границами. Точно также и с высотой.

Хочу увидеть всё собственными глазами

Хотите посмотреть как формируется ваша страница? Попроьуйте дописать в ваш стилевой файл следующее:

* { border: 1px solid red !important; }
Опубликовано: 12.12.2009 Просмотров 33542 Ссылка на оригинал Tweet it!
10 comments  

Andrey

2009.12.15 15:58

 Спасибо, очень полезный материал
 

Я

2009.12.17 18:23

 А я думал я один такой дебил, который пишет border: 1px solid red !important; при отладке верстки :)
 

Игорь

2009.12.19 15:43

 Большое спасибо, для себя уяснил некоторые моменты которые раньше вызывали недоумелую улыбку!
 

Stasovsky

2009.12.21 02:28

 а я всегда писал border: 1px solid #f0f !important; =)
 

Александр

2010.01.21 15:38

 Статья полезная, но недостаточно детальная.
А вот за способ визуализации со * {} - спасибо!
Не знал что с помощью звездочки можно задать стиль для всех элементов.
 

basilkot

2010.01.21 15:44

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

    Хотя, если посоветуете тему, или у вас есть какие-то вопросы, я смогу дополнить, а то и написать статью :)

Григорий

2010.10.27 15:21

 Ну что можно сказать... Толково. Объять необъятное невозможно, как говориться, но для начала очень даже подошло.
Спасибо. У
 

Sober

2010.11.17 13:14

 Или я чего то не догоняю или перевод не совсем точный и перемешивает в голове всё:
текст:
"то ширина будет 100%, а внутренние отступы и границы будут располагаться внутри этой ширины, а не снаружи. Однако если вы явно укажите ширину равной 100%, то внешние отступы будут считаться снаружи. "

"а внутренние отступы и границы будут располагаться внутри этой ширины, а не снаружи" - так и должно же быть что внутреннее - внутри, внешнее - снаружи.

"то внешние отступы будут считаться снаружи" - собственно, снова, так и должно быть - внешние снаружи
 

basilkot

2010.11.17 14:37

  • Да, вы правы, напутал в этом месте.

    Смысл в том, что padding-и, при явно указанной ширине, отсчитываются дополнительно, то есть они тоже оказываются снаружи.

    В качестве примера могу привести следующее, Если вы хотите, обвести, скажем div, шириной 100px, а внутри сделать отступ 10px, то вам надо написать такой стиль:

    #somediv
    {
    border: 1px solid black;
    padding: 10px;
    width: 80px; /* 10px слева 10px справа дадут вам 100px */
    }

    Тоже самое про ширину в процентах.

    Однако же если вы не установите явно ширину, но добавите padding-и, то элемент впишется ровно по размеру родительского элемента.

    Исправил в статье.

pigmalion

2010.12.30 15:40

 весь сайт в закладки
 

Hello_O

2011.03.27 13:31

 pigmalion +1
 

karakum

2014.09.30 06:35

 basilkot, привет!
 

Оставить после себя комментарий

user

2016.11.23

Отправить сообщение:

Email

Сообщение