Урок 12.1 · Интерфейсы и сайты с нуля · Модуль 12. Праздник на экране · Бесплатно
Цель урока: Собрать коробку, которая трясётся, открывается по нажатию и показывает пожелание.
Нужно знать заранее: Уроки 4.2 и 5.3
Зачем это нужно: Подарок, который тихо качается в углу экрана, — это не украшение, а приём: движение замечают раньше текста. Так показывают «нажми меня», новую функцию, подсказку или праздничную акцию. И устроено это проще, чем кажется: картинка, несколько строк анимации и обработчик нажатия.
Как это работает: Тряска — это CSS-анимация. Ключевые кадры описывают, что происходит с элементом в разные моменты времени, а свойство animation подключает их к элементу. @keyframes gift-shake { … } — «что делать». animation: gift-shake 8s ease-in-out infinite — «когда и сколько раз». Восемь секунд — длина одного цикла. Внутри цикла коробка качается только в первые доли секунды, остальное время стоит: infinite повторяет цикл бесконечно, но движение занимает его малую часть. Поэтому коробка «зовёт» раз в восемь секунд, а не дёргается непрерывно. Окно с пожеланием — обычный блок, который лежит в разметке и спрятан: display: none. По нажатию мы меняем это свойство на flex, и окно появляется поверх страницы (position: fixed и inset: 0 растягивают его на весь экран). Так же оно и закрывается: display = 'none'.
Разбор по шагам: 1. Коробка — это button с id gift: кнопку можно нажать и мышью, и с клавиатуры, поэтому она честнее обычной картинки. 2. Опишите @keyframes gift-shake: наклоны влево и вправо через transform: rotate. 3. Подключите анимацию к кнопке: animation: gift-shake 8s ease-in-out infinite. 4. Окно modal спрятано через display: none, а внутри лежит пустой абзац wish. 5. В обработчике gift.onclick покажите окно (modal.style.display = 'flex') и впишите пожелание (wish.textContent = '…'). 6. В обработчике close верните окну display: none.
Частая ошибка: Анимация написана, а коробка стоит. Причина почти всегда одна из двух: имя в animation не совпадает с именем в @keyframes (gift-shake и giftShake — разные имена) или кадры описаны, но к элементу не подключены. Проверить просто: если у кнопки animation-name равен none, значит анимация не подключена.
Важно: В стилях уже стоит блок @media (prefers-reduced-motion: reduce) — он выключает тряску тем, у кого в системе включено «уменьшить движение». Это не формальность: постоянное движение мешает людям с вестибулярными расстройствами, а на слабом телефоне ещё и тратит батарею. Правило простое: любая анимация должна уметь выключаться.
Итог: Коробка качается, по нажатию открывается окно с пожеланием, крестик его закрывает. Это те же три приёма, что и в настоящем приложении: @keyframes для движения, display для показа окна, обработчик для реакции на нажатие.
Что дальше: Коробка — только видимая часть. В настоящем приложении подарок открывается один раз в день на аккаунт, и лимит хранится не в браузере, а в данных: запись «пользователь + день» и проверка до записи. Это разобрано в уроке «Один раз в день: как сервер запоминает действие» из траектории «Программирование с нуля» — вместе два урока дают полную картину.
@keyframes gift-shake {
0%, 100% { transform: rotate(0deg); }
25% { transform: rotate(-8deg) scale(1.05); }
50% { transform: rotate(8deg) scale(1.05); }
75% { transform: rotate(-4deg); }
}
#gift { animation: gift-shake 8s ease-in-out infinite; }Коробка и окно уже свёрстаны. Опишите ключевые кадры gift-shake (наклоны влево-вправо) и подключите их к кнопке #gift. В скрипте: по нажатию на коробку покажите окно #modal (display: flex) и впишите пожелание в #wish, по нажатию на крестик #close спрячьте окно обратно. Кнопка «Проверить» нажмёт на коробку и на крестик вместо вас.
Критерий успеха: Коробка качается, по нажатию открывается окно с пожеланием, а крестик закрывает его обратно.