CSS margin:auto - Як це працює? Для всіх браузерів. Неправильна поведінка у моделі float

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; wid; 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 способи пофіксувати цю неприємну поведінку.

Перший метод

Найпростіший спосіб - встановити властивість float не посиланням, а елементам списку li .

Ul li (float: left;)

Другий метод

Другий спосіб – це застосувати властивість 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: 1 : 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.

Виправляємо

Для вирішення проблеми скористаємося ідентифікатором!

#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: 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:

Перший метод

Найпростіший спосіб – це вказати ширину або висоту для посилання.

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

Другий метод

Наступний спосіб - це встановити float: left, а потім очисити його.

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

Третій метод

Третій спосіб - встановити 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. У 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);
  • для малих елементів;
  • для .

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

Добре погано