Почему этот CSS-верхний стиль не работает?

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

Что я ожидал:
What I expected with margin:50px 50px 50px 50px;

Что я получаю:
What I get with margin:50px 50px 50px 50px;

Код:

#outer {
    	width: 500px; 
    	height: 200px; 
    	background: #FFCCCC;
    	margin: 50px auto 0 auto;
    	display: block;
}
#inner {
    	background: #FFCC33;
    	margin: 50px 50px 50px 50px;
    	padding: 10px;
    	display: block;
}
<div id="outer">
  <div id="inner">
  	Hello world!
  </div>
</div>

Ответ 1

Фактически вы видите верхний край элемента #inner Свернуть в верхний край элемента #outer, оставив только маркер #outer неповрежден (хотя и не показан на ваших изображениях). Верхние края обоих ящиков сливаются друг с другом, потому что их поля равны.

Вот соответствующие точки из спецификации W3C:

8.3.1 Свертывание полей

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

Приближение вертикальных полей сворачивается [...]

Два поля смежны тогда и только тогда, когда:

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

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

Это потому, что:

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

Левое и правое поля ведут себя так, как вы ожидаете, потому что:

Горизонтальные поля никогда не разрушаются.

Ответ 2

Попробуйте использовать display: inline-block; на внутреннем div.

#outer {
    width:500px; 
    height:200px; 
    background:#FFCCCC;
    margin:50px auto 0 auto;
    display:block;
}
#inner {
    background:#FFCC33;
    margin:50px 50px 50px 50px;
    padding:10px;
    display:inline-block;
}

Ответ 3

Что упоминается в @BoltClock, довольно солидно. И здесь я просто хочу добавить еще несколько решений для этой проблемы. проверьте этот w3c_collapsing margin. Зеленые части - это потенциальная мысль о том, как эта проблема может быть решена.

Решение 1

Поля между полем с плавающей точкой и любым другим полем не сворачиваются (даже между поплавком и дочерними потоками).

это означает, что я могу добавить float:left в #outer или #inner demo1.

также заметили, что float приведет к недействительности поля auto.

Решение 2

Поля элементов, которые создают новые контексты форматирования блоков (такие как float и элементы с "переполнением", отличные от "видимых" ), не сворачиваются с их дочерними потоками.

кроме visible, поместите overflow: hidden в #outer. И этот путь кажется довольно простым и приличным. Мне это нравится.

#outer{
    width: 500px;
    height: 200px;
    background: #FFCCCC;
    margin: 50px auto;
    overflow: hidden;
}
#inner {
    background: #FFCC33;
    height: 50px;
    margin: 50px;
}

Решение 3

Поля абсолютно помещенных коробок не сворачиваются (даже с их детьми в потоке).

#outer{
    width: 500px;
    height: 200px;
    background: #FFCCCC;
    margin: 50px auto;
    position: absolute; 
}
#inner{
    background: #FFCC33;
    height: 50px;
    margin: 50px;
}

или

#outer{
    width: 500px;
    height: 200px;
    background: #FFCCCC;
    margin: 50px auto;
    position: relative; 
}
#inner {
    background: #FFCC33;
    height: 50px;
    margin: 50px;
    position: absolute;
}

эти два метода нарушат нормальный поток div

Решение 4

Поля полей inline-block не сворачиваются (даже с их дочерьми в потоке).

- это то же самое, что и @enderskill

Решение 5

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

Это не так много работы с вопросом, так как это разваливающийся запас между братьями и сестрами. это обычно означает, что верхний ящик имеет margin-bottom: 30px, а в сиблок - margin-top: 10px. Общая граница между ними 30px вместо 40px.

Решение 6

Верхнее поле элемента блока потока в потоке сворачивается с его первым верхним полем верхнего уровня на уровне блока, если элемент не имеет верхней границы, нет верхнего заполнения, а у ребенка нет разрешения.

Это очень интересно, и я могу просто добавить одну верхнюю границу

#outer{
    width: 500px;
    height: 200px;
    background: #FFCCCC;
    margin: 50px auto;
    border-top: 1px solid red;

}
#inner {
    background: #FFCC33;
    height: 50px;
    margin: 50px;

}

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

Ответ 4

Если вы добавили дополнение к #outer, оно будет работать.

Демо

#outer {
    width:500px; 
    height:200px; 
    background:#FFCCCC;
    margin:50px auto 0 auto;
    display:block;
    padding-top:1px;
}

Ответ 5

Не совсем понятно, почему, но изменение внутреннего CSS на

display:inline-block;

похоже, работает;

Ответ 6

Не уверен, почему то, что у вас есть, не работает, но вы можете добавить

overflow: auto;

к внешнему div.

Ответ 7

Не отвечает "почему" (должно быть что-то с разваливающейся маркой), но похоже, что самый простой/самый логичный способ сделать то, что вы пытаетесь сделать, - просто добавить padding-top к внешнему div:

http://jsfiddle.net/hpU5d/1/

Незначительное примечание. Не нужно устанавливать div в display:block;, если в коде не будет чего-то другого, говорящего, что он не должен быть блоком.

Ответ 8

попробуйте следующее:

#outer {
    width:500px; 
    height:200px; 
    background:#FFCCCC;
    margin:50px auto 0 auto;
    display:table;
}
#inner {
    background:#FFCC33;
    margin:50px 50px 50px 50px;
    padding:10px;
    display:block;
}​

http://jsfiddle.net/7AXTf/

Удачи.

Ответ 9

Я полагаю, что свойство position #inner div относительное также может помочь в достижении эффекта. Но в любом случае я попробовал оригинальный код, вставленный в вопрос на IE9 и последний Google Chrome, и они уже дают желаемый эффект без каких-либо изменений.

Ответ 10

Используйте padding-top:50px для внешнего div. Что-то вроде этого:

#outer {
    width:500px; 
    height:200px; 
    background:#FFCCCC;
    margin:50px auto 0 auto;
    display:table;}

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

#outer {
    width:500px; 
    height:150px; 
    background:#FFCCCC;
    margin:50px auto 0 auto;
    display:table;}

Ответ 11

Вы пробовали! важно прежде всего, это заставит все:

margin:50px 50px 50px 50px !important;