Не знаете, что такое меню хамелеона? Проверьте это в действии на нашем сайте.
В июне 2017 года мы опубликовали наш новый веб-сайт компании здесь, в Гуаве. Для нас это стало важной вехой, потому что эта новая версия объединила нашу визуальную идентичность.
По сравнению с предыдущей версией произошло много изменений: мы добавили красивые новые иллюстрации, сделанные нашими невероятными дизайнерами, пересмотрели нашу цветовую палитру, написал много нового контента, реализовал опыт создания журналов с обложками на всех страницах и разделил внутренние разделы великолепными пышными формами.
Все эти вещи удивительны, но одна важная деталь, на которую следует обратить внимание: что с точки зрения реализации интерфейса очень сложно иметь дело с взаимодействием между этими извилистыми формами и фиксированными элементами после прокрутки пользователем. Как гордые мастера и женщины мы, избавление от фиксированных элементов не было вариантом, к которому мы стремились, что означало, что мы должны были придумать способ заставить его работать так, как предполагалось. Это проблема, которую мы собираемся обсудить в этом посте.
Содержание статьи
Мотивация
Начиная с ранних версий новой концепции веб-сайта, мы сосредоточились на идее фиксированного навигационного меню для экранов рабочего стола. Блокировка его положения будет очень хорошо работать с нашим видением идеальной навигации для этого конкретного проекта, но она создала проблему поддержания его читабельности по нескольким различным цветам фона и различным контрастным палитрам.
Во-первых, мы рассмотрели защиту содержимого меню с помощью простого, простого цвета фона. Это решение решило бы проблему читабельности довольно хорошо, но — помимо того, что в наших экспериментах это выглядело немного странно — в некоторых разделах страницы скрывались части ключевых иллюстраций. Мы этого не хотели. И все еще оставалась ключевая проблема, которую необходимо решить…
Введите разделители изогнутых секций . Сплошные фоновые заливки ухудшались с каждой минутой. Единственным приемлемым вариантом действий оставалось найти способ заставить меню корректировать свои цвета в зависимости от того, в каком разделе оно находится, при этом соблюдая все изогнутые и не изогнутые границы раздела на этом пути. Черт .
Техника
В поисках существующих решений нашей проблемы мы наткнулись на захватывающую библиотеку под названием Midnight.js. Позволив вам изменить заголовок вашего сайта на лету, этот небольшой плагин jQuery привлек наше внимание. К сожалению для нас, библиотека обрабатывает только прямолинейные секции, по крайней мере, на тот момент.
Даже если бы мы не могли использовать библиотеку, идея ее реализации была бы ключом к разработке нашей собственной методики.
Требуемое нами поведение при изменении меню было довольно своеобразным. Стили меню должны немедленно измениться при наведении на другой раздел с разными цветами фона. Кроме того, это зависание может быть частичным, что означает, что просто слово или даже небольшая часть слова будут иметь разные стили. Одно только это требование отбросило любые потенциальные решения, использующие классическую технику переключения классов CSS / JS.
Именно здесь вступает в игру реализация Midnight.js, вводя понятие маскирующих элементов что наряду с с помощью анимаций меню составляют две основные концепции, применяемые в нашем решении.
Элементы маски
Первоначально, когда мы познакомили вас с нашей небольшой задачей, мы могли испытать искушение поразмышлять о решении, в котором меню «знает», какой раздел оно находится, и какие стили применить к нему. Я знаю у меня есть. С элементами маски проблема решается с точностью до наоборот: разделы являются здесь «интеллектуальными» элементами, зная, какие меню или стили отображать.
Это имеет смысл, верно? Каждый фактический раздел страницы имеет свое собственное фиксированное меню, скрывающее переполнения, поэтому меню не перекрываются. Что ж, легче сказать, чем сделать.
Первая проблема, на которую мы должны обратить внимание, состоит в том, что элементы HTML с фиксированным позиционированием не учитывают границы позиционируемого родителя. Вместо этого фиксированное позиционирование закрепляет элемент на месте относительно самого окна просмотра браузера . Так что это умное переполнение: скрытое; свойство
примененное к элементам раздела, работать не будет.
Во-вторых, мы не хотим вставлять всю разметку меню внутри каждого раздела страницы. Было бы очень странно смешивать навигацию с содержимым каждого раздела на странице; не говоря уже о проблемах доступности. Именно здесь элементы маски пригодятся.
Эти маски представляют собой не что иное, как прозрачные элементы, созданные исключительно для имитации оригинального формата раздела, ограничивая меню каждого раздела внутри него. Их свойства клонируются из фактических элементов раздела. Приведенные ниже фрагменты иллюстрируют этот шаг реализации.
Все фрагменты в этом посте являются общим кодом HTML / jQuery.
Предположим, у нас есть элемент section, которому нужна маска .
Для этого нам понадобится элемент маски на странице (в конце страницы, желательно по причинам, уже упомянутым).
Эта маска имеет некоторые интересные свойства:
-
class
: дополнительные классы используются для установки некоторых конкретных свойств данной маски. Помните кривые, упомянутые выше? Что ж, нам нужно реализовать эти кривые сечения в CSS и повторить их в масках. Таким образом, элемент маски имеет ту же форму, что и элемент section. -
data-menu-class
: это класс, применяемый к элементу меню, добавляемому к дочерним элементам этой маски. -
data-menu-mask
: строка, указывающая селектор для соответствующего элемента раздела.
Таким образом, мы можем использовать jQuery для клонирования CSS-свойства section с использованием атрибутов, определенных в приведенном выше фрагменте.
Очень просто мы клонируем стили раздела в элементы mask. В дополнение к свойствам, указанным выше, нам нужно сделать маску абсолютно позиционированной, чтобы она могла быть точно над секциями. Мы можем сделать это, используя дополнительные классы маски.
После этого нашей следующей задачей должно стать добавление клона меню к дочерним элементам маски. Давайте не забудем класс модификатора меню, указанный в атрибуте data-menu-class
. Он определяет стили для меню этого раздела.
Поскольку фиксированное позиционирование с использованием CSS не будет работать для меню, их необходимо позиционировать абсолютно, и нам нужно перемещать их вверх и вниз с помощью JavaScript, имитируя поведение с фиксированным позиционированием. Это наш хук для следующего подраздела: анимация меню.
Анимация меню
Краткий обзор: на данный момент у нас есть элемент маски для каждого раздела нашей страницы , Эти маски расположены точно над реальными разделами, и каждый из них содержит клон меню страницы, абсолютно расположенный один над другим. Поскольку каждая маска имеет свойство overflow: hidden; свойство
отображается только меню для первого раздела. Ничего не должно происходить при прокрутке (пока) из-за их расположения.
Следующим шагом, в наиболее упрощенном подходе, должно быть обновление верхней позиции каждого меню при прокрутке страницы с помощью window.pageYOffset
имущество. Таким образом, они будут следовать за прокруткой страницы, действуя как фиксированный элемент. В некоторых более простых сценариях это должно работать нормально. Дело в том, что, как правило, мы будем иметь дело с 5+ меню, обновляя каждое из них при каждом крошечном движении прокрутки. Этот подход вызывает значительное заикание в движении.
Чтобы добиться этой элегантной плавности, я бы рекомендовал использовать JavaScript API requestAnimationFrame
.
«Window.requestAnimationFrame
()
метод сообщает браузеру, что вы хотите выполнить анимацию, и запрашивает, чтобы браузер вызвал указанную функцию для обновления анимации перед следующей перерисовкой. Метод принимает обратный вызов в качестве аргумента, который будет вызван перед перерисовкой. "
(Источник: https://developer.mozilla.org/en-US/docs/ Web / API / window / requestAnimationFrame)
Прикладной пример всей логики маски и использования window.requestAnimationFrame
можно проверить в следующей упрощенной проверке концепции, размещенной в Codepen.
Оптимизация графического процессора
Когда мы реализовывали это меню для веб-сайта Гуавы, одним из требований было чтобы содержать эти маскирующие элементы внутри области просмотра div
. Идея заключалась в том, чтобы ограничить все эти области маски областью меню, но есть одна стоимость реализации, которую необходимо учитывать.
В этом случае область просмотра будет иметь фиксированную позицию, поэтому нам придется вручную перемещать маски внутри нее. ong с соответствующими клонами меню при прокрутке.
Иногда маски разделов могут принимать огромные формы, особенно когда имитируют круг или любые другие формы, которые вы используете. Перемещение этих огромных элементов вверх и вниз внутри области просмотра, скорее всего, ухудшит производительность анимации, поскольку браузер перемещает их на при каждом перекрашивании внутри цикла.
Чтобы обойти эту проблему, мы использовали Ускоренные переходы CSS с помощью графического процессора . Детали техники выходят за рамки этой статьи, но есть несколько хороших статей об этом. Вы можете проверить их по ссылкам ниже:
Анимация CSS GPU: Делая все правильно — Smashing Magazine
Повышение производительности приложения HTML5 с помощью CSS-переходов с GPU-ускорением | Urban Insight