Абсолютное горизонтальное и вертикальное центрирование. Лишнее пространство между элементами списка. Установка минимальных размеров

Internet Explorer - это проблема, которая портит жизнь большинства веб-разработчиков. Более 60% времени разработки может уходить на решение этих специфичных проблем, что не является эффективным использованием времени. В этой статье я расскажу о самых популярных багах и несоответствиях при позиционировании, а также о том, как наиболее просто можно решить эти проблемы.

1. Позиционирование по центру.

Каждый веб-разработчик, при вёрстке сайта, сталкивался с необходимостью выровнять элемент по центру. Самый простой и популярный способ - это написать margin: auto; . Это способ позволяет центрировать элемент независимо от разрешения экрана. Однко в IE6 этот способ не работает.

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

#container { border: solid 1px #000; background: #777; width: 400px; height: 160px; margin: 30px 0 0 30px; } #element { background: #95CFEF; border: solid 1px #36F; width: 300px; height: 100px; margin: 30px auto; }

Ожидаемый результат:

Однако Internet Explorer покажет вам следующее:

Это происходит потому что IE6 не распознаёт значение auto установленное свойству margin . К счастью, это легко пофиксить.

Исправляем.

Простейший и испытанный способ центрировать элемент в IE6 - это написать text-alignL center для родительского элемента и применить tex-align: left для него самого, чтобы его содержимое было выровнено корерктно.

#container{ border: solid 1px #000; background: #777; width: 400px; height: 160px; margin: 30px 0 0 30px; text-align: center; } #element{ background: #95CFEF; border: solid 1px #36F; width: 300px; height: 100px; margin: 30px 0; text-align: left; }

2. Эффект ступенек

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

