По какой причине правила CSS-коллапса были введены в CSS?

Просто не могу понять ситуацию, когда этот умный набор правил может быть полезен. Они нарушают простоту модели коробки и обеспечивают бесконечный источник проблем, когда вы объединяете разные части компоновки. Так в чем причина?

Правила для справки.

Обновление: правила являются вполне логичными для элементов sibling, но почему поля должны распространяться на родительские элементы до дерева? Какие проблемы решаются?

Например:

<div style="margin: 20px; background-color: red;">
    <div style="margin: 20px;">
        <p style="margin: 100px;">red</p>
    </div>
</div>
<div style="margin: 20px; background-color: blue;">blue</div>

Дивы верхнего уровня отстоят друг от друга на 100 пикселей.

Ответ 1

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

Как вы, вероятно, знаете, поля задают расстояние между элементами, это не "внешняя прокладка", которая окружает каждый элемент. Если два элемента с запасом 20px находятся рядом друг с другом, расстояние между ними составляет 20px, а не 40px.

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

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

Ответ 2

Когда это может быть полезно?

Самый простой пример: список абзацев и заголовков, каждый с margin-top и margin-bottom. Вы хотите пометку сверху и снизу статьи и между разными элементами.

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

Но я согласен, в целом, это бессмысленная функция.

Ответ 3

Рассмотрим текст текста, содержащий несколько абзацев. Вы хотите, чтобы каждый абзац был разделен на 2em, и вы хотите, чтобы первый абзац был отделен от предыдущего содержимого 2em, а последний абзац должен быть отделен от следующего содержимого 2em.

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

p {
    margin-top: 2em
    margin-bottom: 2em;
}

Если поля не рухнули, это приведет к тому, что поля будут разделены пробелом 4em, а не 2em. Без разваливания маржи единственным способом достижения желаемого эффекта было бы установить некоторые дополнительные правила для первого и последнего абзацев, которые включали бы предоставление им класса или идентификатора (который должен был бы поддерживаться, если бы текст был когда-либо изменен), или обертывание их ненужным дополнительным элементом и использование: first-child и: last-child, или... ну, вы получите эту идею.

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