Введення в обєктно-орієнтований CSS (OOCSS)

13

Від автора: Ви коли-небудь чули вислів (Білла Гейтса, 1996р., прим. перекладача) «контент – це король»? Будучи веб-розробником і, отже, займаючись справою, часто пов’язаних із створенням вмісту, напевно, чули. Це – занадто частоупотребимое, але вірне твердження щодо того, що залучає на сайт відвідувачів.

З точки зору веб-розробника, тим не менш, деякі стверджують, що король – це швидкість. Я все більше починаю схилятися до цієї позиції. В останні роки багато досвідчені фахівці з програмами користувальницького інтерфейсу пропонували поради про те, як можна поліпшити взаємодію з користувачем, виконуючи деякі практичні прийоми.

На жаль, схоже, що CSS в цій області частково ігнорується, тоді як безліч розробників (на достатніх підставах) більшою мірою зосереджуються на ефективності JavaScript’а й інших областях.

В даному пості я займуся цією часто ігнорованої сферою, представивши вам ідею об’єктно-орієнтованого CSS і того, як він сприяє поліпшенню як функціональністю, так і зручності підтримки ваших веб-сторінок.

Введення в обєктно-орієнтований CSS (OOCSS)

Принципи OOCSS

Як у випадку будь-якого об’єктно-орієнтованого методу кодування, метою OOCSS є сприяння повторному використанню коду і, в кінцевому рахунку, більш швидким і ефективним таблиць стилів, які простіше додавати і підтримувати.

Відокремлення від структури оболонки

Майже у кожного елементу нової веб-сторінки є різні візуальні особливості (тобто «оболонки»), що повторюються в різних контекстах. Обміркуйте фірмове оформлення сайту — кольору, використання градієнтів або видимих меж. З іншого боку, точно так само повторюються інші зазвичай невидимі характеристики (тобто «структури»).

Коли ці різні характеристики виділяються в модулі на основі класів, вони стають багаторазового користування і можуть з тим же результатом застосовуватися до будь-якого елементу. Давайте порівняємо трохи коду «до» і «після», щоб можна було побачити те, про що я кажу.

До застосування принципів OOCSS у вас може бути такий код CSS:

#button {
width: 200px;
height: 50px;
padding: 10px;
border: 1px solid #ccc;
background: linear-gradient(#ccc, #222);
box-shadow: rgba(0, 0, 0, .5) 2px 2px 5px;
}
#box {
width: 400px;
overflow: hidden;
border: 1px solid #ccc;
background: linear-gradient(#ccc, #222);
box-shadow: rgba(0, 0, 0, .5) 2px 2px 5px;
}
#widget {
width: 500px;
min-height: 200px;
overflow: auto;
border: 1px solid #ccc;
background: linear-gradient(#ccc, #222);
box-shadow: rgba(0, 0, 0, .5) 2px 2px 5px;
}

У трьох вищенаведених елементів унікальні стилі, а застосовуються вони для призначення стилів за допомогою одноразово використовується селектор ID. Але у них також є деяка кількість загальних стилів. Загальні стилі могли б послужити для цілей брендингу або узгодженості дизайну.

За допомогою невеликого планування і передбачливості можна виділити загальні стилі, щоб CSS виявився таким:

.button {
width: 200px;
height: 50px;
}
.box {
width: 400px;
overflow: hidden;
}
.widget {
width: 500px;
min-height: 200px;
overflow: auto;
}
.skin {
border: 1px solid #ccc;
background: linear-gradient(#ccc, #222);
box-shadow: rgba(0, 0, 0, .5) 2px 2px 5px;
}

Тепер всі елементи використовують класи, спільні стилі скомбіновані в повторно використовується «оболонку» і нічого не потрібно повторювати без особливої потреби. Нам лише потрібно застосувати клас «оболонки» до всіх елементів і результат буде таким, як у першому прикладі, за винятком того, що коду стало менше, і з’явилася можливість його повторного використання в подальшому.

Відділення контейнерів від вмісту

Другий принцип, описаний на сторінці wiki GitHub про OOCSS – це відділення контейнерів від їх вмісту. Щоб показати, чому це важливо, візьмемо наступний CSS:

#sidebar h3 {
font-family: Arial, Helvetica, sans-serif;
font-size: .8em;
line-height: 1;
color: #777;
text-shadow: rgba(0, 0, 0, .3) 3px 3px 6px;
}

