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


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

.child
{
    margin-top: 10px;
}

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

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

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

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

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

14 327

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 говорят. Элемент overflow или маржа трюк даст вам это.

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

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

.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 к дочернему элементу

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

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

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

.child {
margin-top:260px;
}

http://jsfiddle.net/97fzwuxh/

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

The 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 получает a 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 (что устраняет необходимость добавления фактического ребенка в HTML DOM-дерево):

<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 является еще одним возможным решением, если это необходимо.

для предотвращения "Див родитель" наценка использование "див ребенка":
в Родительском использовать эти css:

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