Поле на дочернем элементе перемещает родительский элемент

у меня есть div (родитель), который содержит другой div (ребенок). Parent является первым элементом в body без определенного стиля CSS. Когда я установил

.child
{
    margin-top: 10px;
}

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

мой DOCTYPE установлено значение XHTML Transitional.

чего мне не хватает здесь?

изменить 1
Мой родитель должен иметь строго определенные размеры, потому что он имеет фон, который должен отображаться под ним сверху вниз (идеальный пиксель). Таким образом, установка вертикальных полей на нем является нет go.

edit 2
Это поведение одинаково на FF, IE, а также CR.

14 ответов


нашел альтернативу в дочерние элементы с полями в DIVs вы также можете добавить:

.parent { overflow: auto; }

или:

.parent { overflow: hidden; }

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

.parent {
    padding-top: 1px;
    margin-top: -1px;
}

обновление по многочисленным просьбам: Весь смысл сворачивания полей заключается в обработке текстового контента. Для пример:

<style type="text/css">
    h1, h2, p, ul {
        margin-top: 1em;
        margin-bottom: 1em;
    }
</style>

<h1>Title!</h1>
<div class="text">
    <h2>Title!</h2>
    <p>Paragraph</p>
</div>
<div class="text">
    <h2>Title!</h2>
    <p>Paragraph</p>
    <ul>
        <li>list item</li>
    </ul>
</div>

поскольку браузер сворачивает поля, текст будет отображаться так, как вы ожидаете, и <div> теги обертки не влияют на поля. Каждый элемент гарантирует, что он имеет интервал вокруг него, но интервал не будет удвоен. Поля <h2> и <p> не складывается, но скользят друг в друга (они рушатся). То же самое происходит для <p> и <ul> элемент.

к сожалению, с современным дизайном эта идея может укусить вас, когда вы явно нужен контейнер. Это называется новый контекст форматирования блока в CSS говорят. The overflow или margin trick даст вам это.


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

чтобы получить поведение, которое вы хотите, вам нужно:

.child {
    margin-top: 0;
}

.parent {
    padding-top: 10px;
}

хотя все ответы исправляют проблему, но они приходят с компромиссами / корректировками / компромиссами, такими как

  • floats, вы есть плавать элементы
  • border-top, это толкает родителя по крайней мере 1px вниз, который затем должен быть скорректирован с введением -1px поле для самого родительского элемента. Это может создать проблемы, когда у родителя уже есть margin-top в относительных единицах.
  • padding-top, такой же эффект, как и использование border-top
  • overflow: hidden, Не может использоваться, когда родитель должен отображать переполненный контент, например выпадающее меню
  • overflow: auto, вводит полосы прокрутки для родительского элемента, который (намеренно) переполняет содержимое (например, тени или треугольник подсказки)

проблема может быть решена с помощью CSS3 псевдо-элементов следующим образом

.parent::before {
  clear: both;
  content: "";
  display: table;
  margin-top: -1px;
  height: 0;
}

https://jsfiddle.net/hLgbyax5/1/


добавить стиль display:inline-block дочернему элементу


родительский элемент не должен быть пустым, по крайней мере, поставить &nbsp; перед дочерним элементом.


Это то, что сработало для меня

.parent {
padding-top: 1px;
margin-top: -1px;
}

.child {
margin-top:260px;
}

http://jsfiddle.net/97fzwuxh/


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


на margin элементов, содержащихся в .child рушатся.

<html>
<style type="text/css" media="screen">
    #parent {background:#dadada;}
    #child {background:red; margin-top:17px;}
</style>
<body>
<div id="parent">

    <p>&amp;</p>

    <div id="child">
        <p>&amp;</p>    
    </div>

</div>
</body>
</html>

в этом примере p получает margin из стилей браузера по умолчанию. Браузер по умолчанию font-size как правило, то есть 16px. Имея margin-top более 16px на #child вы начинаете замечать это положение.


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

<div class="supercontainer"></div>

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


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

HTML-код:

<div class="parent">
    <div class="child"></div>
</div>

css:

.parent{width:100px; height:100px;}
.child{float:left; margin-top:20px; width:50px; height:50px;}

смотрите здесь:http://codepen.io/anon/pen/Iphol

обратите внимание, что в случае, если вам нужна динамическая высота на родителе, она также должна плавать, поэтому просто замените height:100px; by float:left;


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

ваш ящик будет использовать дополнительные пиксели...

.parent {
    border:1px solid transparent;
}

аккуратный CSS-только решение

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

.parent:before
{content: '';position: relative;height: 0px;width: 0px;overflow: hidden;white-space: pre;}

преимущество этого метода заключается в том, что вам не нужно изменять CSS любого существующего элемента и, следовательно, оказывает минимальное влияние на дизайн. Рядом с этим элементом добавляется псевдо-элемент, который является не в DOM-дереве.

поддержка псевдоэлементов широко распространена: Firefox 3+, Safari 3+, Chrome 3+, Opera 10+ и IE 8+. Это будет работать в любом современном браузере (будьте осторожны с новыми ::before, который не поддерживается в IE8).

контекст

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

учитывая следующую проблему:

<style type="text/css">
div {position: relative;}
.parent {background-color: #ccc;}
.child {margin-top: 40px;}
</style>

<div class="parent"><!--This div moves 40px too-->
    <div class="child">Hello world!</div>
</div>

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

<style type="text/css">
div {position: relative;}
.parent {background-color: #ccc;}
.child {margin-top: 40px;}
.fix {position: relative;white-space: pre;height: 0px;width: 0px;overflow: hidden;}
</style>

<div class="parent"><!--This div won't move anymore-->
    <div class="fix"></div>
    <div class="child">Hello world!</div>
</div>

здесь position: relative; обеспечивает правильное позиционирование исправить. И white-space: pre; позволяет вам не добавлять какой - либо контент - например, пробел-в исправление. И height: 0px;width: 0px;overflow: hidden; делает, что вы никогда не увидите исправления.

возможно, вам придется добавить line-height: 0px; или max-height: 0px; чтобы убедиться, что высота на самом деле равна нулю в древних браузерах IE (я не уверен). И при желании вы можете добавить <!--dummy--> к нему в старых браузерах IE, если он не работает.

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

<style type="text/css">
div {position: relative;}
.parent {background-color: #ccc;}
.child {margin-top: 40px;}

.parent:before {content: '';position: relative;height: 0px;width: 0px;overflow: hidden;white-space: pre;}
</style>

<div class="parent"><!--This div won't move anymore-->
    <div class="child">Hello world!</div>
</div>

используя top вместо margin-top является еще одним возможным решением, если это необходимо.


чтобы предотвратить "Div parent", используйте поле " div child":
в родителе используйте эти css:

  • Float
  • обивка
  • границы
  • переполнения