Html margin top не работает. Эффективные техники, основанные на использовании отрицательного margin

28.03.2019

Использование margin:auto , чтобы отцентрировать блочный элемент по горизонтали, это хорошо известный способ. Но задумывались ли вы, как это работает?

Результат действия значения auto зависит типа элемента и контекста. Для отступов сверху CSS auto может означать одно из двух: занять все свободное пространство или 0 пикселей. В зависимости от этого будет задаваться различная структура.

«auto» — занять все доступное пространство

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

Посмотреть пример

Это работает только для горизонтальных отступов. Но не будет работать для плавающих и строчных элементов. А также для абсолютно и фиксировано позиционированных элементов.

Имитация плавающего поведения через распределение доступного пространства

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

Посмотреть пример

«auto» — задать 0 пикселей

Как упоминалось выше, auto не работает для плавающих, строчных и абсолютно позиционированных элементов. Для них уже определена структура, так что в использовании margin auto нет смысла.

Это будет только нарушать изначальную структуру. В том числе и для отступа текста сверху CSS . Следовательно, auto будет задавать значение 0 пикселей для отступов этих элементов.

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

Значение auto будет определять отступ в 0 пикселей, когда для блочного элемента задана ширина auto или 100% . Обычно он занимает всю ширину контейнера, следовательно, на ширину отступа останется 0 пикселей.

Что происходит с вертикальными отступами со значением auto?

auto и для отступа сверху CSS , и для нижнего отступа всегда вычисляется как 0 пикселей (за исключением абсолютно позиционированных элементов ). В спецификации W3C указано следующее:

«Если для “margin-top” или “margin-bottom” задано «auto», для них используется значение, равное 0″.

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

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

Или из-за эффекта объединения отступов (слияния отступов соседних элементов ). Это еще одно исключение из данного правила определения вертикальных отступов.

Центрирование абсолютно позиционированных элементов

Так как для абсолютно позиционированных элементов введено исключение, можно использовать значение auto , чтобы выровнять их по центру вертикально и горизонтально. Но сначала нужно выяснить, когда margin:auto будет работать именно так для отступа сверху CSS .

В другой спецификации W3C сказано:

«Если для всех трех позиций (“left”, “width” и “right”) задано значение «auto», сначала установите 0 для “margin-left” и “margin-right…»
» Если «auto» задано только для “margin-left” и “margin-right», тогда решите уравнение с дополнительным условием, чтобы для обоих отступов была задана одинаковая ширина».

Здесь довольно подробно описана ситуация, касающаяся значения auto для горизонтальных отступов. Чтобы эти отступы имели одинаковый размер, для left , width и right не должно задаваться значение auto (их значение по умолчанию ). Чтобы отцентрировать элемент по горизонтали, нужно задать определенное значение для ширины абсолютно позиционируемого элемента, а left и right при этом должны иметь равные значения.

В спецификации также упоминается что-то подобное и для отступов сверху CSS div.

«Если для «top», «height» и «bottom» задано значение «auto» , установите для «top» позицию static…»

«Если для одной из трех позиций не установлено значение «auto»: если для «top» и «bottom» установлено значение «auto», решите уравнение с дополнительным условием, чтобы задать для этих отступов одинаковые значения».

Следовательно, чтобы отцентрировать по вертикали абсолютно позиционируемый элемент top , height и bottom не должны иметь значение auto .

Теперь, объединив все это, мы получим следующее:

Посмотреть пример

Заключение

Если вам требуется сместить элемент на странице вправо или влево без контейнерных элементов (например, как в случае с float ), помните, что есть возможность использовать для отступов значение auto .

Преобразование элемента в абсолютно позиционируемый только для того, чтобы отцентрировать его по вертикали (отступы сверху CSS ), не лучшая идея. Существуют и другие варианты, такие как flexbox и CSS transform , которые больше подходят для этого.

Перевод статьи «CSS – margin auto – How it Works » был подготовлен дружной командой проекта .

Хорошо Плохо

Есть несколько точек зрения на использование отрицательных полей (margin) в CSS , как резко отрицательное, так и сугубо положительное.

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

CSS

#content {margin-left:-100px;}

