CSS GuideLines, частина 3. Іменування класів

       
 
Угоди по іменуванню CSS дозволяють писати строгий, чистий і красивий код. При дотриманні правил іменування ви завжди будете знати:
 
     
  • Для чого використовується клас;
  •  
  • Де клас може бути використаний;
  •  
  • З якими іншими класами пов'язаний цей клас.
  •  

Правила іменування, яким я слідую, вельми прості: я використовую дефіс як роздільник, а в складних місцях використовую БЕМ-подібне іменування.
 
Слід зазначити, що самі по собі правила іменування не дадуть особливої ​​вигоди при написанні CSS; але зате вони вельми корисні при перегляді розмітки.
 
 

Розділення дефісом

Всі слова в назвах класів повинні бути розділені дефісом:
 
 
.page-head {}

.sub-content {}

CamelCase і знак підкреслення не використовуються для класів, наступний приклад неправілен:
 
 
.pageHead {}

.sub_content {}

 
 

БЕМ-подібне іменування

Для більш великих взаємопов'язаних частин інтерфейсу я використовую БЕМ-подібне іменування класів.
 
БЕМ, тобто Блок, Елемент, Модифікатор , це методологія, створена розробниками Яндекса. Незважаючи на те, що БЕМ — це досить крупна методологія, в даний момент ми зацікавлені тільки в її способі іменування елементів. Причому, моя угода з іменування трохи відрізняється від оригінального БЕМ'a: принципи одні й ті ж, але синтаксис різний.
 
БЕМ розділяє компоненти верстки на три групи:
 
     
  • Блок: головний кореневої елемент.
  •  
  • Елемент: частина блоку.
  •  
  • Модифікатор: варіант або модифікація блоку.
  •  
Проведемо аналогію:
 
 
.person {}
.person__head {}
.person--tall {}

На початку класу завжди ставиться назва блоку, для позначення елементу ми відокремлюємо назва блоку від назви елемента двома підкресленнями (__), а для позначення модифікатора використовуємо два дефіса (-).
 
У прикладі вище ми можемо бачити, що
.person {}
— це блок; у нього немає предків.
.person__head {}
— це елемент, частина блоку; нарешті,
.person--tall
— це модифікатор, різновид блоку
.person {}
.
 
 
Використання блоків
Блок повинен бути логічною, самостійною одиницею. Продовжуючи наш приклад з класом
.person {}
: ми не можемо створити клас
.room__person
, бо
.room {}
— це самостійна одиниця. У такому випадку варто розділяти блоки:
 
 
.room {}

    .room__door {}

.room--kitchen {}


.person {}

    .person__head {}

Якщо нам буде потрібно позначити людини всередині кімнати, було б правильніше використовувати такий селектор —
.room .person
, який дозволяє не городити кашу з купи різних незрозумілих елементів і блоків.
 
Більш реалістичний приклад правильного використання блоків може виглядати наступним чином:
 
 
.page {}


.content {}


.sub-content {}


.footer {}

    .footer__copyright {}

Кожна частина коду представляє свій власний блок. Неправильний приклад використання:
 
 
.page {}

    .page__content {}

    .page__sub-content {}

    .page__footer {}

        .page__copyright {}

Важливо вміти розрізняти, де варто застосовувати БЕМ, а де ні. Як правило, я використовую блоки для опису автономних частин інтерфейсу користувача.
 
 
Безліч шарів
Якби ми додали до нашого блоку
.person {}
ще один елемент, скажімо,
.person__eye
, то нам не потрібно було б при іменуванні елемента робити крок назад, додаючи назви попередніх елементів, аж до кореневого елемента. Тобто, правильно буде писати
.person__eye
, а не
.person__head__eye
.
 
 
Додаємо модифікації елементів
Вам може знадобитися додавати варіації елементів, це може бути зроблено декількома способами, в залежності від того, як і чому ці елементи повинні бути змінені. Знову ж таки, якщо людина має блакитні очі, то в CSS це може бути описано так:
 
 
.person__eye--blue {}

