проблеми css

Для багатьох речей, css, не був призначений спочатку, наприклад для таких як: багатоколонкові, чуйний веб дизайн і т.д. Ось чому він став мовою повним хаков і глюків, як якась давня машина з купою розширень.

У кращому випадку - роботу з css можна назвати веселим заняттям. І це те, завдяки чому ми маємо роботу. Тому що, як я вважаю, генерація ефективних і кросбраузерності css стилів неможлива і не буде можлива найближчим часом.

проблеми css

Перейдемо до суті, адже я тут не для того, що б висловити свою думку про css. А для того, що б розглянути ряд часто зустрічаються в css проблем, і їх можливих рішень.

Я намагався вибрати кілька дійсно дуже поширених:

  • Очищення float`ов.
  • Як перемогти відступи між елементами з inline-block?
  • Розуміння абсолютного позиціонування.
  • Коли встановлювати значенням width / height розмір рівний 100%? (частина 2)
  • Як не перемудрувати з z-index. (частина 2)
  • Що таке згортання кордонів (margin collapsing)? (частина 2)

Очищення float`ов.

Мені здається, що це найпоширеніший питання в css. Він старий як світ, чесно, я на тисячу відсотків упевнений, що кожен, хто хоч коли небудь писав на css стикався з ним.

Простими словами його можна описати так: коли всередині елемента містяться тільки елементи з float, він схлопивается так, як ніби в ньому взагалі немає дочірніх елементів. Тобто, за фактом, елементи з float випадають із загального потоку.

проблеми css

Є кілька способів для вирішення цієї проблеми. Раніше ми використовували порожній div зі стилем «clear: both» в самому низу контейнера. Потім, ми замінили його на тег hr, що не на багато краще.

І нарешті Nicolas Gallagher запропонував новий шлях очищення float`ов без необхідності чіпати розмітку зовсім. Після тривалих дискусій і тестів, ми отримали мінімально необхідний, для його роботи, набір стилів, ось його остання версія:

Насправді я збрехав, вона не остання, вона найкоротша. Але якщо вам потрібна підтримка IE 6/7, то вам потрібно додати ще ось це:

Для роботи необхідно додати клас .clearfix в свій проект, а потім застосовувати його до елементів розмітки. Це найпростіший і чистий спосіб для роботи з float`амі.

Як перемогти відступи між елементами з inline-block?