Отрицательные поля, как правило, используются в малых дозах, но, как вы увидите позднее, они способны на большее. Есть несколько вещей об отрицательных полях, которые необходимо знать (чтобы не ошибаться при верстке):

  • Валидность в css
    W3C говорит нам: ‛Отрицательные значения для свойства margin использовать допустимо“. Более подробно на www.w3.org/TR/CSS2/box.html#margin-properties
  • Отрицательные поля не ХАК
    Это идет от непонимания и от внешнего воздействия отрицательного margin на верстку. Отрицательное поле может стать хаком лишь тогда, когда вы пытаетесь поправить ошибку в своем коде при помощи отрицательного margin .
  • Воздействие на поток
    Отрицательные поля не разрушают поток, если применяются к ‛не плавающим“ элементам. То есть если вы используете отрицательно поле, чтобы толкнуть элемент вверх, то все последующие элементы также будут приподняты.
  • Разная реакция, когда используется совместно с float
    Отрицательные поля это все же не повседневный CSS, поэтому вы должны использовать такой margin с осторожностью.
  • Какие-то проблемы dreamveawer
    Тут и обсуждать нечего.
  • Полная совместимость
    Отрицательные поля поддерживаются всеми браузерами, включая IE6.

Работаем с отрицательными полями (margin)

Отрицательные поля очень мощная штука, когда используется корректно.


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

  • Когда статический элемент получает отрицательный margin для top/left, то элемент ‛движется“ в указанном(top/left) направлении.

    CSS

    /* Элемент перемещается на 10px вверх */ #mydiv1 {margin-top:-10px;}
  • Но если вы используете его для down/right, то элемент не сместится по направлению down/right, как вы предполагаете. Вместо этого этим вы втолкнете последующий элемент в основной элемент, перекрывая его.

    CSS

    /* Все следующие элементы за #mydiv1 сместятся вверх на 10px, при этом сам #mydiv1 не сместится */ #mydiv1 {margin-bottom:-10px;}
  • Если у элемента не задана ширина, то при использовании отрицательного margin по направлению left/right элемент будет вытолкнут в обоих направлениях с увеличением ширины элемента .

    CSS

    #mydiv1{margin:0 auto -20px; height: 150px; /*...*/} #mydiv2{margin:0 auto; height: 150px; /*...*/}

Отрицательное поле для плавающих элементов

Рассмотрим следующую разметку:

HTML

First
Second
  • Если отрицательное поле применяется к плавающему элементу, то создается пространство, приводящее к перекрытию контента. Это замечательно для жидких макетов, где одна колонка имеет ширину 100% , а другая колонка, например, фиксированную ширину в 100px .

    CSS

    #mydiv1 {float:left; margin-right:-100px;}
  • Если оба элемента смещены влево (float:left) и #mydiv1 имеет margin-right:-20px , то #mydiv2 рассматривает #mydiv1 , как если бы его ширины была на 20px меньше актуальной (таким образом, перекрывая его). Что интересно, контент #mydiv1 не реагирует на эти манипуляции и сохраняет свою текущую ширину.
  • Если отрицательное поле равно фактической ширине, то перекрытие будет полным. Это происходит потому, что поля, отступы, границы и ширина добавляются к фактической ширине элемента. Таким образом, если отрицательное поле равно общей ширине из всех вышеперечисленных свойств, то фактическая ширина элемента становится равной 0 .

Эффективные техники, основанные на использовании отрицательного margin

С тех самых пор как мы узнали, что отрицательное поле есть валидный код, возникло несколько полезных техник CSS основанных на этом приеме.

Если у вас есть список, в котором так много пунктов, что показывать их по вертикали неразумно, то почему бы не разделить такой список на три колонки?


Отрицательные поля справятся с этим, причем без использования дополнительных тегов и свойства float . Просто удивительно, как легко разделить список на три колонки, например:

HTML

  • Eggs
  • Ham
  • Bread
  • Butter
  • Flour
  • Cream

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

Начинающим верстальщикам она точно будет полезна, а вот профессионалам - сомневаюсь, так как человек занимающийся не первый год версткой уже обязан «вызубрить» наизусть все особенности данного свойства.

В этой части статьи я напишу о вертикальном маргине. О горизонтальном поговорим в следующей части.

Для начала, разберем вкратце, какие есть единицы измерения, что они означают и какие использовать для отступов маргин.

Cm, mm, inch, pc, pt – абсолютные единицы измерения. Рекомендуется использовать при печати документов.

Px, em, ex, % - относительные единицы, используются для мониторов.

Для маргина, я использую px и % , а em – для указания размеров шрифта. Ex(в IE ex = em / 2) – использовать не рекомендую, т.к в каждом броузере интерпретируется по-разному.

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

Область просмотра – то, на чем пользователь видит содержимое сайта, не прокручивая при этом экран. У каждого пользователя она разная.

Каждый верстальщик знает, что любой элемент можно представить в виде 4 областей(маргин, бордер, паддинг и контент).

Маргин – внешний отступ. По вертикали и горизонтали построение маргин разные.

Как я уже писал выше, размеры для маргина могут проставляться в em, ex, px – жесткое задавание и в % - считаются относительно какой-то области.

Приведу пример одной из частых допускаемых ошибок начинающих верстальщиков.

