HTML & CSS

Вступ до CSS. Селектори та специфічність

Глибоке занурення у CSS: три способи підключення стилів, анатомія CSS-правила, типи селекторів (тегові, класи, ID, атрибутні), комбінатори, псевдокласи, псевдоелементи, каскад та специфічність.

Вступ до CSS. Селектори та специфічність

Навіщо потрібен CSS?

Відкрийте будь-який сучасний сайт — YouTube, Apple, Spotify — і поспробуйте уявити його без кольорів, шрифтів, відступів та анімацій. Що залишиться? Голий текст із посиланнями — щось схоже на веб-сторінки 1993 року. Саме CSS (Cascading Style Sheets — каскадні таблиці стилів) перетворює скелет HTML на повноцінний візуальний досвід.

У попередньому занятті ми вже бачили шматочки CSS-коду: color: red, text-decoration: line-through, background-color: #fef08a. Тепер прийшов час зрозуміти цю мову системно — від першого правила до складних механізмів каскаду.

🎨 Зовнішній вигляд

CSS керує кольорами, шрифтами, фонами, тінями — усім, як виглядає сторінка.

📐 Компонування

CSS визначає розташування елементів на екрані: сітки, колонки, центрування, відступи.

📱 Адаптивність

CSS дозволяє одному сайту виглядати ідеально на телефоні, планшеті та десктопі.

✨ Інтерактивність

CSS додає анімації, переходи, ефекти при наведенні — без жодного рядка JavaScript.

Анатомія CSS-правила

Перш ніж вивчати селектори, розберемо структуру самого CSS. Кожне правило (rule) складається з двох частин:

🔒localhost:3000

Розберемо кожну частину CSS-правила:

Loading diagram...
graph LR
    A["CSS-правило"] --> B["Селектор<br/>h1, .highlight, #id"]
    A --> C["Блок оголошень<br/>{ ... }"]
    C --> D["Оголошення 1<br/>color: #1e40af;"]
    C --> E["Оголошення 2<br/>font-size: 2rem;"]
    D --> F["Властивість<br/>color"]
    D --> G["Значення<br/>#1e40af"]
    style A fill:#3b82f6,color:#fff
    style B fill:#f59e0b,color:#fff
    style C fill:#64748b,color:#fff
    style D fill:#3b82f6,color:#fff
    style E fill:#3b82f6,color:#fff
    style F fill:#10b981,color:#fff
    style G fill:#8b5cf6,color:#fff
Селектор (Selector)
string
Вказує, до яких HTML-елементів застосовується правило. Це може бути тег (h1), клас (.highlight), ідентифікатор (#header) або складніша конструкція.
Блок оголошень (Declaration Block)
object
Фігурні дужки { } містять одне або кілька оголошень — пар «властивість: значення».
Властивість (Property)
string
Назва стильового параметра: color, font-size, margin, display тощо. CSS має понад 500 властивостей.
Значення (Value)
string
Конкретне значення властивості: red, 16px, center, #3b82f6.
Крапка з комою (;)
string
Роздільник між оголошеннями. Обов'язковий після кожного оголошення (крім останнього, але рекомендується завжди ставити).

CSS-коментарі

CSS підтримує лише один вид коментарів — блокові:

/* Це коментар. Браузер його ігнорує. */

h1 {
    color: blue; /* Колір заголовка */
    /* font-size: 3rem; — тимчасово вимкнено */
}

/*
    Багаторядковий коментар.
    Зручно для пояснення складних правил.
*/
CSS не підтримує однорядкові коментарі //, які є у JavaScript. Використання // у CSS — це помилка, яку браузер мовчки проігнорує, зламавши наступне правило.

Три способи підключення CSS до HTML

У попередній статті ми бачили ці три способи коротко. Тепер розберемо їх детально.

CSS-код виноситься в окремий файл .css, який підключається через тег <link> у <head>:

<!DOCTYPE html>
<html lang="uk">
    <head>
        <meta charset="UTF-8" />
        <title>Моя сторінка</title>
        <link rel="stylesheet" href="styles.css" />
    </head>
    <body>
        <h1>Привіт!</h1>
    </body>
</html>
styles.css
h1 {
    color: #1e40af;
    text-align: center;
}

Переваги:

  • ✅ Один CSS-файл для всіх сторінок сайту
  • ✅ Браузер кешує файл — наступні сторінки завантажуються швидше
  • ✅ Чітке розділення структури (HTML) і оформлення (CSS)
  • ✅ Легко підтримувати та змінювати стилі

Це стандарт індустрії. У реальних проєктах використовується саме цей спосіб.

На цьому курсі в прикладах ми часто використовуємо компонент ::html-preview, де CSS записаний разом із HTML. У реальних проєктах завжди виносьте CSS у зовнішній файл .css.

Типи селекторів

Селектори — це серце CSS. Вони визначають, які саме елементи будуть стилізовані. Почнемо з простих і рухатимемось до складних.

Універсальний селектор *

Селектор * вибирає абсолютно всі елементи на сторінці:

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}
Цей прийом називається CSS Reset — скидання стандартних стилів браузера. Більшість проєктів починаються з нього, щоб HTML-елементи виглядали однаково в Chrome, Firefox, Safari.

