Як працюють негативні маржі в CSS і чому це (margin-top: -5! = Margin-bottom: 5)?


108

Загальний трюк для елементів вертикального позиціонування - це використання наступних CSS:

.item {
    position:absolute;
    top:50%;
    margin-top:-8px; /* half of height */
    height: 16px;
}

Якщо ви бачите в метричному поданні, як у Chrome, це те, що ви бачите:

введіть тут опис зображення

Однак візуального поля не зображено, коли ви наводите курсор на елемент, тобто поле знаходиться "поза межами", і його можна візуалізувати. Але негативні маржі не відображаються. Як вони виглядають і чим це відрізняється?

Чому це margin-top:-8px не те саме, що margin-bottom:8px ?

Отже, як працюють негативні маржі та яка інтуїція за ними. Як вони "нарізають" (у випадку margin-top < 0) предмет?

Відповіді:


89

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

Наприклад, візуалізація вашого зразкового коду керується специфікацією css, як описано в обчисленні висоти та поля для абсолютно розташованих незамінених елементів .

Якби я робив графічне зображення, я, мабуть, пішов би з чимось подібним (не в масштабі):

від'ємний верхній запас

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

Бонус:

Ще потрібно переконати, що читання специфікацій - це шлях (на відміну від таких статей )? Я бачу, що ви намагаєтесь вертикально зафіксувати елемент, так чому ви повинні встановити, margin-top:-8px;а ні margin-top:-50%;?

Ну, вертикальне центрування в CSS складніше, ніж повинно бути . При встановленні рівних верхнього або нижнього поля у%, значення розраховується у відсотках завжди відносно ширини блоку, що містить . Це досить поширений підводний камінь, і хитрість рідко описується поза межами w3 docos


84

Спробую пояснити це візуально:

/**
 * explaining margins
 */

body {
  padding: 3em 15%
}

.parent {
  width: 50%;
  width: 400px;
  height: 400px;
  position: relative;
  background: lemonchiffon;
}

.parent:before,
.parent:after {
  position: absolute;
  content: "";
}

.parent:before {
  top: 0;
  bottom: 0;
  left: 50%;
  border-left: dashed 1px #ccc;
}

.parent:after {
  left: 0;
  right: 0;
  top: 50%;
  border-top: dashed 1px #ccc;
}

.child {
  width: 200px;
  height: 200px;
  background: rgba(200, 198, 133, .5);
}

ul {
  padding: 5% 20px;
}

.set1 .child {
  margin: 0;
  position: relative;
}

.set2 .child {
  margin-left: 75px;
  position: relative;
}

.set3 .child {
  margin-left: -75px;
  position: relative;
}


/* position absolute */

.set4 .child {
  top: 50%;
  left: 50%;
  margin: 0;
  position: absolute;
}

.set5 .child {
  top: 50%;
  left: 50%;
  margin-left: 75px;
  position: absolute;
}

.set6 .child {
  top: 50%; /* level from which margin-top starts 
	- downwards, in the case of a positive margin
	- upwards, in the case of a negative margin	
	*/
  left: 50%; /* level from which margin-left starts 
	- towards right, in the case of a positive margin
	- towards left, in the case of a negative margin	
	*/
  margin: -75px;
  position: absolute;
}
<!-- content to be placed inside <body>…</body> -->
<h2><code>position: relative;</code></h2>
<h3>Set 1</h3>
<div class="parent set 1">
  <div class="child">
    <pre>
.set1 .child {
  margin: 0;
  position: relative;
}
		</pre>
  </div>
</div>

<h3>Set 2</h3>
<div class="parent set2">
  <div class="child">
    <pre>
.set2 .child {
  margin-left: 75px;
  position: relative;
}
		</pre>
  </div>
</div>

<h3>Set 3</h3>
<div class="parent set3">
  <div class="child">
    <pre>
.set3 .child {
  margin-left: -75px;
  position: relative;
}
		</pre>
  </div>
</div>

<h2><code>position: absolute;</code></h2>

<h3>Set 4</h3>
<div class="parent set4">
  <div class="child">
    <pre>
.set4 .child {
  top: 50%;
  left: 50%;
  margin: 0;
  position: absolute;
}
		</pre>
  </div>
</div>

<h3>Set 5</h3>
<div class="parent set5">
  <div class="child">
    <pre>
.set5 .child {
  top: 50%;
  left: 50%;
  margin-left: 75px;
  position: absolute;
}
		</pre>
  </div>
</div>

<h3>Set 6</h3>
<div class="parent set6">
  <div class="child">
    <pre>
.set6 .child {
  top: 50%;
  left: 50%;
  margin: -75px;
  position: absolute;
}
		</pre>
  </div>
</div>


33

Поля - це відстань поза вашим елементом, подібно до того, як накладка - це інтервал всередині вашого елемента.

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