Есть 2 дива: first и внем див second.


#first{
padding: 100px;
background: #b5bcbc;
}
#second{
height: 100px;
background: #b06b48;
margin: 30% 0 0;
}

Прошу обратить внимание что свойство width я не задал ни одному диву(об этом поговорим позже). Сейчас нас интересует только маргин, который равен margin: 30% 0 0;

Я надеюсь, что все знают, как считается маргин в данном случае, на всякий случай напомню, что считается по часовой стрелке, тоесть: сверху отступ будет 30%, справа - 0, снизу - 0 и слева, - так как я ничего не указал, то маргин принимает значение противоположной стороны, тоесть в данном случает, если маргин справа равен 0, то маргин слева, если не указан, тоже равен 0.

Но сейчас нас интересует маргин, который равен 30%, он же отступ сверху. Откуда же берутся эти 30%?

Многие считают и считают неверно, что 30% берутся от верхней части всей страницы.


Но это неверно!

Так как в данном случае, див second вложен в див first, то margin-top:30% будет считаться относительно ширины родительского дива second, тоесть относительно ширины дива first!


В данном случае ширина дива first по умолчанию авто, поэтому див принимает все свободное пространство по ширине, а из этой ширины будут высчитываться 30% маргин-топ для дива second.

При уменьшении родительского дива, будет и уменьшаться отступ сверху у дива second.

Маргин также может быть и отрицательный. В этом случае элемент по вертикали позволяет «заехать» на себя другому элементу или «выехать низу» за пределы своего контейнера.

Например: два дива, лежащие один под другим.


если мы добавим первому диву margin-bottom: -100px , а второму margin-top: -50px
#first{
height: 200px;
background: #69c;
margin: 0 0 -100px;
}
#second{
height: 200px;
background: #f60;
margin: -50px 100px 0;
}

То произойдет следующее.


Но… тут и наступает большая ошибка новичков.

Многие думают, что так как верхний див имеет маргин-боттом -100px, а нижний див, маргин-топ -50px, то нижний див «заедет» на верхний на -150px.

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

В данном случае нижний див «заедет» на верхний див на 100px, а 50px учитываться не будут.

Тоже самое верно и для положительных маргинов, нижний див «уедет» от верхнего на 100px, а 50px учитываться не будут.

Рассмотрим следующий пример.
Есть 2 дива, один под другим.


#first{
height: 200px;
background: #69c;
margin: 0 0 -100px;
}
#second{
height: 200px;
background: #f60;
margin: 50px 100px 0;
}

First
second

Как видите маргин-боттом первого - отрицательный, а маргин-топ второго - положительный, что произойдет в данной ситуации?

Для разноименных маргинов произойдет сложение, тоесть: -100 + 50 = -50. Соответственно нижний див поднимиться на 50px вверх.

Два дива, один вложен в другой.


#first{
background: #b5bcbc;
}
#second{
height: 200px;
background: #b06b48;
}

Если в цсс добавить внутреннему диву маргин-топ 200px,
#second{
height: 200px;
background: #b06b48;
margin-top: 200px;
}

То, вот тут то и очередная ошибка! Некоторые считают, что внутренний маргин, должен «отодвинуться» от своего родителя на 200px вниз а его родитель останется на месте, и тем самым растянется.


Но, как бы не так!

Если у родительского эл-та нет ограничивающих факторов (об этих факторах напишу чуть ниже), то маргин переходит от внутреннего элемента к внешнему. Потом по старой схеме выбирается маргин: если они одноименные, то выбирается больший, если разноименные, то происходит сложение.
И результат


Но, как быть, если нам это не нужно и мы хотим, чтобы див-родитель остался на своем месте, а див-ребенок отодвинулся на 200px вниз?

Можно отменить это действие по отношению к родителю, есть несколько способов.
1. задавание padding родительскому блоку
2. задавание border родительскому блоку
3. задавание overflow родительскому блоку, любое значение кроме visible(работает везде, кроме старых ИЕ)
И вуаля


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

14 июня 2011 в 17:48

Поговорим о margin, он же маргин(часть 1-я)

  • CSS

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

Начинающим верстальщикам она точно будет полезна, а вот профессионалам - сомневаюсь, так как человек занимающийся не первый год версткой уже обязан «вызубрить» наизусть все особенности данного свойства.

В этой части статьи я напишу о вертикальном маргине. О горизонтальном поговорим в следующей части.

Для начала, разберем вкратце, какие есть единицы измерения, что они означают и какие использовать для отступов маргин.

Cm, mm, inch, pc, pt – абсолютные единицы измерения. Рекомендуется использовать при печати документов.

Px, em, ex, % - относительные единицы, используются для мониторов.

