Как отрицательные поля в CSS работают и почему (margin-top: -5!= Margin-bottom: 5)?

Общим трюком для элементов вертикального позиционирования является использование следующего CSS:

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

Когда вы видите в метрическом представлении, как в Chrome, это то, что вы видите:

enter image description here

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

Почему margin-top:-8px не совпадает с margin-bottom:8px?

Итак, как работают отрицательные поля и какова их интуиция. Как они "подхватывают" (в случае margin-top < 0) элемент?

Ответ 1

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

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

Если бы я сделал графическое представление, я бы, вероятно, пошел с чем-то вроде этого (не для масштабирования):

negative top margin

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

Bonus:

По-прежнему нужно убеждать в том, что спецификации чтения - это путь (в отличие от статей, подобных этому)? Я вижу, что вы пытаетесь вертикально центрировать элемент, так почему вы должны установить margin-top:-8px;, а не margin-top:-50%;?

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

Ответ 2

Я попытаюсь объяснить это визуально:

/**
 * 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>

Ответ 3

Маржа - это интервал вне вашего элемента, так же как заполнение - это интервал внутри вашего элемента.

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

Ответ 4

Верхний край -8px означает, что он будет на 8px выше, чем если бы он имел 0 маржи.

Нижняя граница 8px означает, что нижележащая вещь будет на 8 пунктов ниже, если бы у нее было 0 полей.

Ответ 5

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

"Почему margin-top: -8px не совпадает с margin-bottom: 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-index) любые предыдущие элементы. даже если производительность не была проблемой, перемещение всех элементов могло означать смещение их из окна просмотра, поэтому текущую позицию прокрутки пришлось бы изменить, чтобы все было видно снова.

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

Ответ 6

Поскольку вы использовали абсолютное позиционирование и указали верхний процент, только маржа-верх будет влиять на местоположение вашего объекта .item. Если вместо этого вы позиционировали его с помощью дна: 50%, то вам понадобится margin-bottom -8px, чтобы центрировать его, а margin-top не будет иметь эффекта.

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

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

В вашем случае верхние 50% приведут к тому, что верхняя часть элемента начнется в середине страницы. Применяя отрицательный верхний край, браузер использует точку 8px в верхнем элементе (то есть в строке через середину) как место для размещения на 50%.

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

Ответ 7

Интересно, хорошо ли ответил на этот вопрос: как работают поля css и почему это margin-top: -5; это не то же самое, что и margin-bottom: 5;?

Маржа - это расстояние от окружения элемента. margin-top говорит "... расстояние от окружения по мере того, как мы измеряем с верхней стороны" блока "ящик", а край "край" - это расстояние от нижней стороны "окна". Затем margin-top: 5; связан с верхним "боковым" периметром, -5 в этом случае; все, что приближается с верхней стороны, может перекрывать верхнюю "сторону" элемента на 5, а margin-bottom: 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/

Я исправляю.