Более удобные выпадающие меню
HTML&CSS

Более удобные выпадающие меню

Оригинал: Dropdown Menus with More Forgiving Mouse Movement Paths, Chris Coyier

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

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

Многие выпадающие меню разработаны таким образом, что, когда правая часть не находится в состоянии :hover, срабатывает событие mouseleave или mouseout и подменю с нужным пунктом меню закрывается.

Основной подход CSS

Обычно выпадающие меню реализованы таким образом, что подменю раскрывается с помошью CSS, если родительский элемент переходит в состоние :hover. Или же с помощью JavaScript состояние переключается в обработчиках собития mouseenter / mouseover. Поэтому фокус в том, чтобы предотвратить слишком легкое наступление этих событий. Другими словами, расширить коридор.

Главная причина, почему я стал думать об этом, это узкие коридоры в наших выпадающих меню на CodePen. Чтобы расширить их, я добавил пару псевдо-элементов в подменю. Если курсор мыши проходит над ними, ничего не происходит, как будто бы он находится над подменю.

Красным цветом показано, как спозиционированы псевдо-элементы.

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

История этой техники начинается с 2005 года и классического демо :

А также возможно демо Терри Коблентца .

Расширение границ с помощью CSS

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

See the Pen CSS3 Dropdown Menu by John Gardner (@Alhadis) on CodePen.

Задержка при потере курсора мыши

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

Мы можем вызывать небольшую задержку при потере курсора мыши. При наведении мыши реагировать немедленно, а при потере курсора с небольшой зарежкой. В CSS это можно сделать следующим образом:


.submenu {
  visibility: hidden;
  transition: 0.2s 1s; /* delay of 1 seconds on hover off */
}
.parent:hover .submenu {
  visibility: visible;
  transition-delay: 0s; /* react immediately on hover */
}

Обратите внимание, мы используем здесь свойство visibility, которое можно использовать с CSS transitions, в отличие от display (что довольно странно).

See the Pen Unhover Intent in CSS by CSS-Tricks (@css-tricks) on CodePen.

С помощью JavaScript, конечно, тоже можно сделать задержку при потере курсора мыши. Для этого функция не срабатывает, пока не прошло определенное время. Это может быть реализовано при помощи добавления небольшого таймаута с setTimeout, а когда курсор возвращается снова — таймаут очищается.


var timer;

$(".parent").on("mouseover", function() {
    clearTimeout(timer);
    openSubmenu();
}).on("mouseleave", function() {
    timer = setTimeout(
        closeSubmenu
    , 1000);
});

function openSubmenu() {
    $(".submenu").addClass("open");
}
function closeSubmenu() {
    $(".submenu").removeClass("open");
}

See the Pen Unhover Intent in JS by CSS-Tricks (@css-tricks) on CodePen.

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

Избегайте узких коридоров

Нет такого правила, чтобы выпадающее меню обязательно раскрывалось в сторону. Если оно открывается непосредственно под родительским пунктом, коридор становится широким. Ниже приведен пример Тимоти М. ЛеБланка:

See the Pen Dropdown Menus by White Wolf Wizard (@WhiteWolfWizard) on CodePen.

Построение треугольников на JavaScript

Отличную статью на эту тему написал несколько лет назад Бен Кеймс (Ben Kames). Он исследовал выпадающее меню на Amazon.com, сравнивал юзабилити с другими выпадающими меню, использующими задержку. Волшебство оказалось в математике! Если курсор мыши движется под определенным допустимым углом к подменю, другие пункты меню не раскрываются. Наглядное изображение:

Бен оформил свое решение в виде плагина jQuery , демо .

Он был прав по этому поводу:

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

Это можно сказать о многих вещах в нашей сфере.

Джон Нил предложил решение без jQuery и улучшил математику с помощью «барицентрических координат»:

See the Pen Aim-Aware Menus by Jonathan Neal (@jonneal) on CodePen.

Другие проблемы

Я думаю, что мудрый человек однажды сказал:

Иногда у посетителей вашего сайта будет мышь, а иногда нет.

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

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

Рассылка
Подпишитесь на рассылку и получайте дайджест новостей и статей.
Никакого спама!
Подписаться