Есть ли изменчивое CSS свойство height для элементов, входящих в DOM? Jank происходит при использовании Semantic-UI-React Transitions

Я не уверен, что это правильное место, чтобы задать этот вопрос; Я рассмотрел Рекомендации по программному обеспечению, но решил, что сначала попробую.

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

Так вот в чем проблема - я использую переходы (анимации), предоставляемые Semantic-UI-React, и хотя он прекрасно работает, когда элемент занимает его пространство, мне было интересно, есть ли практика или шаблон, который обрабатывает поведение смежные элементы DOM к тому, что анимируется?

Я предоставил GIF ниже, чтобы проиллюстрировать, что я имею в виду. Я полагаю, что я мог бы просто переместить анимированные элементы из контейнера формы, чтобы предотвратить рывки, но мне было интересно, есть ли более элегантный шаблон или подход к этому...

Merci!

1 ответ

Решение

К сожалению, нет особенно элегантного подхода к этому.

Что касается вопроса в заголовке вашего сообщения, общий подход заключается в том, чтобы оживить height из новых элементов. Если вы не знаете высоту элементов, к сожалению, анимация из 0px в auto еще не работает, но вы можете обмануть его, анимируя max-height от 0px до значения, немного превышающего максимальный размер, который вы ожидаете для элемента.

Но не делай этого.

Это заставит браузер размещать страницу на каждом кадре анимации и почти наверняка будет тормозить на младших устройствах.

Вместо этого вам лучше оживить transform,

Наиболее распространенным подходом является:

  1. Возьмите исходное положение элементов (используя getBoundingClientRect() и т.д.), которые будут затронуты непосредственно перед добавлением новых элементов в DOM (возможно, с использованием getSnapshotBeforeUpdate если вы не используете хуки, в этом случае вы можете использовать useRef аналогичный эффект).

  2. После того, как вы добавили новые элементы (которые вы, вероятно, также анимируете, используя transform с подходящим scale() функция), вычислить дельту от того, где сейчас находятся элементы смещения, по сравнению с тем, где они были раньше.

  3. Настройте transform анимация от негатива дельты до нуля (т. е. подход FLIP). Например, если элемент был смещен на 300 пикселей вниз по странице, анимируйте transform от translateY(-300px) в none,

Конечно, вы должны сделать это для всех элементов в потоке, на которые влияют, поэтому было бы проще всего поместить их все в один контейнер и просто анимировать это.

Что касается третьего пункта, у вас есть несколько вариантов технологий, ни один из которых не является хорошим:

  • CSS переходы. Это самое простое, но вам нужно будет запустить сброс стиля, чтобы получить отрицательную начальную точку дельты. например

    elem.style.transform = `translateY(-${offset}px)`;
    elem.style.transition = `transform .3s`;
    getComputedStyle(elem).transform; // Flush style
    elem.style.transform = `none`;
    
  • CSS анимация. производства @keyframes Динамическое использование правил CSSOM - это боль, но, по крайней мере, вам не нужно запускать сброс стилей (для удобства вы можете установить анимацию с неявным to-keyframe).

    @keyframes random-id { from: { translateY(-300px); } }
    
  • Веб-анимация. Это, наверное, наиболее хорошо подходит.

    elem.animate({ transform: [ `translateY(-${offset}px)`, 'none' ] }, 300);
    
    // In future when browsers ship support for implicit to/from keyframes:
    elem.animate({ transform: `translateY(-${offset}px)`, offset: 0 }, 300);
    

    К сожалению, Safari поддерживает только веб-анимацию в Tech Preview, поэтому пользователи Safari получат неанимированную версию до следующего выпуска Safari. Пользователи Edge также получат неанимированную версию, пока не появится Edge на основе Chromium. Также есть полифилл, но он не поддерживается в данный момент активно.

Если вы используете React, Animating the Unanimatable является полезной статьей обо всем этом.

Другая сложная часть заключается в том, что прокрутка не прыгает, для чего вам может понадобиться привязка прокрутки.

Другие вопросы по тегам