Почему свойства ширины и высоты CSS не корректируются для заполнения?

Итак, сначала немного мяса, чтобы установить сцену:

HTML

<div id="container">
    <div id="inner">test</div>
</div>

CSS

#container {
    width:300px;
    height:150px;
    background-color:#d7ebff;
}

#inner {
    width:100%;
    height:100%;
    padding:5px;
    background-color:#4c0015;
    opacity:.3;
}

Это приведет к тому, что будет выглядеть во всех современных браузерах:

CSS interior width test showing the inner box exceeding the container

Теперь я знаю, что это стандартно-совместимое поведение (как я знал раньше, но подтвержденное в этом сообщении, и я также знаю, что если я включу этот код в внутренняя декларация CSS:

box-sizing:border-box;
-moz-box-sizing:border-box;
-webkit-box-sizing:border-box

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

Кажется (на первый взгляд) более логичным для меня, чтобы внутренний ящик всегда заполнял контейнер ровно на 100% ширины контейнера, независимо от заполнения или границы внутреннего поля. Я сталкиваюсь с этой проблемой все время, когда я пытаюсь установить ширину текстовой области на 100%, которая имеет границу или что-то вроде внутреннего пространства 4px... текстовое поле всегда будет переполнять контейнер.

Итак, мой вопрос: какова логика установки поведения по умолчанию для игнорирования границы и заполнения элемента при установке его ширины?

Ответ 1

Причина CSS использует модель окна как:

+---------------------
|       Margin
| +-------------------
| |     Border
| | +-----------------
| | |   Padding
| | | +---------------
| | | | Width x Height

Это потому, что CSS является языком моделирования документов. Он был (первоначально) разработан с документами исследований и другими формальными документами в виду, а не как способ сделать красивую графику. Таким образом, модель вращается вокруг содержимого, а не контейнера.

CSS не является языком программирования, он является языком стиля. Он явно не указывает документу, как он должен отображаться, он предлагает некоторые рекомендации, которым должен следовать браузер. Все они могут быть перезаписаны и изменены с помощью реального языка программирования: JavaScript.

Возвращаясь к идее модели контента, рассмотрим следующий CSS:

p
{
  background-color: #EEE;
  border: 1px solid #CCC;
  color: #000;
  margin: 10px;
  padding: 9px;
  width: 400px;
}

height не указывается, поскольку контент определяет высоту, он может быть длинным, он может быть коротким, но неизвестным и несущественным. width установлен на 400px, потому что это должно быть как можно больше содержимого (текста).

padding - это просто способ расширения цвета фона, чтобы текст мог быть хорошо различим от краев, точно так же, как вы оставляете пространство при записи/печати на листе бумаги.

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

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

Для поддержания текучести width по умолчанию используется auto, что означает, что ширина будет как можно шире:

  • без чрезмерного использования содержимого
  • без заполнения, выходящего за пределы его контейнера

Конечно, в случаях с краем, прокладка будет выходить за пределы ее контейнера, потому что содержимое может быть сжато. Все о содержании.

Ответ 2

Возможно, вы захотите просмотреть следующее в w3c: http://www.w3.org/TR/CSS21/box.html

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

После заполнения наступает граница, если таковая имеется. Затем Margin применяется за пределами границы. Это означает, что фактическая ширина элементов определяется как: Ширина + Прокладка + Граница + Маржа.

В действительности, css, вы определили внутренний ящик с областью содержимого 300px на 150 пикселей плюс дополнительные 5px отступов за пределами того, что дает поле размером 310px на 160px.

Лично я согласен с тем, что Ширина должна включать заполнение. Однако это не то, что говорит спецификация.

В качестве побочного примечания режим quirks включает в себя заполнение (и границу) в фактической ширине. К сожалению, режим quirks закручивает так много других вещей, что обычно лучше просто иметь дело с моделью w3c spec'd, чем пытаться создать все css, необходимые для исправления других "причудливых" вещей.

Другой сайт (который согласен с вами и мной) находится здесь: http://www.quirksmode.org/css/box.html

Они отмечают, что CSS3 включает объявление размера окна (как вы уже нашли), которое должно дать вам больше контроля над используемой моделью окна. Похоже, что все (IE8, chrome, Firefox) поддерживают то, что хорошо.

Ответ 3

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

Но в итоге это всего лишь выбор, который был сделан, и с этим мы должны работать.

Ответ 4

Посмотрите на следующую картинку: enter image description here

Теперь подумайте, что произойдет, если вы установите значения width и height на 100% - должны ли отступы и границы просто волшебным образом исчезнуть из этого изображения? Как вы, как разработчик, когда-либо справляетесь с этим разумным способом?

width and height is width and height, border and padding is something else - для меня это не становится более логичным, чем это.

С другой стороны,

width and height is width and a height, but sometimes when you choose to set them to 100% they are also border and padding - теперь это не имеет смысла для меня.

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

Ответ 5

Хотя это, возможно, и не было оригинальным намерением модели CSS box, еще одно преимущество - если вы хотите что-то со смещенным фоновым изображением (например, изображение находится слева или справа от текста). Затем вы можете указать заполнение как ширину фонового изображения, чтобы текст не перекрывал его и все еще указывал ширину для самого текста. Например:

.imageDiv{
width:200px;
background-image:url('someimage.png') /*this image is 50 px wide*/
background-repeat:no-repeat;
padding-left:50px;
}

Теперь любой текст, введенный в div с классом imageDiv, будет показывать изображение слева от текста с любым перекрытием.