CSS, який ти пропустив — 8 речей, для яких більше не потрібен JavaScript
Розкритий ноутбук із редактором коду і чашкою кави на дерев'яному столі, м'яке денне світло
Є один надійний спосіб зрозуміти, коли людина вивчала CSS: спитати, як вона робить модальне вікно. Якщо відповідь починається зі слів «беру div з position: fixed, пишу обробник на click, ставлю клас .open...» — це CSS зразка 2015 року. Робочий, але з десятками рядків JavaScript там, де тепер вистачає одного атрибута.
За останні кілька років CSS тихо забрав у JavaScript із десяток задач. Тихо — бо жодна з них не потрапила в заголовки. Ось вісім, які варто знати.
Біля кожної фічі вказано її статус у Baseline — це спільний стандарт браузерів, який каже, чи можна фічу використовувати без страху. «Широко доступна» означає підтримку в усіх основних браузерах уже щонайменше 30 місяців — бери сміливо. «Нещодавно доступна» — усі підтримують, але старі версії ще зустрічаються.
1. :has() — стилізувати батька за дитиною
Двадцять років у CSS можна було йти лише вниз по дереву: батько → дитина. Стилізувати div, у якому лежить картинка, або форму, в якій є помилка — тільки JavaScript.
/* Картка з картинкою — інша сітка, ніж без неї */
.card:has(img) {
grid-template-columns: 120px 1fr;
}
/* Форма, в якій є невалідне поле, підсвічує кнопку */
form:has(:invalid) button[type="submit"] {
opacity: 0.5;
}
Це «батьківський селектор», якого просили з 2000-х. Він працює не лише вгору, а й «убік»: label:has(+ input:focus) — підсвітити мітку, поки фокус на сусідньому полі.
Baseline: широко доступна з грудня 2023.
2. Container queries — компонент дивиться на свій контейнер, а не на екран
Медіа-запити відповідають на одне питання: «якої ширини вікно?». Але картка товару в сайдбарі й та сама картка в основній колонці мають різну ширину при однаковому вікні. Раніше під це заводили окремі класи або перевіряли ширину через ResizeObserver.
.sidebar, .main {
container-type: inline-size;
}
/* Картка сама перебудовується, коли ЇЇ контейнер вужчий за 400px */
@container (max-width: 400px) {
.card {
flex-direction: column;
}
}
Компонент стає справді самодостатнім: поклади його куди завгодно — він сам підлаштується. Це логічне продовження того, що ми розбирали в уроці про responsive design.
Baseline: широко доступна з лютого 2023.
3. <dialog> — модальне вікно, яке вже все вміє
Той самий приклад із початку. Ось усе, що потрібно:
<button onclick="modal.showModal()">Відкрити</button>
<dialog id="modal">
<p>Точно видалити?</p>
<form method="dialog">
<button>Так</button>
<button>Ні</button>
</form>
</dialog>
Один виклик showModal() — і браузер сам: затемнює фон (стилізується через ::backdrop), блокує кліки поза вікном, закриває по Escape, повертає фокус туди, звідки прийшов, і робить вікно доступним для скрінрідерів. Кожен із цих пунктів раніше писали руками — і зазвичай щось забували.
Baseline: широко доступна з березня 2022. Так, уже давно.
4. popover — тултіпи й меню одним атрибутом
Не всі спливаючі елементи — модалки. Меню, підказки, тости не мають блокувати сторінку, але мають закриватися при кліку назовні і не зачиняти одне одного.
<button popovertarget="menu">Меню</button>
<div id="menu" popover>
<a href="/profile">Профіль</a>
<a href="/logout">Вийти</a>
</div>
Жодного рядка JavaScript. Клік поза меню закриває його, Escape теж, елемент автоматично рендериться поверх усього — без боротьби з z-index.
Baseline: нещодавно доступна з січня 2025.
5. Nesting — вкладені правила без Sass
Половина людей ставила Sass заради однієї речі — можливості писати стилі вкладено. Тепер це вбудовано:
.card {
padding: 16px;
& h2 {
margin: 0;
}
&:hover {
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}
@media (max-width: 600px) {
padding: 8px;
}
}
Медіа-запит усередині правила — окрема радість: стилі компонента лежать в одному місці, а не розкидані по файлу.
Baseline: доступна з кінця 2023, у 2026 вже широко.
6. View Transitions — анімація між станами сторінки
Плавне перетікання елементів при зміні контенту — те, заради чого раніше тягнули анімаційні бібліотеки на сотні кілобайт. Тепер:
// Одна обгортка — і браузер сам анімує різницю між "до" і "після"
document.startViewTransition(() => {
list.appendChild(newItem);
});
Це єдиний пункт у списку, де є рядок JavaScript — але лише один, і вся анімація описується в CSS через ::view-transition-old і ::view-transition-new. Раніше для того самого треба було вручну рахувати позиції елементів до й після.
Baseline: нещодавно доступна з жовтня 2025 для переходів у межах сторінки. Переходи між сторінками ще не всюди.
7. Scroll-driven animations — анімація, прив'язана до скролу
Елементи, що з'являються при прокрутці, прогрес-бар читання, паралакс — усе це були IntersectionObserver плюс обробник scroll, який ще й гальмував сторінку.
.reveal {
animation: fade-in linear both;
animation-timeline: view();
animation-range: entry 0% entry 40%;
}
@keyframes fade-in {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: none; }
}
animation-timeline: view() каже: «прогрес цієї анімації — це те, наскільки елемент увійшов у видиму область». Браузер робить це поза головним потоком, тож ніяких гальм.
Baseline: обмежена. Chrome, Edge і Safari підтримують, Firefox — довго відставав. Використовуй як прикрасу: без підтримки елемент просто буде видимий одразу.
8. Anchor positioning — прив'язати елемент до іншого
Тултіп має стояти над кнопкою. Якщо вгорі не влазить — під нею. Це класична задача, під яку існують цілі бібліотеки (Popper, Floating UI).
.tooltip {
position: absolute;
position-anchor: --btn;
top: anchor(bottom);
justify-self: anchor-center;
position-try-fallbacks: flip-block;
}
.button {
anchor-name: --btn;
}
position-try-fallbacks: flip-block — це те саме «не влазить знизу — покажи зверху», яке бібліотеки роблять через обчислення координат на кожен скрол.
Baseline: найсвіжіша у списку — базова підтримка стала Baseline лише на початку 2026, і в Safari вона ще не повна. Перевір на caniuse перед використанням у продакшені.
Що з цього випливає
Зверни увагу на дати: <dialog> — з 2022 року, container queries — з 2023. Це не «новинки», це речі, які багато хто просто пропустив, бо вчився за матеріалами, написаними раніше.
Спільна ідея всіх восьми одна: браузер тепер уміє те, що раніше писали руками — і вміє краще, бо враховує доступність, продуктивність і граничні випадки, про які вручну завжди щось забувається.
Практичне правило: перед тим як писати JavaScript для UI-поведінки, спитай себе, чи не зробить це CSS. У 2026 відповідь дедалі частіше «зробить».
Якщо базові речі — flexbox, grid, позиціонування — ще не сидять у пальцях, почни з блоку CSS у курсі: ці вісім фіч набагато простіше зрозуміти, коли розумієш, на чому вони стоять. А для швидкого пошуку властивостей є шпаргалки з Flexbox і Grid.