Маржинальная вершина толкает внешнюю часть вниз - PullRequest
122 голосов
/ 21 апреля 2010

У меня есть div заголовка в качестве первого элемента в моей оболочке div, но когда я добавляю верхнее поле к h1 внутри div заголовка, он выталкивает весь заголовок div вниз. Я понимаю, что это происходит всякий раз, когда я применяю верхнее поле к первому видимому элементу на странице.

Вот пример кода. Спасибо!

div#header{
	width: 100%;
	background-color: #eee;
	position: relative;
}

div#header h1{
	text-align: center;
	width: 375px;
	height: 50px;
	margin: 50px auto;
	font-size: 220%;
	background: url('../../images/name_logo.png') no-repeat;
}
<div id="header">
	<h1>Title</h1>
	<ul id="navbar"></ul>
</div>

Ответы [ 8 ]

183 голосов
/ 23 мая 2010

поставить overflow:auto в родительском div
подробнее по этой ссылке

33 голосов
/ 21 апреля 2010

У меня нет четких объяснений того, почему это происходит, но я исправил это, изменив top-margin на top-padding или добавив display: inline-block к стилю элемента.

РЕДАКТИРОВАТЬ: Это моя теория

У меня такое ощущение, что это как-то связано с тем, как поля складываются (комбинируются).

из W3C Сжимающиеся поля :

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

Моя теория состоит в том, что, поскольку ваш первый элемент находится рядом с телом, два поля объединяются и применяются к телу: это заставляет содержимое тела начинать ниже примененного свернутого поля в соответствии с коробочной моделью . * * 1022

Существуют ситуации, когда поля не сжимаются, с которыми стоит поиграть (из Свертывание полей ):

* floated elements
* absolutely positioned elements
* inline-block elements
* elements with overflow set to anything other than visible (They do not collapse margins with their children.)
* cleared elements (They do not collapse their top margins with their parent block’s bottom margin.)
* the root element
15 голосов
/ 24 февраля 2015

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

  • Установите для display значение, отличное от block.
  • Установите float на значение, отличное от none.
  • Удалите поле и используйте вместо него padding. Например, если у вас было margin-top: 10px, замените на padding-top: 10px;.
  • Удалите поле и используйте вместо него position (absolute или relative) с атрибутами top, bottom и т. Д. Например, если у вас было margin-top: 10px, замените на position: relative; top: 10px;.
  • Добавьте padding или border на стороне, где сворачиваются поля, к элементу parent . Граница может быть 1px и прозрачной.
  • Установите для overflow значение, отличное от visible, для родительского элемента .
4 голосов
/ 02 марта 2018

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

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

<div>
    <h1>Test</h1>
</div>

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

Так что это легко исправить, не прибегая к странным взломам, как это делает большинство постов здесь (без оскорблений, это просто правда) - просто вернитесь к исходному объяснению - ...if the first element inside a container has a top margin... - После этого поэтому вам понадобится первый элемент в контейнере, чтобы НЕ имел верхнее поле. Хорошо, но как это сделать без добавления элементов, которые семантически не мешают вашему документу?

Легко! Псевдо-элементы! Вы можете сделать это через класс или предопределенный миксин. Добавьте :before псевдоэлемент:

CSS через класс:

.top-margin-fix:before {   
    content: ' ';
    display: block;
    width: 100%;
    height: .0000001em;
}

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

<div class="top-margin-fix">
    <h1>Test</h1>
</div>

Почему это работает?

Первый элемент в контейнере, если у него нет верхнего поля, устанавливает позицию начала верхнего поля следующего элемента. Добавляя псевдоэлемент :before, браузер фактически добавляет несемантический (другими словами, полезный для SEO) элемент в родительский контейнер до вашего первого элемента.

Q. Почему высота: .0000001em?

A. Требуется высота, чтобы браузер выдвигал элемент поля вниз. Эта высота фактически равна нулю, но она все равно позволит вам добавить отступы к самому родительскому контейнеру. Поскольку он фактически равен нулю, он также не повлияет на макет контейнера. Красивые.

Теперь вы можете добавить класс (или лучше, в SASS / LESS, миксин!), Чтобы исправить эту проблему, вместо добавления странных стилей отображения, которые будут вызывать неожиданные последствия, когда вы захотите сделать что-то с вашими элементами, преднамеренно устраняя поля на элементах и ​​/ или их замена отступами или странными стилями позиции / плавающего типа, которые действительно не предназначены для решения этой проблемы.

2 голосов
/ 17 мая 2017

display: flex будет работать в этом случае. Укажите родительский элемент display: flex;, а затем укажите маржу согласно вашему требованию к тегу h1.

0 голосов
/ 20 января 2019

Это происходит из-за коллапса маржи.Когда дочерний элемент касается границы родительского элемента, и любой из них применяется с полями, тогда:

  1. Наибольшее поле будет использовано (применено).

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

Решения

  1. применить границу к родителю, что делаетродительские и дочерние элементы разделяются.
  2. применяет заполнение к родительскому элементу, в результате чего родительские и дочерние элементы разделяются.
  3. применяет переполнение, а не видимое для родительского элемента.
  4. используется до или после создания виртуального элементав родительском div, который может отличаться полем, применяемым для дочернего и родительского полей.
  5. создать один элемент html между полем, применяемым для дочернего элемента, и родитель также может разделять их.
0 голосов
/ 05 марта 2016

Добавление небольшого отступа к верху родительского элемента может решить эту проблему.

.parent{
  padding-top: 0.01em;
}

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

0 голосов
/ 09 апреля 2015

Займитесь этим вопросом сегодня.

overflow: hidden не сработало, как ожидалось, когда за мной последовало больше элементов.

Итак, я попытался изменить свойство отображения родительского div, и display: flex сработало !!!

Надеюсь, это может кому-то помочь. :)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...