Ось твій урок. Вмикай уяву — ми в лекційній залі Гарварду, я ходжу сценою туди-сюди, жестикулюю і готовий розкласти все по поличках. Поїхали!
🏛 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. 🧩 Підсумок
Отже, що ми маємо в сухому залишку?
- BEM — це Блок (герой), Елемент (його зброя), Модифікатор (його настрій).
- Синтаксис:
block__element--modifier. - Ми робимо це, щоб уникнути конфліктів імен і зробити код багаторазовим.
Тепер ти вмієш: Писати CSS, який можна масштабувати від односторінкового сайту до порталу розміром з Amazon.
🔍 Тизер наступного уроку:
Але писати block__element--modifier щоразу — це довго і втомлює пальці, правда?
На наступному уроці ми познайомимося з SASS/SCSS. Ми дізнаємось, як вкладеність (nesting) дозволяє генерувати BEM-імена автоматично. Це буде магія! ✨
А поки що — це був CS50. Побачимось!