2
+1 Мені подобається ваша відповідь. Це можна покращити, вводячи слова onsetта offset. Це правда, тому багато людей завжди використовують слово offset( негатив ), коли вони означають onset( позитив ). Це повідомлення самознищиться, якщо ви оновите свою відповідь. Ура!
arttronics

1
Про що margin-bottom: -8px;? Чому це margin-bottom:-8pxне те саме, що margin-top:-8px?
Рік

27

Вершина маржі -8px означає, що вона буде на 8 пікселів вище, ніж якби вона мала 0 запасів.

Нижнє поле в 8px означає, що річ під ним буде на 8px далі, якщо вона мала 0 запасів.


1
Я просто намагався зробити все просто, але я згоден, це, можливо, найгірше написане з моїх відповідей!
Річ Бредшоу

2
Я думаю, що відповідь досить гарна. Не використовуйте високо технічних відповідей, що половина з нас цього не отримує.
Число945

1
Про що margin-bottom: -8px;? Чому це margin-bottom:-8pxне те саме, що margin-top:-8px?
Рік

22

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

"Чому margin-top: -8px не те саме, що margin-top: 8px?"

що ми також могли запитати:

Чому позитивна нижня маржа не піддається "попереднім елементам", тоді як позитивна нижня межа "нахиляється" наступними елементами?

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

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

врахуйте наступний html:

<div class="box1"></div>
<div class="box2"></div>
<div class="box3"></div>

аналогічно їхньому положенню в коді, ці три поля виглядають складеними "зверху вниз" у веб-переглядачі ( просто, прості речі, ми не будемо розглядати тут orderвластивість модуля css3 "flex-box" ). тому, коли стилі застосовуються до вікна 3, положення попередніх елементів (для вікон 1 і 2) вже визначені, і їх більше не слід змінювати задля швидкості візуалізації.

тепер, уявіть верхню межу -10px для вікна 3. замість того, щоб зміщувати всі попередні елементи, щоб зібрати простір, браузер просто натисне вікно 3 вгору, тому він відображається вгорі (або під ним, залежно від z-індексу ) будь-які попередні елементи. навіть якщо продуктивність не була проблемою, переміщення всіх елементів вгору може означати зміщення їх із вікна перегляду, таким чином, поточне положення прокрутки повинно бути змінено, щоб все було знову видно.

те саме стосується нижньої межі для поля 3, як негативного, так і позитивного: замість впливу на вже оцінені елементи визначається лише нова «відправна точка» для майбутніх елементів. таким чином встановлення позитивного нижнього запасу давить наступні елементи вниз; негативний підштовхне їх.


НАЙКРАЩА відповідь. Цей також пояснює "чому", тоді як інші відповіді лише пояснюють "як".
Амір Хосейн Ахмаді

1
Ця відповідь допомогла мені зрозуміти, чому краще. Дякую @schellmax
iRamesh

3

Оскільки ви використовували абсолютне позиціонування та вказали максимальний відсоток, лише розміщення верхньої точки буде впливати на розташування вашого об’єкта .item. Якщо б замість цього ви розмістили його за допомогою нижнього: 50%, вам знадобиться margin-bottom -8px для його централізації, і margin-top не матиме ефекту.

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

Ваш CSS повідомляє веб-переглядачу розміщувати верхню частину вашого поля в точці 50% шляху вниз по сторінці. Однак, оскільки всі елементи не є одним пікселем, браузер повинен знати, яку частину його складати на 50% шляху вниз по сторінці. Для вишивки у верхній частині елемента використовується верхній край. За замовчуванням це відповідає верхній частині елемента, але ви можете змінити його за допомогою CSS.

У вашому випадку топ-50% призведе до того, що початок елемента починається в середині сторінки. Застосувавши негативний верхній запас, браузер використовує точку 8px в елементі зверху (тобто лінію через середину) як місце для позиціонування на 50%.

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


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

3

Цікаво, чи добре відповіли на це питання: як працюють межі css і чому це маржа-топ: -5; не є тим самим, що і "margin bottom": 5 ;?

Поле - це відстань від оточення елемента. margin-top говорить "... відстань від оточення, оскільки ми вимірюємо" верхню "сторону" коробки "елемента, а нижня межа поля - відстань від нижньої" сторони "" коробки "". Тоді маржа-верх: 5; стосується верхнього «бічного» периметра, в цьому випадку -5; все, що наближається до верхньої "сторони", може перекривати верхню "сторону" елемента на 5, а нижня межа: 5; означає відстань між нижньою стороною елемента та навколишнім оточенням 5.

В основному, але на них впливають float'ed елементи тощо: http://www.w3.org/TR/CSS2/box.html#margin-properties .

http://coding.smashingmagazine.com/2009/07/27/the-definitive-guide-to-using-negative-margins/

Я стою, щоб виправитись.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.