Свойство
margin
очень хорошо для решения задачи установления дистанции между элементами, но знаете ли вы, что отрицательныеmargin
могут не увеличивать, а сокращать расстояние между элементами, вплоть до того, что эти элементы будут перекрывать друг друга.
Создадим простой пример и для этого предположим, что у нас есть страница, на которой элемент после заголовка h2
всегда должен находиться непосредственно под ним. Самый распространенный пример из практики для этого случая, когда первый параграф, идущий сразу же после заголовка, не имеет пустого пространства (blank line) между собой и этим параграфом.
Решения такого вопроса два.
Первый способ - это воспользоваться смежными селекторами.
Второй способ, представленный на рисунке ниже, это применить отрицательный margin-bottom
для h2
:
Можно подумать, что у параграфа, который следует сразу за заголовком, отсутствует margin-top
, но это не так. Margin-top
никуда не пропадал.
Он просто оказался перекрытым заголовком h2
, у которого край margin-bottom
находится в непосредственной близости от края текста самого заголовка. Параграф и его собственный margin
располагаются сразу под ним, а не у нижнего края границы заголовка.
Такой прием полезен на практике в случае, когда необходимо расположить часть контента “на одной линии”. Почему слово на одной линии заключено в кавычки - потому-что контент только визуально располагается на одной линии.
Предположим, у нас есть список (HTML-разметка):
В этом списке нам необходимо расположить оба пункта так, чтобы они находились на горизонтальной линии. Визуально это можно увидеть так, как изображено на рисунке ниже.
Такую задачу можно выполнить обычным способом - через float
(прим. переводчика - я бы так и поступил, разбросал оба li
по разным углам блока ul
через float: left
и float: right
) для обоих пунктов.
Но можно решить такую задачу другим способом:
.jump{
list-style-type: none;
line-height: 1;
width: 25em;
margin: 0 auto;
padding: .25em 1em;
border: 1px solid;
}
.jump .next{
text-align: right;
margin-top: -1em;
}
В этом примере отрицательный margin-top
величиной в -1em
“поднимает” элемент li.next
вверх ровно на высоту строки, установленную нами ранее в правиле line-height: 1
.
Прим. переводчика: очень понравилось, о таком способе решения даже не подозревал!
Другим полезным приемом является частичное выдвижение элемента изнутри наружу своего контейнера-родителя. Предположим, у нас стоит задача расположить блок заголовка точно по центру разделительной линии так, как это показано на рисунке ниже:
HTML-разметка такого заголовка будет следующей:
class="entry">
The Web Stack
...
.entry{
border-top: 1px solid gray;
}
.entry h2{
width: 80%;
background-color: #fff;
border: 1px solid gray;
margin: -0.67em auto 0;
text-align: center;
}
C другой стороны, может потребоваться задача, когда блок заголовка не имеет фиксированной ширины, а ширина задается только его содержимым. В этом случае необходимо добавить всего несколько строк кода в HTML-разметку и CSS-правила, соответственно:
HTML-разметка, в которой добавлен еще один элемент - span
:
.entry h2{
margin-top: -0.67em;
text-align: center;
border-top: 1px solid gray;
}
.entry h2 span{
background-color: #fff;
border: 1px solid gray;
padding: .25em 1em;
}
В этом примере все хорошо работает до тех пор, пока длина текста внутри блока меньше, чем длина разделительной линии. Заголовок разбивается на две линии, сам блок заголовка вмещается вниз от разделительной линии и перестает быть расположенным по центру.
Для этого случая решение с помощью отрицательного margin-top
не является самым лучшим. Можно лишь посоветовать убрать верхнюю границу border-top
у блока-родителя и сделать для него фоновую заливку белого цвета, также. Это будет не совсем то, что нужно; но все же достаточно хорошее решение.
Автор статьи: Eric Meyer - “Smashing CSS Professional Techniques for Modern Layout”
На этом все.
Комментарии