Урок 12. Старый vs Новый: классы-модификаторы против вариантов

📁 Раздел: Состояния и темы ⏱️ Время изучения: ~50 мин 🎯 Сложность: Средняя

⚡ Кратко

Раньше состояния означали классы-модификаторы и JavaScript, который их навешивал. Теперь состояние живёт в DOM (псевдокласс или атрибут), а стили описываются вариантами.

Подсветка выбранного элемента

❌ Класс-модификатор и обработчик

document.querySelectorAll('.plan').forEach((el) => {
  el.addEventListener('click', () => {
    document.querySelectorAll('.plan').forEach(p => p.classList.remove('plan--active'))
    el.classList.add('plan--active')
  })
})
.plan--active { border-color: #6366f1; background: #eef2ff; }

✅ Состояние хранит сам input

<label class="rounded-xl border p-4 has-checked:border-indigo-500 has-checked:bg-indigo-50">
  <input type="radio" name="plan" class="sr-only">
  Тариф
</label>

Ноль JavaScript, доступность из коробки: работает клавиатура, читается скринридером, состояние передаётся в форму при отправке.

Реакция на наведение родителя

❌ Отдельное CSS-правило

.card:hover .card__icon { color: #0ea5e9; }

✅ group-hover

<div class="group">
  <span class="group-hover:text-sky-500">…</span>
</div>

Что появилось в v4

ВариантЧто даёт
has-*стилизация родителя по содержимому
not-*отрицание условия
in-*состояние любого предка, без класса group
*: и **:оформление детей и потомков
nth-*выбор по номеру без произвольных селекторов
starting:анимация появления через @starting-style
Общая линия развития понятна: всё больше интерактивности описывается декларативно и остаётся в CSS, а JavaScript занимается данными, а не переключением классов.