Поліпшене переміщення мишки по пунктах меню

2

Від автора: Якщо говорити про інтерфейсу досвіді взаємодії, то дана концепція є досить давньою, і я якийсь час про неї не чув, але вона все одно залишається актуальною у випадку з багаторівневими випадними меню. Такий дрібний покажчик, як курсор миші, іноді доводиться переміщати в досить обмеженому й вузькому просторі, щоб дістатися до потрібного пункту в випадаючому меню. Дуже легко збитися з шляху» (коли курсор миші виходить за межі активної області), і ви тут же будете покарані за це, т. к. випадаюче меню закриється. Мабуть, ми можемо поліпшити цей процес.

Поліпшене переміщення мишки по пунктах меню

Ви можете дістатися до потрібного вам пункту меню, але доведеться переміщати курсор миші за досить вузьким областям меню.

Поліпшене переміщення мишки по пунктах меню

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

Стандартний CSS підхід

Випадаючі меню зазвичай створюються з розрахунком на те, що підменю буде з’являтися при наведенні (CSS стан :hover) на батьківський елемент. Або коли відбувається спрацьовування подій mouseenter / mouseover в JavaScript і зміна стану. Таким чином весь трюк полягає в спробі зробити так, щоб ці умови не можна було надто легко виконати. Тобто потрібно розширити активні області меню.

Основна причина, з якої я став міркувати про це, полягає в наявності дуже вузьких областей підменю в головному меню на сайті CodePen. Щоб розширити активні області у вузьких місцях, я додав кілька псевдо-елементів підменю. Якщо курсор миші потрапляє на псевдо-елементи, то нічого не відбувається, як ніби курсор знаходиться в рамках підменю, як і повинно бути.

Поліпшене переміщення мишки по пунктах меню

Червоним кольором виділені місця, де розташовані псевдо-елементи.

Це дуже проста техніка, що вимагає тільки використання CSS, і це мені подобається. Невелика небезпека полягає в тому, що ви можете захопити порядна кількість місця, відведеного під сусідні пункти меню. А це означає, що користувач не зможе при наведенні клікнути по потрібного пункту меню. Я уявляю величезна кількість випадків, коли потрібно всього лише трохи змістити курсор миші в бік, і все б запрацювало, але це безумовно балансування між крайнощами (занадто багато, занадто мало).

Історія сягає корінням у далекий 2005 рік до класичного демо-наприклад Позиціонування — це Все:

Поліпшене переміщення мишки по пунктах меню

А також, можливо, до демо-наприклад Тьєррі Кобленц (Thierry Koblentz).

Розширення CSS кордонів

Джон Гарднер (John Gardner) розробив підхід, в якому все меню мають додатковий вільний простір навколо себе, яке дозволить здійснювати безболісний вихід за рамки самого меню:

Поліпшене переміщення мишки по пунктах меню

Намір навести курсор миші

Ви коли-небудь чули про «намір навести курсор миші» («hover intent»)? Це така концепція, яка полягає в тому, що ви не відразу видаєте результат у відповідь на спрацювання подій, пов’язаних з переміщенням курсору миші. Ви вичікуєте частку секунди, щоб таким чином переконатися в тому, що користувач дійсно хоче отримати реакцію на свої дії. Це як навмисна затримка. Вона використовується в ситуаціях, коли користувальницький інтерфейс може працювати дуже нестабільно при її відсутності.

В якості протилежного боку ми можемо виділити «намір відвести курсор миші». Тобто, наприклад, ми відразу реагуємо на подію при наведенні, але трохи затримуємо реакцію, коли відбувається відведення курсору миші. В CSS можна прописати наступне:

.submenu {
visibility: hidden;
transition: 0.2 s 1s; /* затримка в 1 секунду при відведенні курсору миші */
}
.parent:hover .submenu {
visibility: visible;
transition-delay: 0s; /* негайна реакція при наведенні */
}

Зверніть увагу на те, що ми використовуємо властивість visibility, яке можна використовувати для переходів, на відміну від властивості display (що досить дивно).

JavaScript також здатний реалізувати концепцію «наміри відвести курсор миші». Тут ви можете підійти до цього з точки зору «функції з затримкою» (debounce), коли ви будете викликати функції, що виконують закриття, не відразу, а тільки через якийсь час. Це можна реалізувати, використовуючи функцію 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»);
}

Ні в одному з цих демо-прикладів не показано рішення проблеми шляхом збільшення розміру. У даних прикладах користувачеві «прощається» швидке відхилення від наміченого шляху.

Уникайте вузьких областей

Не існує такого правила, що підменю повинні розкриватися в бік від випадаючого меню. Якщо підменю будуть розкриватися відразу під потрібним пунктом меню, то активна область залишиться широкою. Ось приклад від Тімоті М. ЛеБланк (Timothy M. LeBlanc):

Нове рішення з трикутником на JavaScript

Нещодавно Бен Кеймс (Ben Kames) написав чудовий пост на дану тему. Він перевіряв, наскільки дотепно були зроблені випадають меню на сайті Amazon.com порівняно з іншими випадними меню, для яких застосовувалися техніки з тимчасовою затримкою для поліпшення юзабіліті. Виявилося, що вся магія криється в математиці! Якщо курсор переміщається під допустимим кутом у напрямку до тільки що відкрився підміню, то це не буде викликати реакції з боку інших пунктів меню. Візуально це виглядає ось так:

Поліпшене переміщення мишки по пунктах меню

Бен створив з цього jQuery плагін. Ви також можете подивитися демо-приклад.

Він також безумовно правий в цьому: «Я впевнений, що дана проблема була вирішена вже багато років тому, потім забута, потім знову виявлена, потім вирішена, а потім знову забута і т. д.»

І це сумна правда, стосується багатьох аспектів у нашому ремеслі. Джон Ніл (Jon Neal) зробив спробу позбавитися від jQuery залежності і покращити математичні обчислення, використовуючи «барицентричні координати» («barycentric coordinates»):

Інші думки по темі

Думаю, що один мудрий чоловік якось сказав: «Іноді у відвідувачів вашого сайту буде мишка, а іноді – ні».

Отже, будемо сподіватися на те, що ваші випадають меню працюють на пристроях з тач-екранами. Ви безумовно можете зробити так, щоб це було правдою! Ви вчините правильно, якщо захочете зібрати весь ваш код разом з метою підвищення ефективності або будете завантажувати скрипти і стилі тільки при необхідності завдяки визначенню можливостей (або і те й інше одночасно).

Доступність навігації з клавіатури є ще однією класичною проблемою випадаючих меню. Мені просто не хочеться, щоб ви думали, що, вирішивши проблему з переміщенням курсору миші, вам більше нічого не доведеться робити для поліпшення користувацького досвіду взаємодії при роботі з випадними меню. Завжди є можливість поліпшити!