Почему маржа не содержится в родительском элементе?

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

Многие вещи заставят родительский элемент содержать дочернее поле:

  • border: solid;
  • position: absolute;
  • display: inline-block;
  • overflow: auto;

(И это всего лишь небольшое тестирование, несомненно, есть еще кое-что.)

Я бы предположил, что это связано со схлопыванием полей, но:

  1. На странице спецификации W3C нет описания такого поведения.
  2. Здесь нет перекрывающихся полей.
  3. Поведение всех браузеров в этом вопросе похоже.
  4. На поведение влияют триггеры, не связанные с полями.

Какова логика, по которой элемент со значением по умолчанию overflow: auto должен содержать материал, отличный от того, в котором переполнение установлено на авто?

Почему все, кроме поведения по умолчанию обычного div, должно предполагать, что поле содержится в родительском элементе - и почему обычное значение по умолчанию не должно включать поле?


РЕДАКТИРОВАТЬ: Окончательный ответ заключается в том, что W3C действительно определяет это поведение, но это:

  • В спецификациях нет никакого смысла.
  • The specs mix, without any word of explanation:
    • 'free margins' (margins that would touch the top or bottom of their parent are not contained by the parent) and
    • «свернутые поля» (смежные поля могут перекрываться).

Демо:

body {
  margin: 0;
}

div.block {
  background-color: skyblue;
}
div.inline-block {
  display: inline-block;
  background-color: lawngreen;
}
div.position-absolute {
  background-color: rgba(255,255,0,.7);
  position: absolute;
  bottom: 0;
  right: 0;
}
div.overflow-auto {
  background-color: hotpink;
  overflow: auto;
}
div.border {
  background-color: aquamarine;
  border: solid;
}

h2 {
  margin: 80px;
  width: 250px;
  border: solid;
}
<div class="block">
  <h2>Is the margin contained (block)?</h2>
</div>
<div class="inline-block">
  <h2>Is the margin contained (inline-block)?</h2>
</div>
<div class="position-absolute">
  <h2>Is the margin contained (position-absolute)?</h2>
</div>
<div class="overflow-auto">
  <h2>Is the margin contained (overflow-auto)?</h2>
</div>
<div class="border">
  <h2>Is the margin contained (border)?</h2>
</div>


person SamGoody    schedule 01.02.2010    source источник
comment
Я не понимаю, о чем вы спрашиваете. Вы спрашиваете, почему элементы h1 отображаются внутри элементов контейнера? Пожалуйста, поясните свой вопрос.   -  person Antony Carthy    schedule 01.02.2010


Ответы (1)


Вот как работает CSS согласно W3C:

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

Более конкретно для вашего случая верхнего div:

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

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

Лучшее, что я могу сделать, это указать вам на Свертывание полей на sitepoint (Томми Олссон и Пол О'Брайен). Они дают очень подробное объяснение с примерами, демонстрирующими именно то поведение, которое вы продемонстрировали в примере кода вопроса.

person Nick Craver    schedule 01.02.2010
comment
Согласно этой статье, наблюдаемое поведение неверно. ‹Br› Относительно вашего ответа: сворачивание полей означает, что смежные поля ... объединяются. Поскольку здесь нет прилегающих полей, это не может быть схлопывающимся полем. В частности, если поля элемента свернуты с верхним полем его родительского элемента - не может быть, поскольку у родительского элемента нет верхнего поля. В вопросе я имею дело с обрушивающимися полями. В любом случае, однако, это не объясняет, почему поведение должно измениться, когда отображение является встроенным блоком или если для переполнения установлено значение auto (что совпадает с значением по умолчанию). - person SamGoody; 01.02.2010
comment
Исправление: в этой статье перечислены некоторые из моих триггеров + другие. Подобно тому, как эти триггеры предотвращают сжатие перекрывающихся полей, они также предотвращают сжатие обычных полей. Два вопроса: 1) Как такое поведение может иметь смысл? 2) Почему мне кажется, что у меня перекрывающиеся поля? - person SamGoody; 01.02.2010
comment
@samgoody - 1) Я согласен, что это не имеет особого смысла, за исключением случаев, когда вы исходите из печатного фона, который в основном является тем, чем был Интернет, когда была написана спецификация. См. Здесь: complexspiral.com/publications/uncollapsing-margins 2) Это родительский / дочерний элемент в вашем случае ... коллапс от родительского / дочернего элемента дает div.b вертикальное поле в 100 пикселей, поэтому этот фон белый, а не зеленый. Я думаю, что проблема в том, что в спецификации неясно, КАКАЯ маржа выигрывает в этом случае при коллапсе, похоже, с текущим браузером родитель получает это. - person Nick Craver; 02.02.2010