Зовнішній дзвінок "Маржа-Топ" натисніть вниз


126

У мене є заголовок 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>

Відповіді:


193

Помістіть overflow:autoу батьків, div
див. більше за цим посиланням


29
overflow:hiddenкраще в 90% випадків.
vsync

1
Навіщо переповнювати: приховане буде краще?
петерхонт

5
@peterchon - адже авто може спричинити прокрутки
vsync

3
більше не працює, відповідь від @ SW4 у цьому посиланні краща
am05mhz

1
overflow: hiddenабо overflow: autoможе викликати небажані побічні ефекти, деякі з яких ви можете не побачити з першого погляду. Я виявив, що перехід marginна paddingтрюк, як підказує відповідь нижче. Досі не розумію, чому вся проблема трапляється.
Гілад Барнер

34

У мене немає твердого пояснення про те, чому це відбувається, але я це виправив, змінюючи top-marginдо top-padding, або додавання display: inline-blockдо стилю елемента.

EDIT: Це моя теорія

У мене є відчуття, що це пов'язане з тим, як руйнуються (комбінуються) поля.

від границь руйнування W3C :

У цій специфікації вираз згортання поля означає, що суміжні поля (ніякий не порожній вміст, області прокладки або межі або розмежування не розділяють їх) двох або більше полів (які можуть бути поруч один з одним або вкладені) поєднуються, щоб утворювати єдиний запас .

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

Є ситуації, коли поля не руйнуються, з якими варто заграти (від Collapsing Margins ):

* 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

3
Крім того, накладка або рамка на елементі зі згорнутим полем (внутрішній) буде скасовувати його.
Анонім

Це працювало для мене - у мене були абсолютні елементи (спадне меню) у своєму контейнері, тому переповнення: авто не працювало.
mwilcox

17

Це декілька способів уникнути краху поля між елементами батько-дитина. Використовуйте той, який краще відповідає решті вашої стилізації:

  • Встановлено displayінше, ніж block.
  • Встановлено floatінше, ніж none.
  • Видаліть поле та використовуйте натомість padding. Наприклад, якщо у вас був margin-top: 10px, замініть на padding-top: 10px;.
  • Видалити запас, і використовувати замість position( absoluteабо relative) з атрибутами top, bottomі так далі Наприклад , якщо у вас margin-top: 10px, замініть position: relative; top: 10px;.
  • Додайте a paddingабо a borderв сторону, де поля руйнуються, до батьківського елемента. Кордон може бути 1 пікселем і прозорим.
  • Встановіть overflowв положення, відмінне visibleвід батьківського елемента.

5

Я знаю, що це стара проблема, я стикався з нею вже багато разів. Проблема полягає в тому, що всі виправлення тут - хаки, які потенційно можуть мати наслідки.

По-перше, існує легке пояснення кореневої проблеми. Завдяки тому, як працює рубіж поля, якщо перший елемент всередині контейнера має верхній запас, цей верхній запас ефективно застосовується до самого батьківського контейнера. Ви можете перевірити це самостійно, виконавши наступне:

<div>
    <h1>Test</h1>
</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) елемент у батьківський контейнер перед першим елементом.

З. Чому висота: .0000001em?

A. Висота потрібна, щоб браузер відсунув елемент поля вниз. Ця висота фактично дорівнює нулю, але вона все одно дозволить додати прокладку до самого батьківського контейнера. Оскільки він фактично дорівнює нулю, це також не вплине на компонування контейнера. Гарний.

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


2
.0000001em дійсно округлюється до нуля в IE11, порушуючи ваше виправлення. Коли я зміню його на .01em, він працює.
Есгер

1
Я думаю, що .01em буде достатньо, щоб все-таки ефективно дорівнювати нулю. Гарна думка. Зверху, тепер, коли настає 2018 рік, багато хто з нас втратить підтримку IE11 незабаром, особливо з недавнього повідомлення про те, що MS знову створить новий браузер (крім цього разу на основі хрому, що це означає - теоретично - не буде повністю смоктати). : D
dudewad

2

display: flexбуде працювати в цьому випадку. Надайте батьківський елемент, display: flex;а потім дайте маржу відповідно до вашої вимоги до h1тегу.


0

Зустріньтесь із цим питанням сьогодні.

overflow: hidden не працювало так, як очікувалося, коли в мене було більше елементів.

Тож я спробував змінити властивість відображення батьківського діва та display: flexпопрацював !!!

Сподіваюся, це може комусь допомогти. :)


0

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

.parent{
  padding-top: 0.01em;
}

Це корисно, якщо вам потрібен елемент, що знаходиться всередині батьків, бути видимим поза батьківським елементом, наприклад, якщо ви створюєте ефект перекриття.


0

Це відбувається через крах маржі. Коли дочірній елемент торкається межі батьківського елемента та будь-якого з них, застосованих із полями, тоді:

  1. Найбільша маржа виграє (застосовується).

  2. якщо хтось із них має маржу, то обидва поділять однакові.

Рішення

  1. застосувати кордон до батьківського, що змушує батьків та дітей розділятись.
  2. застосувати прокладку до батьків, завдяки чому батьки та дитини розлучаються.
  3. застосувати переповнення, а не бачити батьків.
  4. використовувати до або після створення віртуального елемента в батьківському діві, який може відрізнятися від застосованої дочірніми і батьківськими полями.
  5. створити один html-елемент між дочірнім приляганням до маржі та батьківським, також може відокремити їх.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.