Для маргина, я использую px и % , а em – для указания размеров шрифта. Ex(в IE ex = em / 2) – использовать не рекомендую, т.к в каждом броузере интерпретируется по-разному.

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

Область просмотра – то, на чем пользователь видит содержимое сайта, не прокручивая при этом экран. У каждого пользователя она разная.

Каждый верстальщик знает, что любой элемент можно представить в виде 4 областей(маргин, бордер, паддинг и контент).

Маргин – внешний отступ. По вертикали и горизонтали построение маргин разные.

Как я уже писал выше, размеры для маргина могут проставляться в em, ex, px – жесткое задавание и в % - считаются относительно какой-то области.

Приведу пример одной из частых допускаемых ошибок начинающих верстальщиков.

Есть 2 дива: first и внем див second.


#first{
padding: 100px;
background: #b5bcbc;
}
#second{
height: 100px;
background: #b06b48;
margin: 30% 0 0;
}

Прошу обратить внимание что свойство width я не задал ни одному диву(об этом поговорим позже). Сейчас нас интересует только маргин, который равен margin: 30% 0 0;

Я надеюсь, что все знают, как считается маргин в данном случае, на всякий случай напомню, что считается по часовой стрелке, тоесть: сверху отступ будет 30%, справа - 0, снизу - 0 и слева, - так как я ничего не указал, то маргин принимает значение противоположной стороны, тоесть в данном случает, если маргин справа равен 0, то маргин слева, если не указан, тоже равен 0.

Но сейчас нас интересует маргин, который равен 30%, он же отступ сверху. Откуда же берутся эти 30%?

Многие считают и считают неверно, что 30% берутся от верхней части всей страницы.


Но это неверно!

Так как в данном случае, див second вложен в див first, то margin-top:30% будет считаться относительно ширины родительского дива second, тоесть относительно ширины дива first!


В данном случае ширина дива first по умолчанию авто, поэтому див принимает все свободное пространство по ширине, а из этой ширины будут высчитываться 30% маргин-топ для дива second.

При уменьшении родительского дива, будет и уменьшаться отступ сверху у дива second.

Маргин также может быть и отрицательный. В этом случае элемент по вертикали позволяет «заехать» на себя другому элементу или «выехать низу» за пределы своего контейнера.

Например: два дива, лежащие один под другим.


если мы добавим первому диву margin-bottom: -100px , а второму margin-top: -50px
#first{
height: 200px;
background: #69c;
margin: 0 0 -100px;
}
#second{
height: 200px;
background: #f60;
margin: -50px 100px 0;
}

То произойдет следующее.


Но… тут и наступает большая ошибка новичков.

Многие думают, что так как верхний див имеет маргин-боттом -100px, а нижний див, маргин-топ -50px, то нижний див «заедет» на верхний на -150px.

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

В данном случае нижний див «заедет» на верхний див на 100px, а 50px учитываться не будут.

Тоже самое верно и для положительных маргинов, нижний див «уедет» от верхнего на 100px, а 50px учитываться не будут.

Рассмотрим следующий пример.
Есть 2 дива, один под другим.


#first{
height: 200px;
background: #69c;
margin: 0 0 -100px;
}
#second{
height: 200px;
background: #f60;
margin: 50px 100px 0;
}

First
second

Как видите маргин-боттом первого - отрицательный, а маргин-топ второго - положительный, что произойдет в данной ситуации?

Для разноименных маргинов произойдет сложение, тоесть: -100 + 50 = -50. Соответственно нижний див поднимиться на 50px вверх.

Два дива, один вложен в другой.


#first{
background: #b5bcbc;
}
#second{
height: 200px;
background: #b06b48;
}

Если в цсс добавить внутреннему диву маргин-топ 200px,
#second{
height: 200px;
background: #b06b48;
margin-top: 200px;
}

То, вот тут то и очередная ошибка! Некоторые считают, что внутренний маргин, должен «отодвинуться» от своего родителя на 200px вниз а его родитель останется на месте, и тем самым растянется.


Но, как бы не так!

Если у родительского эл-та нет ограничивающих факторов (об этих факторах напишу чуть ниже), то маргин переходит от внутреннего элемента к внешнему. Потом по старой схеме выбирается маргин: если они одноименные, то выбирается больший, если разноименные, то происходит сложение.
И результат


Но, как быть, если нам это не нужно и мы хотим, чтобы див-родитель остался на своем месте, а див-ребенок отодвинулся на 200px вниз?

Можно отменить это действие по отношению к родителю, есть несколько способов.
1. задавание padding родительскому блоку
2. задавание border родительскому блоку
3. задавание overflow родительскому блоку, любое значение кроме visible(работает везде, кроме старых ИЕ)
И вуаля


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