en.javascript.info/8-css-for-js/11-margin/article.md
2015-04-23 12:31:37 +03:00

173 lines
7.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Свойство "margin"
Свойство `margin` задаёт отступы вокруг элемента. У него есть несколько особенностей, которые мы здесь рассмотрим.
[cut]
## Объединение отступов
Вертикальные отступы поглощают друг друга, горизонтальные -- нет.
Например, вот документ с вертикальными и горизонтальными отступами:
```html
<!--+ autorun height=100 -->
<body style="background: #aef">
<p style="*!*margin:20px;*/!* background:white">
<span style="*!*margin:20px;*/!* background:orange">Горизонтальный 20px</span>
← 40px →
<span style="*!*margin:20px;*/!* background:orange">20px Отступ </span>
</p>
<p style="*!*margin:15px;*/!* background:white">Вертикальный 20px</p>
</body>
```
Расстояние по горизонтали между элементами `SPAN` равно `40px`, так как горизонтальные отступы по `20px` сложились.
А вот по вертикали расстояние от `SPAN` до `P` равно `20px`: из двух вертикальных отступов выбирается больший `max(20px, 15px) = 20px` и применяется.
## Отрицательные margin-top/left
Отрицательные значения `margin-top/margin-left` смещают элемент со своего обычного места.
В CSS есть другой способ добиться похожего эффекта -- а именно, `position:relative`. Но между ними есть одно принципиальное различие.
**При сдвиге через `margin` соседние элементы занимают освободившееся пространство, в отличие от `position: relative`, при котором элемент визуально сдвигается, но место, где он был, остается "занятым".**
То есть, элемент продолжает полноценно участвовать в потоке.
## Пример: вынос заголовка
Например, есть документ с информационными блоками:
```html
<!--+ autorun height=400 -->
<style>
div {
border: 1px solid blue;
margin: 2em;
font: .8em/1.25 Arial, sans-serif;
}
h2 {
background: #aef;
margin: 0 0 0.8em 0;
}
</style>
<div>
<h2>Общие положения</h2>
<p>Настоящие Правила дорожного движения устанавливают единый порядок дорожного движения на всей территории Российской Федерации. Другие нормативные акты, касающиеся дорожного движения, должны основываться на требованиях Правил и не противоречить им.</p>
</div>
<div>
<h2>Общие обязанности водителей</h2>
<p>Водитель механического транспортного средства обязан иметь при себе и по требованию сотрудников милиции передавать им для проверки:</p>
<ul>
<li>водительское удостоверение на право управления транспортным средством соответствующей категории;</li>
<li>...и так далее...</li>
</ul>
</div>
```
**Использование отрицательного `margin-top` позволяет вынести заголовки над блоком**.
```css
/* вверх чуть больше, чем на высоту строки (1.25em) */
h2 {
margin-top: -1.3em;
}
```
Результат:
[iframe src="h2-margin-top" height=330 border=1 link]
А вот, что бы было при использовании `position`:
```css
h2 {
position: relative;
top: -1.3em;
}
```
Результат:
[iframe src="h2-margin-top-position" height=330 border=1 link]
**При использовании `position`, в отличие от `margin`, на месте заголовков, внутри блоков, осталось пустое пространство.**
## Пример: вынос отчерка
Организуем информацию чуть по-другому. Пусть после каждого заголовка будет отчерк:
```html
<div>
<h2>Заголовок</h2>
<hr>
<p>Текст Текст Текст.</p>
</div>
```
Пример документа с такими отчерками:
[iframe src="hr-margin-left-src" height=320 border=1 link]
Для красоты мы хотим, чтобы отчерк `HR` начинался левее, чем основной текст. Отрицательный `margin-left` нам поможет:
```css
/*+ no-beautify */
hr.margin { margin-left: -2em; }
/* для сравнения */
hr.position { position: relative; left: -2em; }
```
Результат:
[iframe src="hr-margin-left" height=320 border=1 link]
Обратите внимание на разницу между методами сдвига!
<ul>
<li>`hr.margin` сначала сдвинулся, а потом нарисовался до конца блока.</li>
<li>`hr.position` сначала нарисовался, а потом сдвинулся -- в результате справа осталось пустое пространство.</li>
</ul>
Уже отсюда видно, что отрицательные `margin` -- исключительно полезное средство позиционирования!
## Отрицательные margin-right/bottom
Отрицательные `margin-right/bottom` ведут себя по-другому, чем `margin-left/top`. Они не сдвигают элемент, а "укорачивают" его.
То есть, хотя сам размер блока не уменьшается, но следующий элемент будет думать, что он меньше на указанное в `margin-right/bottom` значение.
Например, в примере ниже вторая строка налезает на первую:
```html
<!--+ autorun height=80 -->
<div style="border: 1px solid blue; *!*margin-bottom: -0.5em*/!*">
Первый
</div>
<div style="border: 1px solid red">
Второй div думает, что высота первого на 0.5em меньше
</div>
```
Это используют, в частности для красивых вносок, с приданием иллюзии глубины.
Например:
[iframe src="negative-margin-bottom" border=1 height=200 link="Посмотреть в отдельном окне" edit]
## Итого
<ul>
<li>Отрицательные `margin-left/top` сдвигают элемент влево-вверх. Остальные элементы это учитывают, в отличие от сдвига через `position`.</li>
<li>Отрицательные `margin-right/bottom` заставляют другие элементы думать, что блок меньше по размеру справа-внизу, чем он на самом деле.</li>
</ul>
Отличная статья на тему отрицательных `margin`: [The Definitive Guide to Using Negative Margins](http://coding.smashingmagazine.com/2009/07/27/the-definitive-guide-to-using-negative-margins/)