Модуль 32

BEM та інші методології

Ось твій урок. Вмикай уяву — ми в лекційній залі Гарварду, я ходжу сценою туди-сюди, жестикулюю і готовий розкласти все по поличках. Поїхали!


🏛 CS50: Архітектура CSS. BEM та порядок у хаосі

Привіт, світе! 👋

Сьогодні ми не просто пишемо код. Сьогодні ми вчимося бути архітекторами.

1. 🔥 Вступ: Чому ваш CSS перетворюється на пекло?

Уявіть ситуацію. Ви пишете стилі для свого першого сайту. Все йде чудово. Ви створюєте клас .button і робите кнопку красивою, синьою.

Через тиждень вас просять додати "Купити" кнопку в кошик. Вона має бути зеленою. Ви пишете .buy-button. Ще через тиждень — червону кнопку "Видалити". А потім ви бачите, що ваша синя кнопка в футері чомусь стала зеленою, бо десь стилі перетнулися.

Знайомо? Це називається CSS Specificity Wars (Війни специфічності) або просто "спагеті-код".

Риторичне питання: Як знайти потрібну людину на стадіоні "Вемблі", якщо ви крикнете просто "Гей, Іване!"? Обернеться тисяча людей. У CSS так само: якщо ви називаєте клас просто .title або .item, браузер плутається: який саме це заголовок? Заголовок статті? Чи заголовок у сайдбарі?

Навіщо нам методології? Щоб ми могли взяти шматок коду (наприклад, картку товару), перенести її на зовсім іншу сторінку, і вона не розвалилася і не зламала нічого навколо.

Сьогодні ми вивчимо BEM (Block, Element, Modifier). Це як система поштових індексів для вашого коду.


2. 🧠 Теоретична база: BEM "під капотом"

BEM — це угода про іменування. Це не бібліотека, яку треба качати. Це просто домовленість у вашій голові та команді.

Уявіть собі звичайний LEGO.

🔹 1. Block (Блок)

Це самодостатня деталь. Цегла. Якщо ви вирвете цей блок з контексту сторінки і кинете в порожній простір — він все одно матиме сенс. * Приклади: Меню, Кнопка, Картка товару, Хедер. * Синтаксис: .block

🔹 2. Element (Елемент)

Це частина блоку, яка без нього не має сенсу. Чи потрібна вам "ручка від дверей" без дверей? Ні. Чи потрібен вам "пункт меню" без самого меню? Ні. * Приклади: Текст кнопки, Картинка в картці, Пункт меню. * Синтаксис: .block__element (два підкреслення!)

🔹 3. Modifier (Модифікатор)

Це стан або зовнішній вигляд. Це прикметник. Який? Червоний. Великий. Активний. Вимкнений. * Приклади: Кнопка (яка?) велика. Меню (яке?) приховане. * Синтаксис: .block--modifier (два дефіси!)

⚡️ Що треба запам'ятати залізним правилом: Ми НЕ вкладаємо класи один в одного в CSS (уникаємо каскаду), ми даємо їм унікальні довгі імена.

Замість цього (стара школа):

/* Це погано, бо залежить від вкладеності */
.article h2 { ... }

Ми робимо так (BEM):

/* Це добре, клас унікальний */
.article__title { ... }

3. 🧪 Приклади: Від простого до реального

Приклад 1: Звичайна кнопка

Припустімо, у нас є кнопка. ❓ Питання до тебе: Як би ти назвав клас для самої кнопки, і як — для її "неактивного" стану, використовуючи логіку BEM?

(Подумай секунду...)

Відповідь:

<!-- Блок -->
<button class="btn">Click me</button>

<!-- Блок із Модифікатором -->
<button class="btn btn--disabled">Do not click</button>

Зауваж: ми пишемо ДВА класи. btn дає форму, btn--disabled міняє колір/курсор.


Приклад 2: Картка профілю (Real world)

У нас є картка користувача з фото та іменем.

HTML:

<div class="profile-card">
    <img src="avatar.jpg" class="profile-card__avatar" alt="Avatar">
    <h3 class="profile-card__name">David Malan</h3>
    <button class="profile-card__btn profile-card__btn--active">Follow</button>
</div>

CSS:

.profile-card { /* Фон, рамка, тінь */ }
.profile-card__avatar { /* Кругла форма, розмір */ }
.profile-card__name { /* Шрифт, відступи */ }
.profile-card__btn { /* Базові стилі кнопки всередині картки */ }
.profile-card__btn--active { /* Колір для натиснутої кнопки */ }

Чому це круто? Тому що якщо я створю інший блок .news-card, у нього теж може бути __avatar, але стилі ніколи не перетнуться, бо імена класів різні: .news-card__avatar.


4. 🛠 Практична частина

Час бруднити руки кодом! Виконай ці завдання подумки або в редакторі.

Завдання 1: Рефакторинг Перепиши цей "старий" CSS у BEM формат:

/* Old style */
.menu { ... }
.menu ul { ... }
.menu li { ... }
.menu li a.active { ... }

Підказка: ul — це список, li — це елемент, a.active — це модифікований елемент.

Завдання 2: Створення структури Напиши HTML (тільки класи) для форми входу. Має бути: 1. Сама форма. 2. Поле вводу (input). 3. Поле вводу з помилкою (червона рамка). 4. Кнопка "Увійти".

Завдання 3: Виправ помилку (Grandchild problem) Новачки часто роблять таку помилку: .card__header__title Чому це неправильно в BEM? Як це виправити, якщо title лежить всередині header, який лежить всередині card?

Завдання 4: Міні-кейс Тобі треба зробити три види повідомлень (Alerts) на сайті: 1. Звичайне (сіре). 2. Успіх (зелене). 3. Помилка (червоне). Як ти організуєш це через BEM, щоб написати мінімум коду?


5. 💡 Мислення як у розробника

Ось де ми відділяємо новачків від профі.

❌ Типова помилка: "Копіювання структури DOM"

Новачок пише: .block__elem1__elem2__elem3 Він думає, що класи мають повторювати вкладеність HTML. Як думає профі: "Мені байдуже на вкладеність. Мені важливо, чиїм елементом це є". Правильно: .block__elem3. (Всі елементи плоскі).

❌ Типова помилка: "Імена по дизайну"

Новачок: .button--red Як думає профі: "А якщо завтра дизайнер скаже перефарбувати кнопку помилки в помаранчевий? Клас red стане помаранчевим? Це брєд". Правильно: .button--error або .button--danger. Називай за сенсом, а не за виглядом.

🚀 Порада з практики:

BEM дозволяє вам спати спокійно. Ви знаєте, що змінивши CSS в одному файлі, ви не зламаєте верстку на іншій сторінці. Це називається інкапсуляція.


6. 🧩 Підсумок

Отже, що ми маємо в сухому залишку?

  1. BEM — це Блок (герой), Елемент (його зброя), Модифікатор (його настрій).
  2. Синтаксис: block__element--modifier.
  3. Ми робимо це, щоб уникнути конфліктів імен і зробити код багаторазовим.

Тепер ти вмієш: Писати CSS, який можна масштабувати від односторінкового сайту до порталу розміром з Amazon.

🔍 Тизер наступного уроку: Але писати block__element--modifier щоразу — це довго і втомлює пальці, правда? На наступному уроці ми познайомимося з SASS/SCSS. Ми дізнаємось, як вкладеність (nesting) дозволяє генерувати BEM-імена автоматично. Це буде магія! ✨

А поки що — це був CS50. Побачимось!