Ul { list-style: none; } ul li a { display: block; width: 130px; height: 30px; text-align: center; color: #fff; float: left; background: #95CFEF; border: solid 1px #36F; margin: 30px 5px; }

Получаем следующее:

Однако IE нам покажет:

Не очень дружелюбная навигация, не правда ли? Однако есть 2 способа пофиксить это неприятное поведение.

1-ый способ

Простейший способ - это установить свойство float не ссылкам, а элементам списка li .

Ul li { float: left; }

2-ой способ

Второй способ - это применить свойство display: inline для элемента li . Дополнительно мы фиксим баг с двойным внешним отступом, который описан ниже.

Ul li { display: inline }

3. Двойной отступ для элементов с установленным свойством float

Воспроизвети эту ошибку очень просто. Устанавливаем элементу float: left а затем внешний отступ. В результате получаем отступ в два раза больше указанного.

Рассмотрим пример:

#element{ background: #95CFEF; width: 300px; height: 100px; float: left; margin: 30px 0 0 30px; border: solid 1px #36F; }

Ожидаемый результат:

Однако в IE6 мы увидем следующее:

Исправляем

Исправляется это таким же образом как и проблема с эффектом ступенек. То есть устанавливаем свойство display: inline для элемента. Наш код изменится так:

#element{ background: #95CFEF; width: 300px; height: 100px; float: left; margin: 30px 0 0 30px; border: solid 1px #36F; display: inline; }

4. Элементы с маленькой высотой.

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

В результате мы получаем элемент с высотой 2px и с границей в 1px.

Исправляем.

Причина этого бага очень проста: IE просто изменяет высоту элемента до высоты равной размеру шрифта. Таким образом просто устанавливаем размер шрифта равным нулю.

#element{ background: #95CFEF; border: solid 1px #36F; width: 300px; height: 2px; margin: 30px 0; font-size: 0; }

Второй подход

Ещё один хороший способ - это использовать свойство overflow , необходимо применить значение hidden . И тогда элемент будет необходимой высоты.

#element{ background: #95CFEF; border: solid 1px #36F; width: 300px; height: 2px; margin: 30px 0; overflow: hidden; }

5. Overflow и относительное позиционирование элементов.

Этот баг проявляется в случае когда родительскому элементу установлено свойство overflow: auto , а дочерний позиционирован относительно него, то есть ему установлено свойство position: relative . При этом получается что дочерний элемент находится как бы поверх родительского. Давайте рассмотрим на примере:

#element{ background: #95CFEF; border: solid 1px #36F; width: 300px; height: 150px; margin: 30px 0; overflow: auto; } #anotherelement{ background: #555; width: 150px; height: 175px; position: relative; margin: 30px; }

Ожидаемый результат:

Результат в IE:

Исправляем.

Простейший способ решить проблему - установить родительскому элементу относительное позиционирование.

#element{ background: #95CFEF; border: solid 1px #36F; width: 300px; height: 150px; margin: 30px 0; overflow: auto; position: relative; }

6. Box Model

Internet Explorer неверно интерпретирует модель внешних и внутренних отступов - box model.

К примеру есть 2 элемента div . Один с исправленной ошибкой, а второй - нет. Между ними будет разница в размерах, равная сумме внутренних отступов.

Исправляем

Про корректную модель я расскажу в другой статье, сейчас же просто покажу как это исправить.

Смысл в том, что для IE5/6 высоту и ширину надо устанавливать отдельно. Я например делаю это так:

Для всех браузеров

#element{ width: 400px; height: 150px; padding: 50px; }

Для IE надо делать так:

#element { width: 400px; height: 150px; \height: 250px; \width: 500px }

По существу, вы добавляете значения внутренних отступов к размерам элемента для IE6.

7. Установка минимальных размеров.

Минимальные ширина и высота просто незаменимы когда делаешь красивый дизайн. К сожалению, IE игнорирует свойства min-height и min-width .

Исправляем

Для решения проблемы воспользуемся идентификатором!important .

#element { min-height: 150px; height: auto !important; height: 150px; }

Второй вариант.

Если мы примем во внимание тот факт, что IE не понимает вложенные селекторы, то можно сделать так:

#element { min-height: 150px; height: 150px; } html>body #element { height: auto; }

8. Неверное поведение в модели float.

Одна из самых главных концепций в бестабличной вёрстке используя CSS - это float . В большинстве случаев IE6 обрабатывает это корректно, но иногда бывают проблемы. Например когда контент неразрывный или ширина элемента больше, чем ширина родительского. В этих случаях разметка ломается. Давайте посмотрим пример.

http://net.tutsplus.com/

#element, #anotherelement{ background: #95CFEF; border: solid 1px #36F; width: 100px; height: 150px; margin: 30px; padding: 10px; float: left; } #container{ background: #C2DFEF; border: solid 1px #36F; width: 365px; margin: 30px; padding: 5px; overflow: auto; }

Получили в IE:

Как видите, первый div расширился по ширине контента и вытолкнул соседний на следующую строку.

Исправляем

Красивого решения нет. Но можно, например, применить свойство overflow: hidden , но тогда контент отсечётся и часть его не будет видно.

#element{ background: #C2DFEF; border: solid 1px #36F; width: 365px; margin: 30px; padding: 5px; overflow: hidden; }

9. Лишнее пространство между элементами списка.

IE 6 добавляет лишние отступы в вертикальных списках. Рассмотрим пример.

  • Link 1
  • Link 2
  • Link 3

Ul { margin:0; padding:0; list-style:none; } li a { background: #95CFEF; display: block; }

Как это должно выглядеть:

Что показывает IE:

1-ый способ

Самый простой способ - это указать ширину или высоту для ссылки.

Li a { background: #95CFEF; display: block; width: 200px; }

2-ой способ

Следующий способ - это установить float: left , а затем очисить его.

Li a { background: #95CFEF; float: left; clear: left; }

3-ий способ

Третий способ - это установить display: inline для элемента li . Что, кстати исправит ошибку с двойным внешним отступом, описанную выше.

Использование 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 » был подготовлен дружной командой проекта .

Хорошо Плохо

Описание

Устанавливает величину отступа от каждого края элемента. Отступом является пространство от границы текущего элемента до внутренней границы его родительского элемента (рис. 1).

Рис. 1. Отступ от левого края элемента

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

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

Синтаксис

margin: [значение | проценты | auto] {1,4} | inherit

Значения

Разрешается использовать одно, два, три или четыре значения, разделяя их между собой пробелом. Эффект зависит от количества значений и приведен в табл. 1.

Величину отступов можно указывать в пикселах (px), процентах (%) или других допустимых для CSS единицах. Значение может быть как положительным, так и отрицательным числом.

Auto Указывает, что размер отступов будет автоматически рассчитан браузером. inherit Наследует значение родителя.

HTML5 CSS2.1 IE Cr Op Sa Fx

margin

Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.

Результат данного примера показан на рис. 2.

Рис. 2. Применение свойства margin

Объектная модель

document.getElementById("elementID ").style.margin

Браузеры

Internet Explorer 6 в режиме совместимости (quirk mode) не поддерживает выравнивание блока по центру с помощью правила margin: 0 auto . Также в этом браузере наблюдается ошибка с удвоением значения левого или правого отступа для плавающих элементов, вложенных в родительские элементы. Удваивается тот отступ, который прилегает к стороне родителя. Проблема обычно решается добавлением display: inline для плавающего элемента.

Internet Explorer до версии 7.0 включительно не поддерживает значение inherit .

Примечание

У блочных элементов расположенных рядом друг с другом по вертикали наблюдается эффект схлопывания, когда отступы не суммируются, а объединяются между собой. Само схлопывание действует на два и более блока (один может быть вложен внутрь другого) с отступами сверху или снизу, при этом примыкающие отступы комбинируются в один. Для отступов слева и справа схлопывание никогда не применяется.

Схлопывание не срабатывает:

  • для элементов, у которых на стороне схлопывания задано свойство padding .
  • для элементов, у которых на стороне схлопывания задана граница;
  • на элементах с абсолютным позиционированием, т.е. таких, у которых position установлено как absolute ;
  • на плавающих элементах (для них свойство float задано как left или right );
  • для строчных элементов;
  • для .

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

Центровка элементов по горизонтали не так уж и сложна, по вертикали уже вызывает вопросы, ну а комбинирование вообще может поставить в тупик. В эру адаптивного дизайна, нам редко точно ясны размеры тех или иных элементов. Я насчитал 6 различных способов центровки элементов с помощью CSS. Начнём с простых примеров, закончим более сложными. Работать будет с одним и тем же HTML кодом:

Горизонтальная центровка с помощью text-align

Порой, самое простое решения является самым лучшим:

Div.center { text-align: center; background: hsl(0, 100%, 97%); } div.center img { width: 33%; height: auto; }

Тут нет вертикальной центровки: для этого вам нужно будет к div-у добавить свойство margin-top и margin-bottom.

Центровка с помощью margin: auto

Ещё одно решения для горизонтальной центровки:

Div.center { background: hsl(60, 100%, 97%); } div.center img { display: block; width: 33%; height: auto; margin: 0 auto; }

Заметьте что для этого способа нужно выставить свойство display: block.

Центровка с помощью table-cell

Используя display: table-cell, мы можем обеспечить центровку элемента как по вертикали, так и по горизонтали. Но тут нам понадобится вложить изображение ещё в один элемент div.

Center-aligned { display: table; background: hsl(120, 100%, 97%);width: 100%; } .center-core { display: table-cell; text-align: center; vertical-align: middle; } .center-core img { width: 33%; height: auto; }

Чтобы всё работало корректно, div-у нужно выставить width: 100%. Для центровки элемента по вертикали, воспользуемся стандартными приёмами, выставив высоту. Работает везде, включая IE8+.

Абсолютная центровка

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

Absolute-aligned { position: relative; min-height: 500px; background: hsl(200, 100%, 97%); } .absolute-aligned img { width: 50%; min-width: 200px; height: auto; overflow: auto; margin: auto; position: absolute; top: 0; left: 0; bottom: 0; right: 0; }

Центрируем с помощью translate

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

Center { background: hsl(180, 100%, 97%); position: relative; min-height: 500px; } .center img { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 30%; height: auto; }

Есть несколько минусов:

  • Свойство CSS transform требует использование браузерных префиксов
  • Не работает в старых версиях IE (8 и ниже)
  • Внешнему контейнеру нужно задавать высоту.
  • Если внутри контейнера есть текст, то он может быть немного размыт.

Центровка с помощью вида отображения flex

Наверное самый простой вариант.

Center { background: hsl(240, 100%, 97%); display: flex; justify-content: center; align-items: center; } .center img { width: 30%; height: auto; }

Работает не во всех версиях IE (хотя можно подстраховать себя, используя вдобавок display: table-cell). Полный CSS:

Center { background: hsl(240, 100%, 97%); display: -webkit-box; /* Safari, iOS 6 и ранних версиях; Android, старых WebKit */ display: -moz-box; /* Firefox (может и глючить) */ display: -ms-flexbox; /* IE 10 */ display: -webkit-flex; /* Chrome 21+ */ display: flex; /* Opera 12.1+, Firefox 22+ */ -webkit-box-align: center; -moz-box-align: center; -ms-flex-align: center; -webkit-align-items: center; align-items: center; -webkit-box-pack: center; -moz-box-pack: center; -ms-flex-pack: center; -webkit-justify-content: center; justify-content: center; }

Центровка с помощью calc

В некоторых случаях, данный способ более универсален чем использование flexbox:

Center { background: hsl(300, 100%, 97%); min-height: 600px;position: relative; } .center img { width: 40%; height: auto; position: absolute; top:calc(50% - 20%); left: calc(50% - 20%); }

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

Top: calc(50% - (40% / 2)); left: calc(50% - (40% / 2));

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

Center img { width: 500px; height: 500px; position: absolute; top:calc(50% - (300px / 2)); left: calc(50% - (300px - 2)); }

Данный метод поддерживается Firefox-ом, начиная с 4 версии, вам нужно будет прописать браузерные префиксы. В IE 8 не работает. Полный код:

Center img { width: 40%; height: auto; position: absolute; top: -webkit-calc(50% - 20%); left: -webkit-calc(50% - 20%); top: -moz-calc(50% - 20%); left: -moz-calc(50% - 20%); top: calc(50% - 20%); left: calc(50% - 20%); }

Надеюсь, данных методов хватит, чтобы вы нашли для себя лучшее решение.