Ці стилі застосовуватися до будь-яких заголовків третього рівня, що є нащадками елемента #sidebar. Але що, якщо нам потрібно застосувати в точності ті ж стилі до заголовків третього рівня нижнього колонтитула, за винятком іншого розміру шрифту і видозміненій тіні тексту?

Тоді нам знадобиться зробити щось на зразок цього:

#sidebar h3, #footer h3 {
font-family: Arial, Helvetica, sans-serif;
font-size: 2em;
line-height: 1;
color: #777;
text-shadow: rgba(0, 0, 0, .3) 3px 3px 6px;
}
#footer h3 {
font-size: 1.5 em;
text-shadow: rgba(0, 0, 0, .3) 2px 2px 4px;
}

Чи могло б вийти ще гірше:

#sidebar h3 {
font-family: Arial, Helvetica, sans-serif;
font-size: 2em;
line-height: 1;
color: #777;
text-shadow: rgba(0, 0, 0, .3) 3px 3px 6px;
}
/* other styles here…. */
#footer h3 {
font-family: Arial, Helvetica, sans-serif;
font-size: 1.5 em;
line-height: 1;
color: #777;
text-shadow: rgba(0, 0, 0, .3) 2px 2px 4px;
}

Зараз ми без необхідності дублюємо стилі, і, можливо, не розуміємо цього (або нас це просто не хвилює). OOCSS заохочує нас краще продумати те, що є спільного між різними елементами, а потім відокремити ці загальні риси в модулі або об’єкти, які можна повторно використовувати де завгодно.

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

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

Реально існуючий приклад

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

У мене було щось подібне, коли я став призначати стилі заголовку:

.header-inside {
width: 980px;
height: 260px;
padding: 20px;
margin: 0 auto;
position: relative;
overflow: hidden;
}

Деякі з наведених тут стилів – виключно для елемента .header-inside. Але інші можуть сформувати модуль, який можна повторно застосовувати. Так що я можу виділити структурні стилі в їх власний клас з можливістю нового використання. Ось результат:

.globalwidth {
width: 980px;
margin: 0 auto;
position: relative;
padding-left: 20px;
padding-right: 20px;
overflow: hidden;
}
.header-inside {
padding-top: 20px;
padding-bottom: 20px;
height: 260px;
}

Стилі, що належать до класу .globalwidth, охоплюють наступне:

Фіксовану ширину

Центрування за допомогою margin: auto

Відносне позиціонування для створення позиціонує контексту дочірніх елементів

Лівий і правий відступ в 20px

Переповнення, встановлене на «hidden» для очищення потоку

Тепер ми можемо вільно застосовувати ці стилі до будь-яких елементів, які вимагають тих же характеристик, просто додаючи до потрібного елементу даний клас — і не написавши жодної додаткової рядка CSS.

Для свого сайту я повторно застосовував ці структурні стилі до основного елементу контенту і внутрішнього елементу нижнього колонтитула. В залежності від вимог дизайну ці стилі можна також застосовувати до горизонтального елемента керування, що може бути між заголовком і контентом, або до будь-якого іншого елементу з фіксованою шириною fixed-width, який потрібно розмістити на сторінці по центру.

Після додавання до цих елементів стилів «globalwidth» розмітка буде виглядати приблизно так:

1

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

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

Медиаобъект

Один з піонерів руху OOCSS – Ніколь Салліван (Nicole Sullivan). Вона створила повторно використовуваний модуль під назвою медиаобъект, який, як вона пояснює, здатний заощадити сотні рядків коду.

Введення в обєктно-орієнтований CSS (OOCSS)

Медиаобъект – відмінний приклад здібностей OOCSS, так як може містити медиаэлемент будь-якого розміру з контентом зі свого правого боку. Хоча багато стилів, застосовні до вмісту всередині нього — і навіть розмір самого елемента можуть змінюватися, у медиаобъекта є загальні основні стилі, допомагають уникнути непотрібних повторень.

Переваги OOCSS

Я вже згадував деякі переваги OOCSS. Тут я розповім про них більш детально.

Більш швидкі вебсайти

Переваги продуктивності OOCSS явно видно. Якщо у вашому CSS повторюється менше стилів, це призведе до меншого розміру файлів і, таким чином, до швидкої завантаження ресурсів.

