Плавный интерфейс без библиотек: аккордеон, вкладки и переходы

0

Анимации ♡

Плавный интерфейс без библиотек: аккордеон, вкладки и переходы
Плавно —
значит дорого ♡

Разница между сайтом «сделано» и сайтом «приятно» часто в анимации. Не в эффектах ради эффектов, как в презентациях из 2007 года, а в том, что блок не прыгает, а плавно раскрывается. Подключать для этого библиотеку не нужно: браузер умеет всё сам. Показываю на реальных кусках моего сайта.

Аккордеон: details + Web Animations API

Тег "" раскрывается без JavaScript, но мгновенно, как будто кто-то дёрнул шторку. Чтобы получилось плавно, перехватываем клик, сами анимируем высоту и только потом переключаем "open":

const animation = details.animate(
  { height: [`${from}px`, `${to}px`] },
  { duration: 280, easing: 'cubic-bezier(0.4, 0, 0.2, 1)' },
);

animation.finished.then(() => finish(details, opening)).catch(() => {});

Чтобы открытым оставался только один вопрос, перед раскрытием нового закрываем остальные тем же способом. Стрелку можно вращать по классу, который ставится сразу при клике, а не после окончания анимации: так интерфейс кажется отзывчивее.

Грабли: onfinish иногда просто не приходит

Я поначалу ждала конца анимации через "animation.onfinish". В обычной вкладке всё работало, я расслабилась. А потом оказалось, что в фоновой вкладке, пока браузер ничего не рисует, событие не приходит вообще, и аккордеон застревает полуоткрытым. Классика: в разработке работает, у пользователя нет.

Решение: ждать не событие, а промис "animation.finished", и добавить страховочный таймер, который сам завершит анимацию чуть позже её длительности. Ремень плюс подтяжки.

Вкладки с плавной высотой

Панели вкладок разной высоты при переключении дёргают страницу вверх-вниз, и выглядит это так себе. Я оборачиваю их в общий контейнер, запоминаю высоту до переключения и после, а потом анимирую контейнер между этими значениями. Новая панель при этом плавно проявляется и чуть выезжает снизу:

box.animate({ height: [`${from}px`, `${to}px`] }, { duration: 320, easing: 'cubic-bezier(0.4, 0, 0.2, 1)' });
panels[index].animate(
  { opacity: [0, 1], transform: ['translateY(10px)', 'translateY(0)'] },
  { duration: 320, easing: 'ease-out' },
);

Переходы между страницами одной строкой

Современные браузеры умеют плавно сменять страницы сами. Достаточно одного правила в CSS:

@view-transition { navigation: auto; }

::view-transition-old(root),
::view-transition-new(root) { animation-duration: 240ms; }

Клик по обычной ссылке или фильтру теперь даёт мягкое перетекание вместо белой вспышки. А если браузер так не умеет, страница просто откроется как обычно, ничего не ломается. Это тот редкий случай, когда красота достаётся почти бесплатно.

Не забудь про тех, кому анимации мешают

В системе можно включить «уменьшить движение». Проверяй "prefers-reduced-motion: reduce" и отключай в этом случае анимации. Это пара строк CSS, а доступность растёт заметно. Кого-то от лишнего движения реально мутит, а не «ну он привередничает».

И ещё одна грабля: диалог уехал в угол

Окошко "" по умолчанию центрируется само, за счёт "margin: auto". Но у меня в стилях стоял общий сброс отступов, и окошко прилипло к левому верхнему углу и сидело там как ни в чём не бывало. Лечится одной строкой: "margin: auto" самому диалогу. Заметить такое можно только глазами, тесты про это не знают. Про мелочи, которые ловятся только внимательным взглядом, я писала в статье про визуал, а полный список моих находок ждёт в статье про мелочи в интерфейсе.

Комментарии

Буду рада вашим мыслям, идеям и вопросам!
Давайте обсуждать ♡

Пока никто не написал.
Станьте первым! ♡

Поддержать проект

Угостить кофе по СБП

Перевод через Систему быстрых платежей, сумма любая. Спасибо, что вы здесь ♡

QR-код для перевода по СБП
Или другим способом
Дневник на почте

Подписаться на блог

Когда выйдет новая запись, я пришлю письмо со ссылкой. Без рассылок «просто так» и без спама. Отписаться можно одним нажатием.

Или следить в Telegram