20. Продвинутые паттерны
Tailwind CSS: Продвинутые паттерны
Заголовок раздела «Tailwind CSS: Продвинутые паттерны»
В финальном уроке разберём продвинутые CSS-фичи через Tailwind: container queries, logical properties, has() селектор, scroll-driven animations и паттерны, которые выделят тебя как сильного frontend-разработчика.
Container Queries
Заголовок раздела «Container Queries»Container Queries — стили на основе размера родительского контейнера, а не вьюпорта. Идеальны для переиспользуемых компонентов.
В Tailwind v3 — через плагин:
npm install @tailwindcss/container-queriesВ Tailwind v4 — встроены из коробки.
<!-- Отмечаем контейнер --><div class="@container"> <!-- Стили зависят от ширины контейнера, не вьюпорта --> <div class="flex flex-col @md:flex-row @lg:grid @lg:grid-cols-3 gap-4"> <div>Карточка</div> <div>Карточка</div> <div>Карточка</div> </div></div>Брейкпоинты контейнера:
| Класс | Ширина контейнера |
|---|---|
@xs | 320px |
@sm | 384px |
@md | 448px |
@lg | 512px |
@xl | 576px |
@2xl | 672px |
Именованные контейнеры:
<div class="@container/sidebar"> <div class="@md/sidebar:flex">Зависит от ширины sidebar</div></div>Logical Properties
Заголовок раздела «Logical Properties»Logical properties заменяют физические (left/right) на логические (start/end), что важно для RTL-языков (арабский, иврит):
<!-- Физические (работают только для LTR) --><div class="ml-4 mr-8 pl-6 pr-2 text-left border-l-4">
<!-- Логические (работают для LTR и RTL) --><div class="ms-4 me-8 ps-6 pe-2 text-start border-s-4">Маппинг:
| Физический | Логический | LTR | RTL |
|---|---|---|---|
ml-4 | ms-4 | margin-left | margin-right |
mr-4 | me-4 | margin-right | margin-left |
pl-4 | ps-4 | padding-left | padding-right |
pr-4 | pe-4 | padding-right | padding-left |
text-left | text-start | left | right |
border-l | border-s | border-left | border-right |
rounded-l | rounded-s | radius-left | radius-right |
left-0 | start-0 | left: 0 | right: 0 |
:has() селектор
Заголовок раздела «:has() селектор»:has() — «родительский селектор», проверяет наличие дочерних элементов:
<!-- Стилизуем форму, когда внутри есть невалидный инпут --><div class="[&:has(input:invalid)]:border-red-500 border-2 rounded-xl p-4"> <input type="email" required></div>
<!-- Карточка с кнопкой — показываем кнопку при hover на всю карточку --><div class="group [&:has(button:focus)]:ring-2 [&:has(button:focus)]:ring-blue-500"> <p>Контент</p> <button>Действие</button></div>Scroll Snap
Заголовок раздела «Scroll Snap»<!-- Горизонтальная прокрутка с привязкой --><div class="flex overflow-x-auto snap-x snap-mandatory gap-4 p-4"> <div class="snap-center shrink-0 w-80 h-48 bg-blue-500 rounded-2xl">Слайд 1</div> <div class="snap-center shrink-0 w-80 h-48 bg-purple-500 rounded-2xl">Слайд 2</div> <div class="snap-center shrink-0 w-80 h-48 bg-pink-500 rounded-2xl">Слайд 3</div></div>
<!-- Типы привязки --><div class="snap-start">Привязка к началу</div><div class="snap-center">Привязка к центру</div><div class="snap-end">Привязка к концу</div>Aspect Ratio
Заголовок раздела «Aspect Ratio»<div class="aspect-video">16:9 — видео</div><div class="aspect-square">1:1 — квадрат</div><div class="aspect-[4/3]">4:3 — фото</div><div class="aspect-[21/9]">21:9 — ультраширокий</div>Object Fit для изображений
Заголовок раздела «Object Fit для изображений»<!-- Заполнить контейнер, обрезая --><img class="w-full h-48 object-cover rounded-2xl" src="photo.jpg">
<!-- Вместить целиком --><img class="w-full h-48 object-contain" src="logo.png">
<!-- Фокус на центре --><img class="object-cover object-center" src="photo.jpg"><img class="object-cover object-top" src="portrait.jpg">Backdrop Blur (Glassmorphism)
Заголовок раздела «Backdrop Blur (Glassmorphism)»<!-- Стеклянный эффект --><div class="backdrop-blur-md bg-white/30 border border-white/20 rounded-2xl p-6"> Контент с размытым фоном</div>
<!-- Навигация с glass-эффектом --><nav class="fixed top-0 w-full backdrop-blur-lg bg-white/70 border-b border-gray-200/50 z-50"> Прозрачная навигация</nav>Isolation и Mix-Blend
Заголовок раздела «Isolation и Mix-Blend»<!-- Текст поверх изображения --><div class="relative"> <img src="bg.jpg" class="w-full h-64 object-cover"> <div class="absolute inset-0 bg-gradient-to-t from-black/80 to-transparent"> <h2 class="absolute bottom-4 left-4 text-white text-2xl font-bold">Заголовок</h2> </div></div>
<!-- Mix-blend-mode --><div class="mix-blend-multiply">Наложение</div><div class="mix-blend-screen">Экран</div><div class="mix-blend-overlay">Оверлей</div>Паттерн: Sticky Header + Scroll
Заголовок раздела «Паттерн: Sticky Header + Scroll»<header class="sticky top-0 z-50 backdrop-blur-lg bg-white/80 border-b border-gray-200/50 transition-all duration-300"> <nav class="max-w-5xl mx-auto px-6 py-3 flex items-center justify-between"> <span class="font-bold">Logo</span> <div class="flex gap-6"> <a href="#">Ссылка</a> </div> </nav></header>Паттерн: Truncate и Line Clamp
Заголовок раздела «Паттерн: Truncate и Line Clamp»<!-- Однострочный текст с ... --><p class="truncate">Очень длинный текст который обрезается...</p>
<!-- Многострочный текст с ... (2 строки) --><p class="line-clamp-2">Длинный текст обрезается через 2 строки и показывается многоточие...</p><p class="line-clamp-3">3 строки</p>