06
Май 2017
Статьи

Правильная css-анимация

  • Главная
  • Статьи
  • Для чего в вебе нужна анимация? Ответ довольно прост: во-первых, правильная анимация позволяет нам привлечь внимание пользователя к определенной детали интерфейса и побудить совершить определенное действие, во-вторых, анимация делает наш сайт более красивым, динамичным и интересным.

    Что значит «Правильная анимация»? Согласитесь, довольно неприятно, когда анимация на сайте подлагивает, подвисает, подтормаживает. Она же должна быть плавной, приятной и совсем не заметной! Придерживаясь рекомендаций, которые описаны ниже, наша с вами анимация будет всегда правильной!

    Анимация (animation)

    Правило @keyframes — установка ключевых кадров. Пример:

    @keyframes move {
    0% {transform: scale(1);}
    50% {transform: scale(1.5);}
    100% {transform: scale(1);}
    }
    1. animation-name: move — название анимации.
    2. animation-duration: .2s — продолжительность анимации (Значение в секундах .2s или в миллисекундах 20ms).
    3. animation-timing-function: linear — изменение скорости анимации. Значения:
      cubic-bezier(x1, y1, x2, y2) — Кривая Безье. Значения переменных от 0 до 1.
      ease — Используется по умолчанию. Начинается медленно, быстро ускоряется, замедляется в конце. Аналог: cubic-bezier(0.25,0.1,0.25,1)
      linear — Равномерная скорость. Аналог: cubic-bezier(0,0,1,1)
      ease-in — Начинается медленно, плавно ускоряется в конце. Аналог: cubic-bezier(0.42,0,1,1)
      ease-out — Начинается быстро, плавно замедляется в конце. Аналог: cubic-bezier(0,0,0.58,1
      ease-in-out — Начинается медленно и медленно заканчивается. Аналог: cubic-bezier(0.42,0,0.58,1)
      steps(количество шагов,start|end) — Временная функция. Позволяет разбить анимацию на чёткое количество шагов. Первый аргумент steps — количество шагов. start – означает, что при начале анимации нужно сразу применить первое изменение. Альтернативное значение end означает, что изменения нужно применять не в начале, а в конце каждой секунды
      step-start — Задаёт пошаговую анимацию, разбивая ее на отрезки, изменения происходят в начале каждого шага. Аналог steps(1, start)
      step-end — Пошаговая анимация, изменения происходят в конце каждого шага. Аналог: steps(1, end)
    4. animation-delay: 2s — Задержка анимации. (Значение в секундах 2s или в миллисекундах 200ms).
    5. animation-iteration-count: 3 — Повтор анимации. С помощью целого числа задается количество повторов анимации. Значение по умолчанию 1. Дробные значения больше 1 будут воспроизводить анимацию, обрезая её на части следующей итерации. Значение infinite — анимация будет проигрываться бесконечно.
    6. animation-direction: revers — Направление анимации. Свойство задает направление повтора анимации. Если анимация не повторяется, то это свойство не имеет смысла. Значения:
      normal — По умолчанию. Обычный режим.
      alternate — Анимация проигрывается с начала до конца, затем в обратном направлении
      alternate-reverse — Анимация проигрывается с конца до начала, затем в обратном направлении
      reverse — Анимация проигрывается с конца
    7. animation-play-state: paused — Запуск и остановка анимации. Пример: .element:hover {animation-play-state: paused;}. Значения:

      running — По умолчанию. Запуск анимации.
      paused — Остановка анимации.

    8. animation-fill-mode: forwards — Состояние элемента до и после воспроизведения анимации. Значения:

      None — По умолчанию. Состояние элемента не меняется
      forwards — Элемент остается в конечном состоянии.
      backwards — Возвращает состояние элемента после загрузки страницы к первому кадру, даже если установлена задержка animation-delay, и оставляет его там, пока не начнется анимация.
      both — Позволяет оставлять элемент в первом ключевом кадре до начала анимации (игнорируя положительное значение задержки) и задерживать на последнем кадре до конца последней анимации.

    Краткая запись анимации

    animation: animation-name animation-duration animation-timing-function animation-delay animation-iteration-count animation-direction;
    Для воспроизведения анимации обязательно нужно указать свойства: animation-name и animation-duration, остальные свойства примут значения по умолчанию. Порядок свойств не имеет значения, однако animation-duration должно стоять перед animation-delay.

    Множественные анимации

    Для одного элемента можно задать сразу несколько анимаций через запятую: animation: first-antimation 1s ease-in-out 0.5s alternate, second-animation 1s linear .3s;

    Переходы (transition)

    Css-свойство transition позволяет анимировать элемент при наступлении определенного события, чаще всего при наведении курсора (:hover). Далее подробно о каждом свойстве.

    1. transition-property: opacity, transform — Названия свойств, к которым будет применен эффект перехода. Значения:

      css-свойства — свойства через запятую
      all — По умолчанию. Эффект перехода применится ко всем свойствам элемента.

    2. transition-duration: .2s — продолжительность перехода (Значение в секундах .2s или в миллисекундах 20ms)
    3. transition-timing-function: linear — Можно использовать разные функции для каждого свойства. Аналог: animation-timing-function
    4. transition-delay: 2s — Задержка перехода. (Значение в секундах 2s или в миллисекундах 200ms)

    Краткая запись перехода

    transition: transition-property transition-duration transition-timing-function transition-delay;
    Обязательно нужно указать свойство: transition-duration, остальные свойства примут значения по умолчанию. Пример: transition: .2s; аналог: transition: all .2s ease 0s;

    Плавный переход нескольких свойств

    transition: opacity .3s ease, transform .2s linear;

    или

    transition-property: opacity, transform;
    transition-duration: .3s, .2s;
    transition-timing-function: ease, linear;

    Немного про загрузку страницы в браузере

    Для того, чтобы писать производительный css нужно хотя бы немного знать, как работают браузеры, как они обрабатывают всю эту HTML, CSS, JS кашу.

    Есть пять основных областей, о которых следует знать и помнить при выполнении своей работы. Это те области, которые вы в наибольшей степени контролируете. Они являются ключевыми точками конвейера вывода пикселей на экран.

    Полный конвейер пикселей

    JavaScript. Обычно JavaScript используется для выполнения работы, результатом которой будут визуальные изменения, будь то функция jQuery animate, сортировка набора данных или добавление DOM-элементов на страницу. Однако вызывать визуальное изменение можно не только с помощью JavaScript: Также часто используются анимация CSS, переходы и API-интерфейс веб-анимации.
    Вычисление стилей. В процессе вычисления стилей определяется, какие правила CSS к каким элементам применяются с учетом соответствующих селекторов, например: .headline или .nav > .nav__item. Отсюда, после того как правила определены, они применяются и вычисляются итоговые стили для каждого элемента.

    Расчет макета. Как только браузер будет знать, какие правила применяются к элементу, он может начать вычислять, сколько места он займет, и где он находится на экране. Модель макета для Интернета означает, что один элемент может влиять на другие, например: ширина элемента <body> обычно влияет на значения ширины дочерних элементов и так далее по всему дереву, поэтому этот процесс для браузера может быть довольно сложным.

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

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

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

    Далеко не всегда каждый кадр затрагивает все части конвейера. На самом деле есть три варианта, в соответствии с которыми конвейер_обычно_ воспроизводится для данного кадра при внесении визуального изменения, – с помощью JavaScript, CSS или веб-анимации:

    JS / CSS > Стиль > Расчет макета > Прорисовка > Компоновка

    Полный конвейер пикселей

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

    JS / CSS > Стиль > Прорисовка > Компоновка

    Конвейер пикселей без перерасчета макета

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

    JS / CSS > Стиль > Компоновка

    Конвейер пикселей без перерасчета макета или прорисовки

    Если же изменить свойство, которое не требует ни перерасчета макета, ни прорисовки, браузер сразу же перейдет к компоновке.

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

    Какие свойства нужно использовать при анимации

    Из выше описанного нам стало ясно, что для хорошей плавной анимации можно использовать те свойства, которые вызывают только компоновку, исключая перерасчет макета и прорисовку. Таких свойств в CSS пока что немного: opacity и transform, но с их помощью можно сделать многое.

    1. Позиционированиеtransform: translate(x,y) translateX(n) translateY(n)
    2. Масштабированиеtransform: scale(x,y) scaleX(n) scaleY(n)
    3. Вращениеtransform: rotate(ndeg)
    4. Деформированиеtransform: kew(x-ndeg,y-ndeg) skewX(ndeg) skewY(ndeg)
    5. Матрицаtransform: matrix(a, c, b, d, x, y)
    6. Прозрачностьopacity: 0…1

    Свойство will-change

    CSS свойство will-change предоставляет разработчику возможность уведомить об ожидаемом изменении элемента, таким образом браузер может настроить соответсвующую оптимизацию до того как элемент действительно изменится.

    Данное свойство, является пока еще экспериментальным и работает не во всех браузерах, поэтому я пока не решался его использовать. Если кто пользуется, выскажете свое мне по его работе в комментариях, буду признателен.

    Значения will-change

    scroll-position – ожидается анимация или изменение положения скролла элемента в ближайшем будущем.
    contents — ожидается анимация или изменение чего-то в контенте элемента в ближайшем будущем.
    css-свойство – свойство которое должно измениться в ближайшем будущем

    Правильное использование свойства will-change

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

    Используйте умеренно. Обычное поведение для оптимизаций которые выполняет браузер, удалить оптимизацию как можно скорее и вернуть нормальное состояние. Но добавление will-change прямо в файле стилей предполагает, что указанный элемент всегда находится в нескольких шагах от изменений и браузер будет сохранять для него оптимизацию гораздо больше времени. Так что, было бы хорошо включать и отключать will-change используя скрипт до и после того как произошли изменения.

    Не применяйте will-change к элементам для выполнения преждевременной опимизации. Если ваша страница хорошо отрабатывается, не применяйте will-change свойство к элементу только чтобы выжать немного больше скорости. will-change предназначен для использования в крайнем случае, для того чтобы исправить существующие проблемы оптимизации. Его не следует использовать для предвидения проблем оптимизации. Черезмерное использование will-change приведет к излишнему потреблению памяти и вызовет более тяжелый рендеринг так как браузер будет пытаться подготовиться к возможным изменениям. Это приведет к ухудшению производительности.

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

    Длительность анимации

    Результаты исследований показали, что веб-анимация элементов пользовательского интерфейса (UI) для комфортного восприятия пользователем, должна быть в диапазоне от 200мс до 500мс. Причем, если элемент небольшой, допустим кнопка с достаточно простой анимацией при наведении, то 200мс для данной анимации будет в самый раз. То есть чем больше элемент и сложнее анимация, тем анимация может длиться дольше, но не более 500мс.

    Список источников

    1. CSS3-анимация
    2. Переходы в CSS
    3. Производительность визуализации
    4. will-change
    5. How fast should your UI animations be?
    0
    комментить
    поделиться
    252
    подписаться
    Заметки по книге: Веб-дизайн идеи, секреты, советы
    Привет! ;) Меня зовут Владислав
    я — веб-дизайнер

    Люблю дизайнить, создавать что-то новое и совершенствовать существующее. В теме с 2010 года. Постоянно прокачиваю себя в данной сфере, слежу за трендами.

    Увлекаюсь спортом, люблю слушать музыку, путешествовать, развиваться и расти, как специалист. Стараюсь брать от жизни сполна!

    • photoshop
    • Figma
    • XD
    • responsive
    • adaptive
    • UI
    • UX
    • Interactive
    • modern
    • html
    • css/scss
    • css
    • JavaScript
    • jQuery
    • gulp
    • php
    • Wordpress