Селектор тегу (Type Selector)

Вибирає всі елементи за іменем тегу:

🔒localhost:3000

Особливість: селектор тегу має найнижчу специфічність. Він стилізує всі елементи цього типу — іноді це забагато.

Селектор класу . (Class Selector)

Вибирає елементи за значенням атрибута class. Це найпопулярніший тип селектора у реальних проєктах:

🔒localhost:3000
Правило хорошого тону: Називайте класи за призначенням, а не за зовнішнім виглядом. .error-message — добре. .red-text — погано (бо завтра помилки можуть стати оранжевими).

Селектор ідентифікатора # (ID Selector)

Вибирає єдиний елемент із зазначеним атрибутом id:

<header id="main-header">
    <h1>Мій сайт</h1>
</header>
#main-header {
    background-color: #1e293b;
    color: #f8fafc;
    padding: 1rem 2rem;
}
Уникайте #id у CSS! Селектор #id має аномально високу специфічність, яку дуже важко перевизначити. У сучасній верстці для стилізації використовують виключно класи (.class). Ідентифікатори id залишають для JavaScript (getElementById) та якірних посилань (<a href="#section">).

Селектор атрибутів (Attribute Selector)

Вибирає елементи за наявністю або значенням атрибутів:

🔒localhost:3000

Усі варіанти атрибутних селекторів:

СелекторЩо вибирає
[attr]Елементи, що мають атрибут attr
[attr="value"]Точне значення
[attr~="value"]Значення як окреме слово (розділене пробілами)
[attr^="value"]Значення починається з value
[attr$="value"]Значення закінчується на value
[attr*="value"]Значення містить value
/* Посилання на PDF-файли */
a[href$=".pdf"] {
    color: #dc2626;
}

/* Посилання на зовнішні ресурси */
a[href^="https://"] {
    color: #059669;
}

Групування селекторів

Якщо кілька селекторів мають однакові стилі, їх можна об'єднати через кому:

/* ❌ Дублювання стилів */
h1 {
    font-family: 'Georgia', serif;
    color: #1e293b;
}
h2 {
    font-family: 'Georgia', serif;
    color: #1e293b;
}
h3 {
    font-family: 'Georgia', serif;
    color: #1e293b;
}

/* ✅ Групування */
h1,
h2,
h3 {
    font-family: 'Georgia', serif;
    color: #1e293b;
}
Кожен селектор у групі пишеться з нового рядка — це конвенція для читабельності. Кома між селекторами означає «або» — стилі застосуються до кожного з перелічених селекторів.

Комбінатори (Combinators)

Комбінатори дозволяють вибирати елементи залежно від їхнього розташування в DOM-дереві.

Нащадок <space> (Descendant Combinator)

Пробіл між селекторами вибирає елемент, що знаходиться всередині іншого на будь-якому рівні вкладеності:

🔒localhost:3000

Дочірній > (Child Combinator)

Символ > вибирає лише безпосередніх нащадків (дітей першого рівня):

/* Тільки прямі li в ul, а не вкладені */
ul > li {
    list-style: square;
    color: #1e40af;
}

