Модуль 1 · урок 9 з 14
BEM і SCSS
Лід дав вибір: BEM або SCSS-вкладеність. Насправді це не «або» — здоровий проєкт бере іменування з BEM і синтаксичні зручності зі SCSS, але не зловживає вкладеністю.
BEM за п'ять хвилин
.card /* Блок — самостійний компонент */
.card__title /* Елемент — частина блоку, окремо не існує */
.card__title--muted /* Модифікатор — варіант вигляду або стану */
.card--compact /* модифікатор може бути й у блока */
- Блок — те, що можна перенести в інше місце й воно працюватиме:
.card,.btn. - Елемент — частина, яка без блоку безглузда:
.card__footer. Подвійного вкладення не буває: не.card__body__title, а.card__title. - Модифікатор — не новий клас-двійник, а додатковий клас поруч:
class="btn btn--ghost".
Головна цінність BEM не в красі, а в тому, що вага всіх селекторів однакова — (0,1,0).
Каскадних сюрпризів просто немає, і !important нема звідки взятись.
SCSS: що з нього справді потрібно
// 1. Вкладеність + амперсанд — щоб не повторювати ім'я блоку
.card {
padding: 16px;
&__title { font-weight: 700; }
&__footer { border-top: 1px solid var(--rule); }
&--compact { padding: 8px; }
&:hover { border-color: var(--accent); }
}
// 2. Змінні SCSS — для того, що не має мінятись у рантаймі
$radius: 10px;
$bp-desktop: 1024px;
// 3. Міксин — повторюваний шматок із параметрами
@mixin focus-ring($color: var(--accent)) {
outline: 2px solid $color;
outline-offset: 2px;
}
.btn:focus-visible { @include focus-ring(); }
// 4. Розбиття на файли
@use 'tokens';
@use 'mixins' as m;
Головна пастка SCSS
Вкладеність спокушає писати структуру дерева: .page { .content { .card { .title { … } } } }.
На виході отримаєш селектор .page .content .card .title вагою (0,4,0), який
перебивається тільки чимось іще важчим. Правило: вкладеність — лише для
&__елемент, &--модифікатор і псевдокласів. Максимальна
глибина реального селектора — два рівні.
Структура файлів, яку зрозуміє будь-хто
styles/
_tokens.scss // CSS-змінні: кольори, відступи, радіуси, шрифти
_reset.scss // нормалізація: box-sizing, margin: 0, шрифт форм
_mixins.scss // focus-ring, visually-hidden, медіазапити
_typography.scss // заголовки, текст, посилання
styles.scss // збирає все разом через @use
// стилі компонентів живуть біля самих компонентів,
// в Angular це файл component.scss поруч із component.ts