Продовжимо з розміщенням елементів в рядок, в цей раз не за допомогою float, а за допомогою inline-blocks. display: inline-block довгий час був недооцінений, і все ж ми розібралися, як він працює і чому це круто. Сьогодні, все більше і більше front-end розробників вважають за краще використовувати inline-block натомість float`ов, коли у них є така можливість.

Головний плюс inline-block в тому, що нам не доводиться відчищати float`и і ми не стикаємося з іншими проблемами які можуть виникнути через елементи позиційований за допомогою float`ов. Просто встановивши властивість елемента display в значення inline-block отримаємо гібрид сатиричного елемента і блоку. Вони можуть мати розмір, відступи, але їх ширина, по-замовчуванню, залежить від контенту, а не займає всю ширину родітелького елемента. Таким чином вони розміщуються горизонтально, а не вертикально.

Ви можете запитати: «У чому ж тоді проблема?». А проблема в тому, що вони на половину рядкові, а значить мають відступ один від одного розміром рівним пробілу. Зі стандартним шрифтом розміром 16px, він становить 4px. У більшості випадків розмір відступу можна розрахувати, як 25% від розміру шрифту. Так чи інакше, це може перешкодити нормальному розташуванню елементів. Наприклад, візьмемо контейнер розміром в 600px з трьома елементами всередині, розмір яких 200px і задано властивістю display: inline-block. Якщо не прибрати відступ, то нам не вдасться розмістити їх в одну лінію (200 * 3 + 4 * 2 = 608).

Є кілька шляхів, як прибрати непотрібний нам пробіл, кожен зі своїми плюсами і мінусами. Якщо чесно, то поки немає ідеального рішення. Давайте поглянемо на все по черзі!

Рівень розмітки: видалення пробілів

Для всіх наших тестів скористаємося такою розміткою.

Як я вже говорив раніше, дочірні елементи не стануть в одну лінію, тому що є додатковий символ пробілу між кожним з них (в нашому випадку переклад рядка і 4 пробілу). Перший спосіб вирішити проблему - повністю видалити пробіли.

Це дійсно працює, але робить не зручним читання нашого коду. Хоча, ми можемо, трохи реорганізувати наші елементи, що б зберегти читаність:

І якщо бути вже зовсім крутим, можна зробити і так:

Так - це працює! Звичайно я не рекомендую такий підхід, тому що він не інтуїтивний і робить код потворним. Давайте, краще, спробуємо, що небудь ще.

Так, так набагато краще! Код читаємо і працює. Так, спосіб виглядає не звично на перший погляд, але не так і складно до нього звикнути. Я і сам використовую такий спосіб, коли мені треба видалити пробіли між елементами з inline-block.

Звичайно, хтось скаже, що це не ідеальне рішення, так як воно працює на стороні розмітки, а проблема повинна бути вирішена на рівні css. Дійсно. Більшість з нас насправді використовують css рішення.

Рівень css: відстань між символами

Властивість letter-spacing використовується для завдання відступів між символами. Ідея полягає в тому, що б встановити відступ таким, що б він невіліровал відступ між нашими елементами, потім, нам доведеться скинути letter-spacing для дочірніх елементів, що б текст в них виглядають нормально.

Рівень css: негативний margin

Ще один підхід до вирішення завдання, дуже схожий на попередній, але з використання негативного відступу. Головний його недолік він не працює в IE 6/7. Плюс нам необхідно прибрати відступ з першого елемента, що б вони рівно встали всередині нашого контейнера.

Якщо вам не потрібна підтримка IE 6/7, я вважаю що це досить непогане рішення.

Рівень css: font-size

Ну і на останок, ви можете встановити розмір шрифту батьківського блоку в 0, що б зробити пробіл рівним 0px, а потім відновити розмір шрифту для дочірніх елементів.

У цього рішення є кілька своїх проблем і обмежень:

  • Ви не зможете відновити шрифт для дочірніх елементів використовуючи em як розмір шрифту
  • Пропуски не видаляються на пристроях з Android до Jellybean
  • Текст з використання @ font-face може втратити згладжування в Safari 5
  • Деякі браузери ігнорують font-size: 0. наприклад Китайська версія Chrome, в такому випадку font-size скидається до 12px

Розуміння абсолютного позиціонування.

Позиціонування елементів - каверзне процес і завжди ним був. Позиціонування, початківцям, дається з великими труднощами. Вони часто (не) використовують властивість position. Це властивість визначає як елемент може переміщатися за допомогою зсувів (top, right, bottom and left). І набуває таких значень:

  • static - по-замовчуванню, зміщення не діють
  • relative - зміщення рухають візуальний шар, але не сам елемент
  • absolute - зміщення рухають елемент всередині контексту (Перший не static елемент)
  • fixed - зміщення позиціонують елемент всередині viewport`a і не важливо де він розташований в документі

Проблеми з'являються при використанні position: absolute. І напевно ви з ними вже стикалися: ви визначили елемент з абсолютним позиціонування, тому що хочете, що б він був у верхньому правому куті свого батька (наприклад кнопка закрити у модального вікна).

... а він виявляється у верхньому правому кутку документа. У вас промелькает думка «Якого біса?». Насправді, це нормальна поведінка браузера. Ключове слово тут контекст.

Код вище просто говорить: «Я хочу що б мій елемент б позиційований в верхньому правому куті контексту». Так що ж таке контекст? Це перший елемент із властивістю position не рівним static. Це може бути безпосередньо батьківський елемент, або батько батька, або батько батька батька. І так до першого елемента з position! = Static.

Ця концепція часто виявляється складною для розуміння новачками, але коли ви її зрозуміли вона відкриває великі можливості по роботі з елементами позиційований абсолютно.

Невелика демка ілюструє вищесказане. Два батька, в кожному по одному дочірньому елементу позиційований абсолютно зі зміщення top: 0 і right: 0. Зліва правильний батько з position: relative, праворуч неправильний з position: static.

Кінець першої частини.

Схожі статті