Сусідній + (Adjacent Sibling)

Символ + вибирає елемент, який стоїть безпосередньо після іншого на тому ж рівні:

🔒localhost:3000

Загальний сусід ~ (General Sibling)

Символ ~ вибирає всіх братів/сестер, що стоять після зазначеного елемента:

/* ВСІ абзаци після h2 (на тому ж рівні) */
h2 ~ p {
    color: #64748b;
}

Зведена таблиця комбінаторів

КомбінаторПрикладЩо вибирає
(пробіл)div pБудь-який <p> всередині <div> (на будь-якій глибині)
>div > pТільки прямий дочірній <p> в <div>
+h2 + pПерший <p> безпосередньо після <h2>
~h2 ~ pВсі <p>, що йдуть після <h2> (на тому ж рівні)

Псевдокласи (Pseudo-classes)

Псевдокласи вибирають елементи за їхнім станом або позицією у DOM — без додавання класів у HTML.

Стани взаємодії

🔒localhost:3000

Головні псевдокласи станів:

ПсевдокласКоли активний
:hoverКурсор миші над елементом
:activeЕлемент натиснутий (mouse down)
:focusЕлемент у фокусі (клік або Tab)
:focus-visibleФокус через клавіатуру (не через клік)
:visitedВідвідане посилання
:checkedУвімкнений checkbox або radio
:disabledВимкнений елемент форми

Структурні псевдокласи

Ці псевдокласи вибирають елементи за їхньою позицією серед братів/сестер:

🔒localhost:3000

Формула nth-child():

Формула An+B дає гнучкий контроль:

СелекторЩо вибирає
:nth-child(3)Тільки третій елемент
:nth-child(odd)Непарні: 1, 3, 5, 7...
:nth-child(even)Парні: 2, 4, 6, 8...
:nth-child(3n)Кожен третій: 3, 6, 9...
:nth-child(3n+1)1, 4, 7, 10...
:nth-child(-n+3)Перші три елементи
:nth-last-child(2)Другий з кінця

Псевдоклас :not() — виключення

Вибирає елементи, що не відповідають зазначеному селектору:

/* Всі посилання без класу .btn */
a:not(.btn) {
    color: #2563eb;
    text-decoration: underline;
}

/* Всі input, крім submit */
input:not([type="submit"]) {
    border: 1px solid #e2e8f0;
}

Псевдоелементи (Pseudo-elements)

Псевдоелементи створюють віртуальні елементи, яких немає в HTML, але які можна стилізувати. Записуються з подвійним двокрапком ::.

🔒localhost:3000

Основні псевдоелементи:

ПсевдоелементЩо робить
::beforeВставляє вміст перед елементом
::afterВставляє вміст після елемента
::first-lineСтилізує перший рядок тексту
::first-letterСтилізує першу літеру тексту
::placeholderСтилізує placeholder у <input>
::selectionСтилізує виділений користувачем текст
::before та ::afterобов'язково потребують властивість content. Без неї — псевдоелемент не з'явиться. Навіть якщо вміст порожній, потрібно вказати content: "".

Каскад (Cascade)

У назві CSS — Cascading Style Sheets — каховане ключове слово. Каскад — це алгоритм, за яким браузер визначає, яке правило «перемагає», коли кілька правил конфліктують.

Три стовпи каскаду

Loading diagram...
graph TD
    A["Який стиль застосувати?"] --> B["1. Джерело<br/>(Origin)"]
    A --> C["2. Специфічність<br/>(Specificity)"]
    A --> D["3. Порядок<br/>(Order)"]
    B --> B1["Браузерні стилі"]
    B --> B2["Авторські стилі"]
    B --> B3["!important"]
    C --> C1["Вага селектора<br/>(id, class, tag)"]
    D --> D1["Останнє оголошення перемагає"]
    style A fill:#3b82f6,color:#fff
    style B fill:#f59e0b,color:#fff
    style C fill:#10b981,color:#fff
    style D fill:#8b5cf6,color:#fff

1. Джерело стилів (Origin): Стилі браузера (user-agent) < стилі автора < !important.

2. Специфічність (Specificity): Якщо два правила з одного джерела — перемагає правило з вищою специфічністю (вагою селектора).

