CSS-анимации — готовые эффекты
Готовые одностраничные примеры: скопировали HTML в файл, открыли в браузере — эффект уже работает. Ищете «css fade in», «анимация появления блока», «loader spinner css», «shimmer skeleton», «кнопка hover transition», «css shake error», «keyframes пример» — ниже код с разбором каждой важной строки, как в примерах Turtle и готовых макетах HTML+CSS.
Под каждым блоком — зачем свойство, как браузер проигрывает кадры, типичные ошибки новичков и что поменять для эксперимента.
Школьникам — fade in для презентации, спиннер «загрузка» для проекта по информатике.
Студентам — лабораторная по вебу, курсовой лендинг, портфолио.
Самоучкам — первый живой интерфейс без JavaScript и без фреймворков.
Кто гуглит перед экзаменом — короткий рабочий код вместо десяти вкладок Stack Overflow.
Основы CSS-анимаций
Теория — в Анимации, переходы и трансформации. Каркас страницы и сетка — HTML + CSS — готовые макеты. Кнопки, карточки и модальные окна — UI-компоненты на CSS. Шпаргалка «что анимировать / чего избегать» — Практические рекомендации по CSS.
Вставьте любой пример из статьи в редактор — предпросмотр обновится через пару секунд. Так быстрее, чем каждый раз сохранять файл на диск.
Мини-симулятор показывает, как duration и timing-function меняют отклик кнопки на наведение и клик.
Как запустить пример за 30 секунд
- Скопируйте весь блок (от
<!DOCTYPE html>до</html>). - Вставьте в Блокнот / VS Code / Notepad++.
- Сохраните как
anim.html(расширение.html, не.txt). - Откройте двойным щелчком или перетащите в Chrome / Edge / Firefox.
- Не видите эффект — обновите страницу (
F5). Всё ещё пусто — проверьте, что скопировали@keyframesвыше или ниже класса, но внутри<style>.
| Где править | Что менять для эксперимента |
|---|---|
0.6s, 0.5s | Скорость — меньше число, быстрее движение |
translateY(24px) | Дальность сдвига |
ease, ease-out, linear | Характер ускорения |
infinite | Уберите — анимация один раз |
цвета #2563eb | Любой hex с htmlcolorcodes.com |
Базовые термины
| Термин | Простыми словами |
|---|---|
transition | «Если свойство вдруг изменилось — меняй его плавно за N секунд» |
@keyframes | Сценарий: «на 0% элемент такой, на 50% — такой, на 100% — такой» |
animation | Запуск сценария @keyframes по таймеру (даже без клика и hover) |
transform | Сдвиг, поворот, масштаб без пересчёта всей страницы — обычно плавнее |
opacity | Прозрачность 0 (невидим) … 1 (полностью видим) |
forwards | После конца анимации остаться в последнем кадре |
infinite | Повторять сценарий бесконечно (спиннер, пульс) |
animation-delay | Пауза перед стартом; у второго элемента — «волна» |
prefers-reduced-motion | Настройка ОС «уменьшить движение» — отключаем декор ради доступности |
Transition или @keyframes — что выбрать
| Ситуация | Инструмент | Пример из статьи |
|---|---|---|
| Навели мышь, нажали Tab, сменили класс | transition | Кнопка hover |
| Элемент сам «оживает» при загрузке | @keyframes + animation | Fade in |
| Бесконечная загрузка | @keyframes + infinite | Спиннер |
| Несколько элементов по очереди | один @keyframes, разные delay | Stagger-список |
Мысленная модель. transition — дверь с доводчиком: толкнули (сменили стиль) — плавно закрылась. @keyframes — мультфильм: браузер сам листает кадры по расписанию.
Как работать с примерами
- Сначала запустите код как есть — убедитесь, что работает.
- Меняйте одно свойство за раз (скорость, цвет,
translateY). - Сломали — верните исходник из статьи.
- Готовый эффект вставьте в макет страницы — замените содержимое
<body>или добавьте класс к карточке.
animation в одну строкуanimation: fadeIn 0.6s ease forwards; читается так:
fadeIn — имя сценария из @keyframes
0.6s — длительность одного прохода
ease — плавность (мягкий старт и финиш)
forwards — после конца остаться в последнем кадре
Обязательный каркас
Любой пример ниже можно собрать на этом фундаменте.
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>CSS-анимация</title>
<style>
*, *::before, *::after { box-sizing: border-box; }
body {
margin: 0;
min-height: 100dvh;
padding: 1.5rem;
font-family: system-ui, sans-serif;
line-height: 1.5;
background: #f8fafc;
color: #1e293b;
}
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}
</style>
</head>
<body>
<!-- сюда разметка и стили эффекта -->
</body>
</html>
Разбор по строкам.
| Фрагмент | Смысл |
|---|---|
<!DOCTYPE html> | Режим HTML5 — браузер рисует страницу предсказуемо |
<meta charset="UTF-8"> | Кириллица в <title> и тексте |
viewport | На телефоне страница не «уменьшенный десктоп» |
box-sizing: border-box | padding входит в ширину — сетка не ломается |
body { margin: 0 } | Убирает белую полоску у края окна |
min-height: 100dvh | Минимум на всю высоту экрана; dvh учитывает панель браузера на телефоне |
prefers-reduced-motion: reduce | Если в системе включено «уменьшить движение» — почти отключаем анимации |
0.01ms !important | Контент остаётся, движение почти незаметно — это правильнее, чем display: none |
Типичные ошибки.
- Сохраняют файл как
anim.txt— браузер покажет код текстом, а не страницу. - Кладут
@keyframesвне<style>— правило не сработает. - Пишут
animation: fadeInбез@keyframes fadeIn { … }— браузер не знает, что проигрывать.
Попробуйте сами. В Windows включите Параметры → Специальные возможности → Визуальные эффекты → Анимация в Windows (выкл.) и перезагрузите страницу — каркас должен уважать настройку.
Стартовые эффекты
Простые эффекты, которые чаще всего ищут в Google и Яндексе.
Плавное появление (fade in)
Задача. Карточка, баннер или текст плавно проявляются при открытии страницы.
Частые запросы: css fade in, анимация появления css, opacity animation, плавное появление блока.
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Fade in</title>
<style>
*, *::before, *::after { box-sizing: border-box; }
body {
margin: 0;
min-height: 100dvh;
display: grid;
place-items: center;
font-family: system-ui, sans-serif;
background: #eef2ff;
}
.card {
padding: 1.5rem 2rem;
background: #fff;
border-radius: 12px;
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.08);
animation: fadeIn 0.6s ease forwards;
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
</style>
</head>
<body>
<article class="card">
<h1 style="margin: 0 0 0.5rem; font-size: 1.25rem;">Привет!</h1>
<p style="margin: 0; color: #64748b;">Карточка плавно появилась.</p>
</article>
</body>
</html>
Разбор CSS — что за что отвечает.
| Свойство | Зачем здесь |
|---|---|
display: grid + place-items: center на body | Карточка по центру экрана без position: absolute |
animation: fadeIn 0.6s ease forwards | Запуск сценария fadeIn, 0,6 с, плавность ease, финал сохраняется |
@keyframes fadeIn | Имя должно совпадать с первым словом в animation |
from { opacity: 0 } | Старт: полностью прозрачный |
to { opacity: 1 } | Финиш: полностью видимый |
forwards | Без него после 0,6 с элемент может «мигнуть» и вернуться к opacity: 1 по умолчанию — но при других эффектах без forwards часто исчезает |
Как браузер проигрывает анимацию (по шагам).
- Страница загрузилась —
.cardуже в DOM. - Браузер видит
animation: fadeIn …и ищет@keyframes fadeIn. - 0 ms — рисует кадр
from(opacity: 0), карточка невидима. - 0 … 600 ms — плавно интерполирует прозрачность от 0 до 1.
- 600 ms — кадр
to; благодаряforwardsкарточка остаётся видимой.
HTML. <article class="card"> — самостоятельный блок контента; для урока и портфолио лучше, чем безликий <div>.
Типичные ошибки.
- Опечатка в имени:
animation: fade-inи@keyframes fadeIn— анимация не запустится. - Ставят
opacity: 0в.cardи забываютforwards— после анимации элемент снова прозрачный. - Ожидают fade in при скролле — для этого нужен JavaScript или
animation-timeline(продвинутый CSS); этот пример — при загрузке.
Попробуйте сами.
0.6s→2s— медленное проявление.ease→linear— равномерное, «роботное» появление.- Добавьте в
from:transform: scale(0.95)и вto:transform: scale(1)— лёгкое увеличение вместе с fade.
Появление снизу (slide up)
Задача. Уведомление «Сохранено», toast, карточка выезжает снизу и проявляется.
Частые запросы: css slide up animation, translateY animation, появление снизу css.
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Slide up</title>
<style>
body {
margin: 0;
min-height: 100dvh;
display: grid;
place-items: center;
font-family: system-ui, sans-serif;
background: #f0fdf4;
}
.toast {
padding: 1rem 1.25rem;
background: #166534;
color: #fff;
border-radius: 8px;
animation: slideUp 0.5s ease-out forwards;
}
@keyframes slideUp {
from {
opacity: 0;
transform: translateY(24px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
</style>
</head>
<body>
<p class="toast">Сохранено успешно</p>
</body>
</html>
Разбор CSS.
| Свойство | Зачем здесь |
|---|---|
translateY(24px) в from | Элемент ниже финальной позиции на 24 px — создаёт эффект «подъёма» |
translateY(0) в to | Финальная позиция — там, где блок стоит в потоке документа |
ease-out | Быстрый старт, мягкая остановка — toast «приземляется» |
opacity + transform вместе | И выезд, и проявление — профессиональный UX-паттерн |
Почему transform, а не margin-top или top.
margin-topиtopдвигают layout — соседние блоки прыгают, браузер пересчитывает всю страницу.transform: translateY()только рисует элемент в другом месте — соседи на месте, анимация обычно плавнее.
Как браузер проигрывает анимацию.
- from: невидим (
opacity: 0), сдвинут вниз на 24 px. - За 0,5 с одновременно поднимает и делает непрозрачным.
- to: на месте, полностью видим —
forwardsфиксирует результат.
Типичные ошибки.
- Анимируют
top: 24px→top: 0уposition: absolute— работает, но сложнее вёрстка и чаще лаги. translateY(-24px)вfrom— блок упадёт сверху, а не поднимется снизу (знак важен).- Слишком большой сдвиг (
120px) на мобильном — toast «улетает» за экран.
Попробуйте сами. 24px → 8px — едва заметный сдвиг, только fade «с характером». Добавьте box-shadow в to — toast «отрывается» от фона.
Пульсация (pulse)
Задача. Красная точка «онлайн», кнопка «Записаться», индикатор — мягко пульсирует и привлекает взгляд.
Частые запросы: css pulse animation, pulsating dot css, scale animation infinite.
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Pulse</title>
<style>
body {
margin: 0;
min-height: 100dvh;
display: grid;
place-items: center;
font-family: system-ui, sans-serif;
}
.dot {
width: 16px;
height: 16px;
border-radius: 50%;
background: #ef4444;
animation: pulse 1.5s ease-in-out infinite;
}
@keyframes pulse {
0%, 100% { transform: scale(1); opacity: 1; }
50% { transform: scale(1.35); opacity: 0.65; }
}
</style>
</head>
<body>
<span class="dot" aria-hidden="true"></span>
</body>
</html>
Разбор CSS.
| Свойство | Зачем здесь |
|---|---|
width/height: 16px + border-radius: 50% | Круг из квадрата |
infinite | Цикл без остановки — пока страница открыта |
ease-in-out | Мягкое ускорение и замедление — «дыхание», не мигание |
0%, 100% | Один и тот же кадр в начале и конце — цикл бесшовный |
50% | Середина цикла — максимум размера, минимум прозрачности |
scale(1.35) | Увеличение на 35% — заметно, но не карикатурно |
Как браузер проигрывает анимацию.
- 0 s — круг обычного размера.
- 0,75 s (середина 1,5 s) — крупнее и полупрозрачный.
- 1,5 s — снова исходный вид → цикл повторяется.
HTML. aria-hidden="true" — скринридер не озвучивает декоративную точку.
Типичные ошибки.
- Только
opacityбезscale— мигает, как сигнализация; для «онлайн» лучше комбо. scale(2)— слишком агрессивно; начните с1.2–1.4.- Пульс на всей карточке
infinite— отвлекает; лучше на маленьком badge.
Попробуйте сами. Поменяйте 1.5s на 3s — спокойный медленный pulse. Цвет #ef4444 → #22c55e — «онлайн» вместо «ошибка».
Кнопка с hover и focus (transition)
Задача. Кнопка приподнимается при наведении, нажимается при клике, видна при Tab с клавиатуры.
Частые запросы: css button hover effect, transition transform, кнопка анимация css, hover поднять кнопку.
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Кнопка hover</title>
<style>
body {
margin: 0;
min-height: 100dvh;
display: grid;
place-items: center;
font-family: system-ui, sans-serif;
background: #fafafa;
}
.btn {
padding: 0.75rem 1.5rem;
border: none;
border-radius: 10px;
background: #2563eb;
color: #fff;
font-size: 1rem;
font-weight: 600;
cursor: pointer;
box-shadow: 0 4px 14px rgba(37, 99, 235, 0.35);
transition: transform 0.2s ease, box-shadow 0.2s ease, background-color 0.2s ease;
}
.btn:hover {
transform: translateY(-2px);
box-shadow: 0 8px 20px rgba(37, 99, 235, 0.4);
background: #1d4ed8;
}
.btn:focus-visible {
outline: 3px solid #93c5fd;
outline-offset: 2px;
}
.btn:active {
transform: translateY(0);
box-shadow: 0 2px 8px rgba(37, 99, 235, 0.3);
}
</style>
</head>
<body>
<button type="button" class="btn">Отправить</button>
</body>
</html>
Разбор CSS — цепочка состояний.
| Селектор | Что происходит |
|---|---|
.btn (обычное) | Базовый вид + объявление transition — «как плавно менять свойства» |
.btn:hover | Мышь над кнопкой — подъём на 2 px, тень сильнее, фон темнее |
.btn:focus-visible | Фокус с клавиатуры (Tab) — синее кольцо; после клика мышью кольцо не висит |
.btn:active | Кнопка нажата — возврат вниз, тень слабее — эффект «вдавливания» |
Разбор transition — порядок важен.
transition: transform 0.2s ease, box-shadow 0.2s ease, background-color 0.2s ease;
transform 0.2s— движение вверх-вниз за 0,2 секунды.box-shadow 0.2s— тень меняется синхронно — кнопка «отрывается» от фона.background-color 0.2s— цвет не переключается мгновенно.ease— чуть медленнее в начале и конце — приятнее глазу, чемlinear.
Почему transition на .btn, а не на :hover.
Браузер должен знать правила плавности до смены состояния. Если написать transition только в :hover, при уходе мыши возврат будет резким.
Как это работает при наведении.
- Курсор вошёл на кнопку → применился
.btn:hover. transformизменился сnoneнаtranslateY(-2px)— за 0,2 s.- Курсор ушёл → стили
:hoverснялись → за 0,2 s кнопка вернулась.
Типичные ошибки.
transition: all— браузер следит за всеми свойствами, включая дорогие; перечисляйте явно.- Только
:hoverбез:focus-visible— с клавиатуры кнопку не видно (плохо для доступности и экзамена по вебу). transform: translateY(-20px)— кнопка «улетает»; для UI хватит 2–4 px.
Попробуйте сами. 0.2s → 0.6s — «желе». Уберите :active — пропадёт ощущение нажатия.
Загрузка и ожидание
Эффекты «подождите, идёт загрузка» — частый запрос в учебных проектах и на собеседованиях junior.
Крутящийся спиннер
Задача. Показать, что сайт ждёт ответ сервера или грузит файл.
Частые запросы: css loading spinner, loader animation, крутящийся кружок css, rotate animation infinite.
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Spinner</title>
<style>
body {
margin: 0;
min-height: 100dvh;
display: grid;
place-items: center;
font-family: system-ui, sans-serif;
}
.spinner {
width: 40px;
height: 40px;
border: 4px solid #e2e8f0;
border-top-color: #3b82f6;
border-radius: 50%;
animation: spin 0.8s linear infinite;
}
@keyframes spin {
to { transform: rotate(360deg); }
}
</style>
</head>
<body>
<div class="spinner" role="status" aria-label="Загрузка"></div>
</body>
</html>
Разбор CSS — из чего складывается «кольцо».
| Свойство | Зачем здесь |
|---|---|
border: 4px solid #e2e8f0 | Серое кольцо по всему перimeter |
border-top-color: #3b82f6 | Только верхняя дуга синяя — глаз видит «сектор» |
border-radius: 50% | Квадрат 40×40 превращается в круг |
rotate(360deg) | Полный оборот за один цикл |
linear | Равномерная скорость — для спиннера это стандарт |
0.8s | Быстро enough, не раздражает |
Как браузер проигрывает анимацию.
- Каждые 0,8 s элемент поворачивается от 0° до 360°.
infinite— следующий оборот сразу после предыдущего.- Синяя дуга «бежит» по кругу — классический loader.
HTML — доступность.
| Атрибут | Зачем |
|---|---|
role="status" | Область статуса для скринридера |
aria-label="Загрузка" | Озвучка «Загрузка» для незрячих пользователей |
Типичные ошибки.
- Крутят через
border-colorна всех сторонах по очереди — сложнее; паттерн «серое кольцо + цветной top» проще. animation: spin 0.8s ease— спиннер замирает на секунду между оборотами; нуженlinear.- Забывают
border-radius: 50%— крутится квадрат.
Попробуйте сами. border-top-color → border-right-color — дуга смещена. 40px → 24px — компактный спиннер для кнопки.
Три прыгающие точки
Задача. Индикатор «печатает…», «бот думает», загрузка чата.
Частые запросы: typing indicator css, three dots animation, bounce animation css.
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Точки загрузки</title>
<style>
body {
margin: 0;
min-height: 100dvh;
display: grid;
place-items: center;
font-family: system-ui, sans-serif;
}
.dots {
display: flex;
gap: 0.4rem;
}
.dots span {
width: 10px;
height: 10px;
border-radius: 50%;
background: #6366f1;
animation: bounce 0.6s ease-in-out infinite;
}
.dots span:nth-child(2) { animation-delay: 0.15s; }
.dots span:nth-child(3) { animation-delay: 0.3s; }
@keyframes bounce {
0%, 80%, 100% { transform: translateY(0); }
40% { transform: translateY(-10px); }
}
</style>
</head>
<body>
<div class="dots" aria-hidden="true">
<span></span><span></span><span></span>
</div>
</body>
</html>
Разбор CSS.
| Свойство | Зачем здесь |
|---|---|
display: flex + gap | Три точки в ряд с равным промежутком |
Один @keyframes bounce на все <span> | Не дублируем код — один сценарий |
:nth-child(2) { animation-delay: 0.15s } | Вторая точка стартует позже — волна |
:nth-child(3) { animation-delay: 0.3s } | Третья ещё позже |
0%, 80%, 100% на одном уровне | Большую часть цикла точка на земле — пауза между прыжками |
40% — пик прыжка | Короткий всплеск в середине цикла |
Как браузер проигрывает волну.
- Первая точка прыгает в момент 0.
- Вторая — с задержкой 0,15 s — фаза сдвинута.
- Третья — 0,3 s — глаз видит «бегущую» волну.
Типичные ошибки.
- Три разных
@keyframes— лишний код; хватит одного +delay. - Одинаковый
delayна всех — точки прыгают синхронно, не «typing». translateY(10px)вместо-10px— точки проваливаются вниз.
Попробуйте сами. 0.15s и 0.3s → 0.1s и 0.2s — более частая волна. Четыре точки — добавьте <span> и правило для :nth-child(4).
Skeleton shimmer
Задача. Серые полоски имитируют текст, пока данные грузятся (VK, Ozon, YouTube).
Частые запросы: skeleton loading css, shimmer effect, placeholder animation css.
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Shimmer</title>
<style>
body {
margin: 0;
padding: 2rem;
font-family: system-ui, sans-serif;
background: #fff;
}
.skeleton {
max-width: 320px;
}
.skeleton__line {
height: 14px;
margin-bottom: 12px;
border-radius: 6px;
background: linear-gradient(
90deg,
#e2e8f0 0%,
#f1f5f9 50%,
#e2e8f0 100%
);
background-size: 200% 100%;
animation: shimmer 1.4s ease-in-out infinite;
}
.skeleton__line--short { width: 60%; }
.skeleton__line--title { height: 20px; width: 80%; margin-bottom: 16px; }
@keyframes shimmer {
0% { background-position: 200% 0; }
100% { background-position: -200% 0; }
}
</style>
</head>
<body>
<div class="skeleton" aria-busy="true" aria-label="Загрузка контента">
<div class="skeleton__line skeleton__line--title"></div>
<div class="skeleton__line"></div>
<div class="skeleton__line"></div>
<div class="skeleton__line skeleton__line--short"></div>
</div>
</body>
</html>
Разбор CSS — почему «блик» едет.
| Свойство | Зачем здесь |
|---|---|
linear-gradient(90deg, …) | Полоска: серый → светлый → серый слева направо |
background-size: 200% 100% | Градиент в два раза шире блока — есть куда «ездить» |
background-position: 200% 0 → -200% 0 | Сдвигаем фон — светлая полоса пробегает по серой |
--title / --short | Разная ширина и высота — как заголовок и строки текста |
aria-busy="true" | Скринридер: контент ещё загружается |
Как браузер проигрывает shimmer.
- Фон шире видимой полоски.
- За 1,4 s позиция фона смещается с правого края к левому.
- Глаз видит «блик», бегущий по серым линиям.
Типичные ошибки.
- Забыли
background-size: 200%— блик не двигается, только статичный градиент. - Анимируют
widthполоски — тяжело; здесь двигается фон, не layout. - Shimmer на весь экран
infiniteна слабом телефоне — лаги; для учебы норм, в проде — осторожно.
Попробуйте сами. Светлая полоса в градиенте на 80% вместо 50% — узкий блик. Добавьте border-radius: 50% и height: 48px; width: 48px — skeleton-аватар.
Полоска прогресса
Задача. Полоска заполняется до 75% — загрузка файла, шаг мастера, HP в игре.
Частые запросы: css progress bar animation, width animation keyframes.
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Progress bar</title>
<style>
body {
margin: 0;
min-height: 100dvh;
display: grid;
place-items: center;
padding: 1rem;
font-family: system-ui, sans-serif;
}
.progress {
width: min(100%, 280px);
height: 8px;
background: #e2e8f0;
border-radius: 999px;
overflow: hidden;
}
.progress__bar {
height: 100%;
width: 0;
background: linear-gradient(90deg, #22c55e, #16a34a);
border-radius: inherit;
animation: fillBar 2.5s ease-out forwards;
}
@keyframes fillBar {
to { width: 75%; }
}
</style>
</head>
<body>
<div class="progress" role="progressbar" aria-valuenow="75" aria-valuemin="0" aria-valuemax="100" aria-label="Загрузка">
<div class="progress__bar"></div>
</div>
</body>
</html>
Разбор CSS.
| Свойство | Зачем здесь |
|---|---|
.progress — серая «дорожка» | Фон, виден незаполненный участок |
overflow: hidden | Зелёная полоска не вылезает за скругление |
width: 0 в начале | Старт с пустой полосы |
@keyframes fillBar { to { width: 75% } } | За 2,5 s ширина растёт до 75% родителя |
border-radius: inherit | Внутренний бар повторяет скругление дорожки |
ease-out | Быстро в начале, медленнее к концу — «дожим» загрузки |
Почему здесь width, а не transform.
Для узкой полоски 8 px пересчёт layout дешёвый. В реальном приложении процент часто задаёт JavaScript (style.width = '45%'). CSS-анимация показывает идею без скриптов.
HTML — доступность.
role="progressbar" + aria-valuenow="75" — скринридер озвучит прогресс. В живом приложении valuenow обновляют из JS.
Типичные ошибки.
- Нет
overflow: hidden— зелёный прямоугольник торчит за скруглённую дорожку. width: 75%сразу в.progress__barбез анимации — полоска статична.- Анимировать
widthу широкого sidebar — может лагать; для progress bar это норма.
Попробуйте сами. 75% → 100% — полное заполнение. 2.5s → 0.8s — быстрая загрузка.
Внимание и обратная связь
Тряска при ошибке (shake)
Задача. Поле формы дёргается, если email неверный — понятная обратная связь без alert().
Частые запросы: css shake animation, input error animation, form shake css.
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Shake</title>
<style>
body {
margin: 0;
min-height: 100dvh;
display: grid;
place-items: center;
font-family: system-ui, sans-serif;
}
.field {
padding: 0.65rem 0.85rem;
border: 2px solid #ef4444;
border-radius: 8px;
font-size: 1rem;
animation: shake 0.45s ease;
}
@keyframes shake {
0%, 100% { transform: translateX(0); }
20% { transform: translateX(-8px); }
40% { transform: translateX(8px); }
60% { transform: translateX(-6px); }
80% { transform: translateX(6px); }
}
</style>
</head>
<body>
<input class="field" type="email" value="не-email" aria-invalid="true">
</body>
</html>
Разбор CSS — почему «дёргается».
| Кадр | translateX | Эффект |
|---|---|---|
| 0%, 100% | 0 | Центр — покой |
| 20% | −8px | Рывок влево |
| 40% | +8px | Рывок вправо |
| 60% | −6px | Затухание |
| 80% | +6px | Затухание |
Амплитуда убывает (8 → 6 px) — тряска «успокаивается», как пружина.
Как связать с JavaScript (идея).
form.addEventListener('submit', (e) => {
if (!emailValid) {
field.classList.add('field--error');
field.addEventListener('animationend', () => {
field.classList.remove('field--error');
}, { once: true });
}
});
.field--error { animation: shake 0.45s ease; }
Класс вешают на момент ошибки; после animationend снимают — можно трясти снова при повторной ошибке.
Типичные ошибки.
infiniteна shake — поле трясётся вечно, пользователь в панике.translateX(50px)— слишком агрессивно для input.- Тряска без красной рамки — не все понимают, что это ошибка.
Попробуйте сами. Только 20% и 40% кадры — одно «нет» вместо двух. Добавьте background: #fef2f2 — розовый фон ошибки.
Парящий декор (float)
Задача. Иконка или иллюстрация на лендинге мягко покачивается вверх-вниз.
Частые запросы: floating animation css, hover float effect, translateY infinite.
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Float</title>
<style>
body {
margin: 0;
min-height: 100dvh;
display: grid;
place-items: center;
font-family: system-ui, sans-serif;
background: linear-gradient(180deg, #dbeafe, #eff6ff);
}
.float-icon {
font-size: 4rem;
animation: floatY 3s ease-in-out infinite;
}
@keyframes floatY {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-14px); }
}
</style>
</head>
<body>
<div class="float-icon" aria-hidden="true">🚀</div>
</body>
</html>
Разбор CSS.
| Свойство | Зачем здесь |
|---|---|
3s | Медленный цикл — спокойный декор, не отвлекает |
ease-in-out | Плавный разворот в верхней и нижней точке |
translateY(-14px) | Подъём вверх; минус — вверх по экрану |
infinite | Бесконечное «парение» на hero-секции |
Отличие от pulse. Pulse меняет размер и прозрачность. Float только двигает — объект «висит в воздухе».
Типичные ошибки.
- Float на весь текст абзаца — читать невозможно; только иконка или картинка.
translateY(-80px)— «прыжки», не парение.- Анимировать
topуposition: absolute— layout страдает;transformпредпочтительнее.
Попробуйте сами. Две иконки с animation-delay: 1.5s у второй — «вола» на лендинге. Замените emoji на <img src="…" alt="">.
Тот же приём — в UI-компонентах для декора hero-блока.
Последовательности и сложные сцены
Список с задержкой (stagger)
Задача. Пункты меню или карточки появляются по очереди — эффект «дорогого» интерфейса без библиотек.
Частые запросы: stagger animation css, animation-delay nth-child, список появление по очереди css.
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Stagger list</title>
<style>
body {
margin: 0;
min-height: 100dvh;
padding: 2rem;
font-family: system-ui, sans-serif;
background: #fff;
}
.list { list-style: none; margin: 0; padding: 0; max-width: 20rem; }
.list li {
padding: 0.75rem 1rem;
margin-bottom: 0.5rem;
background: #f1f5f9;
border-radius: 8px;
opacity: 0;
transform: translateX(-16px);
animation: staggerIn 0.45s ease forwards;
}
.list li:nth-child(1) { animation-delay: 0.05s; }
.list li:nth-child(2) { animation-delay: 0.15s; }
.list li:nth-child(3) { animation-delay: 0.25s; }
.list li:nth-child(4) { animation-delay: 0.35s; }
@keyframes staggerIn {
to {
opacity: 1;
transform: translateX(0);
}
}
</style>
</head>
<body>
<ul class="list">
<li>Первый пункт</li>
<li>Второй пункт</li>
<li>Третий пункт</li>
<li>Четвёртый пункт</li>
</ul>
</body>
</html>
Разбор CSS.
| Свойство | Зачем здесь |
|---|---|
opacity: 0 + translateX(-16px) до анимации | Начальное состояние — невидим, слева |
@keyframes staggerIn { to { … } } | Только конечный кадр — from берётся из стилей элемента |
forwards | После появления пункт остаётся видимым |
:nth-child(n) { animation-delay: … } | Каждый следующий стартует на 0,1 s позже |
| Шаг 0,1 s (0.05, 0.15, 0.25…) | Ритм «каскада» |
Как браузер проигрывает stagger.
- t = 0,05 s — стартует первый
<li>. - t = 0,15 s — второй (первый уже почти на месте).
- К t ≈ 0,8 s все четыре пункта видимы.
Масштаб на много пунктов (CSS-переменная).
.list li {
animation-delay: calc(var(--i, 0) * 0.08s);
}
<li style="--i: 1">…</li>
<li style="--i: 2">…</li>
Типичные ошибки.
- Забыли
opacity: 0в.list li— пункты видны до анимации, stagger теряет смысл. - Одинаковый
delay— всё появляется разом. animation-delay: 2sна десятом пункте — пользователь уйдёт раньше.
Попробуйте сами. translateX(-16px) → translateY(12px) — каскад снизу. 0.45s → 0.25s — быстрее, «снэппи».
Модальное окно — затемнение и масштаб
Задача. Диалог плавно открывается: фон темнеет, окно чуть увеличивается.
Частые запросы: modal fade in css, popup animation scale, overlay opacity animation.
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Modal fade</title>
<style>
body {
margin: 0;
min-height: 100dvh;
font-family: system-ui, sans-serif;
}
.modal {
position: fixed;
inset: 0;
display: grid;
place-items: center;
padding: 1rem;
}
.modal__backdrop {
position: absolute;
inset: 0;
background: rgba(15, 23, 42, 0.55);
animation: fadeIn 0.25s ease forwards;
}
.modal__dialog {
position: relative;
width: min(100%, 22rem);
padding: 1.5rem;
background: #fff;
border-radius: 12px;
box-shadow: 0 20px 50px rgba(0, 0, 0, 0.2);
animation: scaleIn 0.3s ease-out 0.05s forwards;
opacity: 0;
transform: scale(0.92);
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes scaleIn {
to {
opacity: 1;
transform: scale(1);
}
}
</style>
</head>
<body>
<div class="modal" role="dialog" aria-modal="true" aria-labelledby="modal-title">
<div class="modal__backdrop"></div>
<div class="modal__dialog">
<h2 id="modal-title" style="margin: 0 0 0.5rem;">Подтверждение</h2>
<p style="margin: 0; color: #64748b;">Окно появилось с fade и лёгким scale.</p>
</div>
</div>
</body>
</html>
Разбор CSS — два слоя, две анимации.
| Элемент | Анимация | Смысл |
|---|---|---|
.modal__backdrop | fadeIn 0.25s | Затемнение фона |
.modal__dialog | scaleIn 0.3s … 0.05s | Окно: задержка 0,05 s, рост из 92% + проявление |
Разбор animation: scaleIn 0.3s ease-out 0.05s forwards.
scaleIn— имя keyframes.0.3s— длительность.ease-out— быстро выезжает, мягко останавливается.0.05s— delay; фон успевает начать темнеть раньше окна.forwards— окно остаётсяopacity: 1иscale(1).
Разбор позиционирования.
| Свойство | Зачем |
|---|---|
.modal { position: fixed; inset: 0 } | На весь экран поверх страницы |
.modal__backdrop { position: absolute; inset: 0 } | Заливка на фон модалки |
.modal__dialog { position: relative } | Окно выше backdrop в stacking order |
display: grid; place-items: center | Диалог по центру |
HTML — доступность.
role="dialog", aria-modal="true", aria-labelledby — минимум для модального окна. Открытие/закрытие по кнопке — в UI-компонентах + JavaScript.
Типичные ошибки.
- Одна анимация на
.modal— нельзя отдельно затемнить фон и масштабировать окно. scale(0)в начале — окно «вырастает из точки», слишком драматично;0.92–0.95мягче.- Модалка без
position: fixed— блок в потоке страницы, не поверх контента.
Попробуйте сами. 0.05s delay → 0.15s — окно явно «опаздывает». scale(0.92) → scale(1.05) в начале — лёгкий overshoot (пружинка).
Набор переиспользуемых классов
Скопируйте в конец style.css — подключайте классы к любым элементам на готовой странице.
/* --- Появление --- */
.animate-fade-in { animation: fadeIn 0.6s ease forwards; }
.animate-slide-up { animation: slideUp 0.5s ease-out forwards; }
.animate-pulse { animation: pulse 2s ease-in-out infinite; }
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes slideUp {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
}
@keyframes pulse {
0%, 100% { transform: scale(1); }
50% { transform: scale(1.05); }
}
/* --- Hover-кнопка --- */
.btn-motion {
transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.btn-motion:hover {
transform: translateY(-2px);
}
Разбор использования.
<div class="card animate-fade-in">…</div>
<button type="button" class="btn btn-motion">Действие</button>
| Класс | Когда вешать |
|---|---|
animate-fade-in | Карточка, hero-текст при загрузке |
animate-slide-up | Toast, popup снизу |
animate-pulse | Badge «live», кнопка CTA |
btn-motion | Любая кнопка с лёгким hover |
Такой же набор — в UI-компоненты на CSS.
Шпаргалка — что копировать под задачу
| Нужно | Минимальный код |
|---|---|
| Появление | @keyframes + opacity + forwards |
| Движение | transform: translate… / rotate / scale |
| Hover-кнопка | transition на .btn + :hover { transform } |
| Бесконечный цикл | infinite + linear (спиннер) или ease-in-out (float) |
| По очереди | один @keyframes + :nth-child(n) { animation-delay } |
| Уважение к ОС | @media (prefers-reduced-motion: reduce) { … } |
Для движения и появления предпочитайте transform и opacity. Осторожно с бесконечным box-shadow, filter: blur и shimmer на весь экран. Учитывайте prefers-reduced-motion — каркас в начале статьи. Подробнее — Практические рекомендации по CSS и Доступность.
Что дальше
| Задача | Куда идти |
|---|---|
| Целая страница с сеткой и шапкой | HTML + CSS — готовые макеты |
| Страница на utility-классах | Tailwind — готовые блоки |
Справочник по animation-* | Анимации, переходы и трансформации |
| Карусель, табы, модалка + JS | UI-компоненты, Виджеты на JavaScript |
| Рисование и игровой цикл | p5.js — примеры фигур |
| 200 вопросов с ответами | 200 вопросов по CSS |
См. также
Другие статьи этого же раздела в боковом меню (как на странице "О разделе"). Практическая карта типовых IT-задач: термины, пошаговое внедрение, проверка качества и типичные ошибки. Простой консольный чат на C# — учебное приложение с сокетами: TCP между клиентом и сервером, многопоточность и обмен сообщениями в консоли. Примеры вёрстки на HTML и CSS с разбором: центрирование, Flexbox, Grid, формы, шапка, подвал и адаптив для учебы и портфолио. Перед началом работы обязательно изучите главу Turtle . Галерея 3D-фигур на Panda3D — карточки, куб, пирамида, сфера, сетки и составные сцены; код для локального запуска. Готовые docker-compose.yml с разбором каждой строки — nginx, PostgreSQL, Redis, WordPress, MongoDB. Примеры для школьников и студентов: postgres example, поднять базу локально, app + db. Примеры nginx.conf для статики, reverse proxy, React/Vue SPA, PHP, SSL и балансировки — построчный разбор директив, проверка curl и типичные ошибки для лабораторных и VPS. dockerfile example — 10 готовых Dockerfile с построчным разбором: node, python, golang, react nginx, spring boot, php, dotnet. Для студентов, лабораторных и docker build с нуля. PromQL example — готовые запросы Prometheus и Grafana с построчным разбором: up, rate, node_exporter cpu, memory, disk, http_requests_total, histogram_quantile p99, алерты. Для студентов, лабораторных и devops docker compose. Готовые манифесты Kubernetes с разбором каждой строки — Pod, Deployment, Service, ConfigMap, Secret, Ingress. Примеры для Minikube, kind и kubectl apply. Примеры графиков Matplotlib на Python для школьников и студентов — sin, cos, парабола, столбцы, scatter, гистограмма, подграфики; код с подробным разбором. Примеры pandas на Python для школьников и студентов — DataFrame, фильтрация, groupby, очистка, merge, сводные таблицы и экспорт; код с подробным разбором каждой строки.Готовые решения
Простой консольный чат на CSharp
HTML + CSS — готовые макеты
Примеры фигур Turtle на Python
Примеры фигур Panda3D на Python
Docker Compose — готовые стеки
Nginx — конфиги под задачу
Dockerfile — 10 типовых образов
Prometheus + Grafana — запросы
Kubernetes YAML — минимальные манифесты
Matplotlib — графики
Pandas — типовые операции