Це вірно, що розмітка стане захаращеною і, таким чином, будуть створюватися великі файли HTML. Але в багатьох випадках втрати продуктивності розмітки будуть побиті перевагами продуктивності таблиць стилів.

Слід пам’ятати про іншу концепцію – про wiki OOCSS говорить як про «дармової» продуктивності. Це відноситься до факту, що кожен раз при повторному застосування чого-небудь у вашому CSS ви насправді створюєте нові елементи з призначеними стилями без рядків коду CSS. Для масивних проектів з великим трафіком ця «дарівщина» може виявитися критичним виграш в продуктивності.

Легко обслуговуються таблиці стилів

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

Роблячи доповнення до існуючого сайту, ви не станете додавати нові стилі внизу своєї таблиці стилів без урахування того, що було до них. Замість того ви станете заново застосовувати існуючі стилі і розширювати їх на підставі існуючих наборів правил.

При такій продуманості можливо створювати цілі сторінки, роблячи при цьому мало CSS-кодування. Основою для всіх нових сторінок можуть служити будь-які існуючі модулі CSS і кількість будь-якого нового CSS стане мінімальним. У деяких випадках ви навіть могли б створити нову сторінку з повністю призначеними стилями, не вдаючись до кодування жодного рядка CSS.

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

Моменти, що заслуговують уваги

OOCSS породив у співтоваристві серйозне обговорення, викликавши суперечки. Я спробую тут розсіяти пару непорозумінь.

Ви все ще можете застосовувати ID

Якщо ви вирішите працювати виключно за методикою OOCSS, то ваші стилі будуть в основному базуватися на класах CSS, і ви не зможете призначати стилі елементів із застосуванням селектора ID.

З-за цього багато хто помилково заявляють, що OOCSS заохочує повністю відмовитися від використання ID. Але це невірно.

Якщо більш точно, то правило уникнення ID звучить як: не застосовувати ID в селекторах. Таким чином, цілком прийнятно використовувати принципи OOCSS (і, так, уникати призначення стилів з допомогою селектора ID) під час застосування ID у своєму HTML для перехоплювачів JavaScript’а й ідентифікаторів фрагментів.

Звичайно, може виникнути ситуація, де у вас вже є ID, застосований до елементу, який, як ви знаєте, унікальний для сторінки. Так що можна заощадити кілька байтів, уникнувши додавання до цього елемента класу, а призначивши замість того йому стилі з допомогою селектора ID. Але навіть у цьому випадку набагато безпечніше покладатися на клас, щоб гарантувати, що в майбутньому ви не натрапите на проблему конфлікту.

Робота з невеликими проектами

Ви напевно можете висунути переконливі докази того, що для маленьких сайтів і додатків OOCSS буде надмірністю. Так що не приймайте цю статтю в якості пропаганди OOCSS для всіх випадків — це залежить від проекту.

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

Деякі рекомендації щодо реалізації

Набуття досвіду роботи з OOCSS може зайняти деякий час. Я все ще працюю над цим, і не заявляю, що у мене є всі відповіді на запитання і величезний досвід.

А ось деякі речі, які вам, можливо, знадобиться почати робити, щоб допомогти вам зрозуміти спосіб мислення OOCSS:

Уникайте селектора-нащадка (тобто не використовуйте .sidebar h3)

Уникайте ID в якості пасток-прехватчиков стилів

Уникайте прикріплення класів до елементів у своїй таблиці стилів (тобто не робіть div.header або h1.title)

За виключення деяких рідкісних випадків уникайте використання !important

Застосовуйте CSS Lint для перевірки свого CSS (і знайте, що у нього додаткових опцій і методів багато до нестями)

Застосовуйте сітки CSS

Очевидно, настануть часи, коли деякі з цих правил будуть порушені, але в загальному це хороші навички розробки і ведуть до більш маленьким і легко підтримується таблиць стилів.

Висновок

Багато хто побоюється ідеології OOCSS з-за того, що вона, як здається, йде врозріз з багатьма вивченими нами так званими «кращими практиками». Але як тільки стають зрозумілі довготривалі переваги використання OOCSS, я впевнений, багато розробники стануть її прихильниками.

Загалом, я вважаю, що у OOCSS є майбутнє у розробці CSS, і це концепція, яку варто почати впроваджувати в свої проекти всім розробникам — принаймні в якійсь мірі — для створення більш швидких, ефективних та легко підтримуваних веб-сторінок.