3. Порядок (Order): Якщо специфічність однакова — перемагає правило, записане останнім у коді.

Порядок оголошення

🔒localhost:3000

Обидва правила мають однакову специфічність (один клас). Тому перемагає правило, записане другим — текст буде зеленим.


Специфічність (Specificity)

Специфічність — це числова вага селектора. Браузер порівнює ваги, щоб визначити, яке правило застосувати.

Алгоритм підрахунку

Специфічність записується як чотири числа: (інлайн, ID, клас, тег)

Крок 1: Рахуємо інлайн-стилі

Якщо стиль заданий через атрибут style="" — він отримує вагу (1, 0, 0, 0). Це найвища специфічність (крім !important).

Крок 2: Рахуємо ID-селектори

Кожен #id у селекторі додає (0, 1, 0, 0).

Крок 3: Рахуємо класи, псевдокласи, атрибутні селектори

Кожен .class, :hover, [type="text"] додає (0, 0, 1, 0).

Крок 4: Рахуємо теги та псевдоелементи

Кожен div, p, ::before додає (0, 0, 0, 1).

Таблиця прикладів

СелекторСпецифічністьПояснення
p0,0,0,11 тег
.info0,0,1,01 клас
p.info0,0,1,11 клас + 1 тег
#header0,1,0,01 ID
#header .nav a0,1,1,11 ID + 1 клас + 1 тег
div#main p.text:hover0,1,2,21 ID + 2 (клас + псевдоклас) + 2 теги
style="color: red"1,0,0,0Інлайн — найвища

Специфічність у дії

🔒localhost:3000

Текст буде червоним, бо #container p (0,1,0,1) має найвищу специфічність серед усіх правил.

!important — ядерна зброя CSS

Оголошення з !important перевизначає будь-яку специфічність:

p {
    color: red !important; /* Перемагає навіть #id */
}

#container p {
    color: blue; /* Програє, незважаючи на ID */
}
Ніколи не використовуйте !important у повсякденному коді. Це як «пожежний вихід» — інструмент для крайніх випадків (наприклад, перевизначення стилів сторонньої бібліотеки). Кожне !important робить код важчим для підтримки, бо єдиний спосіб перевизначити !important — це інше !important з вищою специфічністю.

Спадкування (Inheritance)

Деякі CSS-властивості автоматично передаються від батька до дітей у DOM-дереві. Це називається спадкуванням.

🔒localhost:3000

Що успадковується:

  • Текстові: color, font-family, font-size, font-weight, line-height, text-align, letter-spacing
  • Списки: list-style-type, list-style-position
  • Курсор: cursor, visibility

Що НЕ успадковується:

  • Блокова модель: margin, padding, border, width, height
  • Фон: background-color, background-image
  • Позиціонування: position, top, left, z-index
  • Flexbox/Grid: display, flex, grid
Якщо потрібно примусово успадкувати значення, використовуйте ключове слово inherit:
.child {
    border: inherit; /* Бере значення border від батька */
}

Практичні завдання

Рівень 1 — Базовий

Рівень 2 — Логіка та комбінування

Рівень 3 — Створення з нуля


Підсумок

🎯 Селектори

CSS-селектори вибирають HTML-елементи для стилізації. Основні типи: тег (p), клас (.info), ID (#header), атрибут ([type="text"]).

🔗 Комбінатори

Комбінатори визначають зв'язок між селекторами: нащадок ( ), дочірній (>), сусідній (+), загальний сусід (~).

⚡ Псевдокласи

:hover, :focus, :nth-child(), :not() — вибирають елементи за станом або позицією без HTML-класів.

⚖️ Специфічність

Вага селектора визначає пріоритет: inline > #id > .class > tag. Уникайте !important — використовуйте точніші селектори.

Корисні посилання

  • 📖 MDN — CSS Selectors — повний довідник селекторів
  • 🎮 CSS Diner — інтерактивна гра для вивчення CSS-селекторів
  • ⚖️ Specificity Calculator — калькулятор специфічності
  • 📐 W3C CSS Specification — офіційна специфікація
  • 🎨 Can I Use — підтримка CSS-властивостей браузерами