Однак, в реальних проектах все буває дещо складніше. Прощу вибачення за таку аналогію, але давайте собі уявимо людини з красивим обличчям. Сам по собі він не особливо гарний, тому найкращим рішенням буде додати модифікатор до елементу
.person__face {}
:
 
 
.person__face--handsome {}

Але що робити, якщо ми хочемо описати особа красивого людини? Тобто людина гарний сам по собі, на відміну від попереднього прикладу, і нам потрібно описати його обличчя? Це робиться таким чином:
 
 
.person--handsome .person__face {}

Це один з небагатьох випадків, коли ми можемо міняти елемент залежно від модифікації блоку. При використанні Sass вийшов би такий код:
 
 
.person {}

    .person__face {

        .person--handsome & {}

    }

.person--handsome {}

Зауважте, що ми не додаємо новий елемент
.person__face
всередину елемента
.person--handsome
; замість цього ми використовуємо батьківський селектор Sass всередині вже існуючого селектора
.person__face
. Це значить, що всі правила, пов'язані з
.person__face
знаходитимуться в одному місці, і нам не доведеться розкидати їх по всьому файлу. Це хороша практика при роботі з вкладеним кодом: зберігайте все потрібні стилі всередині одного контексту (в нашому випадку, всередині
.person__face
).
 
 

Іменування в розмітці

Як раніше було відмічено, угоду з іменування класів найбільш корисно при роботі з розміткою. Погляньте на наступний шматок розмітки, не слід нашій угоді:
 
 
<div class="box  profile  pro-user">

    <img class="avatar  image" />

    <p class="bio">...</p>

</div>

Як класи
.box
і
.profile
пов'язані один з одним? Як класи
.profile
і
.avatar
пов'язані один з одним? Чи пов'язані вони взагалі? Чи залежить клас
.bio
від класу
.pro-user
? Чи можна використовувати клас
.avatar
поза цією розмітки?
 
При перегляді такої розмітки дуже складно відповісти на всі ці питання. Використання угоди про іменування міняє справу:
 
 
<div class="box  profile  profile--is-pro-user">

    <img class="avatar  profile__image" />

    <p class="profile__bio">...</p>

</div>

Тепер нам відразу видно, які класи пов'язані один з одним і як, а які ні; ми знаємо, які класи ми не можемо використовувати поза цією розмітки; нарешті, ми знаємо, які класи можуть бути використані в будь-якому іншому місці.
 
 

JavaScript-хуки

 
Як правило, нерозумно прив'язувати JS- і CSS-код до одного і того ж класу в розмітці, бо видаливши або змінивши один клас з метою, наприклад, зміни поведінки скрипта, ви неодмінно торкнеться CSS, і навпаки. Набагато чистіше, прозоріше і в цілому краще прив'язувати JS до окремих класів.
 
Я стикався з випадками, коли видалення якихось класів з метою переробки стилів, ламало роботу всіх скриптів на сторінці, а все тому що розробник не подумав і прив'язав стилі з скриптами до одного і того ж класу.
 
Як правило, розробники використовують окремий клас для js, що починається з префікса «js-», наприклад:
 
 
<input type="submit" class="btn  js-btn" value="Follow" />

Така розмітка дозволяє використовувати стилі
.btn
в будь-якому іншому місці, при цьому не зачіпаючи поведінки
.js-btn
.
 
 
data- * атрибути
Також досить часто розробниками використовуються data- * атрибути в якості js-хуков, але це неправильно. data- * атрибути, згідно специфікації, призначені для зберігання даних, недоступних на сторінці. data- * атрибути створені для зберігання даних, а не для для прив'язки до js.
 
 

У продовження теми…

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

Матеріали для додаткового вивчення

  
Попередня частина: CSS GuideLines, частина 2. Коментування коду
  
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.