Дебаунсинг выпадающего списка (меню сайта) средствами одного CSS / Песочница / Хабр

Предыстория

Около пяти-шести лет назад я переделывал меню на рабочем сайте (не называю). Меняли меню каталога со старомодного разворачивающегося на (сейчас относительно) современное выпадающее. Меню делали горизонтальное, выпадающее вправо.

Коллега обратил мое внимание на проблему «цепляния за соседние пункты» при передвижении курсора мыши к выпавшим подпунктам меню. Он предложил решить ее так, как это было тогда сделано на сайте Амазона, и скинул мне местную статью Загадка выпадающего списка «Амазона» (где и постановка задачи и описание решения и ссылки на).

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

Я долго ждал, когда увижу, что кто-то сделал что-то подобное (и мне не придется писать на Хабр), но пока не дождался. Возможно плохо смотрел.

Проблема

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

На картинке, думаю, понятно изображено. Двигать нужно по синим стрелкам. Кратчайшее движение по красной стрелке приведет к перескоку на пункты 4 и 3. Кто хочет проверить: ссылка на jsfiddle.

Мое решение

Живой пример возможно многим пояснит лучше дальнейших слов.

Мое решение: при зависании мыши над корневым пунктом меню закрываем соседние пункты прозрачным дочерним элементом (dom-елементом) этого пункта, таким образом, чтобы на соседних элементах событие hover уже не происходило.

В примере для наглядности этот вспомогательный элемент div.unhover сделал полупрозрачным красным. В продакте, конечно, ставим ему в стиле background: transparent.

А чтобы другой корневой пункт все-таки можно было выбрать, прячем этот вспомогательный div, если курсор передвинут непосредственно на него или на выпавший блок. Но делаем это с анимацией свойства width этого вспомогательного элемента.

В общем при движении курсора к подпунктам (зеленая стрелка) эта «шторка» div.unhover плавно но быстро сворачивается ему вслед. Скорость анимации нужно подбирать по ширине меню и скорости движения мыши среднестатистического посетителя.

Чтобы не происходило осцилляций вспомогательного блока, названия корневых пунктов обернуты в span‘ы, которые при наведении получают больший z-index, чем их сестринский div.unhover.

Заключение

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

Но в последнее время даже на ведущих сайтах в лучшем случае отделываются простой задержкой переключения корневых пунктов.

Оно и понятно тач-интерфейсы основательно вышли на передний план.

Выпадающее меню — HTML и CSS — Форумы SitePoint

rimsky1 1

Вечер,

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

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

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

 
<дел>
  <дел>
    <дел>
       html">
        Логотип компании
      
    
<ул>
  • Главная
  • Службы <ул>
  • Управляемая служба печати
  • Управление документами
  • Параметры машинного финансирования
  • Ремонт и поддержка машин
  • Продукты <ул>
  • Машины
  • Ricoh
  • Лексмарк
  • Konica Minolta
  • Программное обеспечение
  • Кофакс
  • Вырезка из бумаги
  • Файлстар
  • Свяжитесь с нами
  • <кнопка> <я> Меню
     * {
      box-sizing: граница-коробка;
      маржа: 0;
      заполнение: 0;
    }
    тело {
      цвет фона: #242424;
      семейство шрифтов: 'proxima-nova', без засечек;
      вес шрифта: 100;
      стиль шрифта: обычный;
      размер шрифта: 16px;
      высота строки: 1,5 бэр;
    }
    ли {
      тип стиля списка: нет;
    }
    а {
      текстовое оформление: нет;
      цвет: наследовать;
    }
    . Панель навигации {
      цвет фона: #ffffff;
      набивка: 2рем 1рем;
      положение: родственник;
      box-shadow: rgba(14, 30, 37, 0.12) 0px 2px 4px 0px, rgba(14, 30, 37, 0.32) 0px 2px 16px 0px;
    }
    .навигационный элемент {
      дисплей: гибкий;
      выравнивание содержимого: пробел между;
      выравнивание элементов: по центру;
    }
    .логотип изображения {
      ширина: 10рем;
      дисплей: блок;
    }
    .navigation-bar-toggle {
      набивка: 1рем;
      цвет фона: #ecf0f1;
      цвет: наследовать;
      курсор: указатель;
      преобразование текста: верхний регистр;
      граница: нет;
      шрифт: наследовать;
      радиус границы: 0,25 бэр;
    }
    .navigation-bar-dropdown {
      дисплей: гибкий;
      flex-направление: столбец;
    }
    .navigation-bar-menu {
      flex-направление: столбец;
      справа: 0;
      переполнение: скрыто;
      верх: 100%;
      фон: #ecf0f1;
      дисплей: нет;
      положение: абсолютное;
      ширина: 100%;
    }
    .navigation-bar-menu .active {
      цвет фона: #242424;
      цвет: #ffffff;
      вес шрифта: 300;
    }
    .navigation-bar-menu li {
      дисплей: гибкий;
      выравнивание содержимого: по центру;
      набивка: 1рем;
    }
    .
    navigation-bar-menu a { преобразование текста: верхний регистр; } .навигационная панель a:hover { непрозрачность: 1 !важно; } .navigation-bar-menu: не (.active): наведите курсор { цвет фона: #242424; цвет: #ffffff; непрозрачность: 1; имя-анимации: fadeInOpacity; количество итераций анимации: 1; функция синхронизации анимации: легкость; продолжительность анимации: 500 мс; } .navigation-bar-menu.open { дисплей: гибкий; } Только экран @media и (минимальная ширина: 700 пикселей) { /* ПАНЕЛЬ НАВИГАЦИИ */ .navigation-bar-toggle { дисплей: нет; } .navigation-bar-menu { дисплей: гибкий; flex-направление: строка; положение: родственник; фон: нет; оправдать-содержание: конец; ширина: авто; зазор: 1бэр; } .navigation-bar-menu li { цвет фона: #ecf0f1; радиус границы: 0,25 бэр; набивка: 1рем; } }
     window.addEventListener('DOMContentLoaded', () => {
      const menuToggler = document.querySelector('.navigation-bar-toggle')
      const menu = document.
    querySelector('.navigation-bar-menu') menuToggler.addEventListener('щелчок', () => { menu.classList.toggle('открыть') }) })

    ПолОБ 2

    Привет,

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

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

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

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

    Надеюсь, это все равно поможет

    1 Нравится

    rimsky1 3

    Привет, Пол

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

    Спасибо за вашу помощь, если вам когда-нибудь понадобится кофе £, дайте мне ссылку.

    1 Нравится

    система Закрыто 4

    Эта тема была автоматически закрыта через 91 день после последнего ответа. Новые ответы больше не допускаются.

    DHTML-скрипты Dynamic Drive — раскрывающееся меню Flex Level

    Версия 2.0 (16 апреля 2015 г.) : Добавляет оверлейная версия активированного меню в мобильных браузерах и браузерах с маленькими экранами. Улучшает поведение выпадающего меню, когда нет места ни справа, ни слева для размещения подменю; в этом case подменю перекрывает родительское меню. Требуется jQuery 1.8+

    Описание: Более надежный, чем обычный строка меню, этот гибкий сценарий меню позволяет добавить многоуровневое раскрывающееся меню к любой ссылке на странице. Близкий родственник всплывающего меню Flex Level, каждый меню может быть либо выпадающим, либо справа от элемента привязки (полезно, когда ссылка является боковой панелью). Меню разумно перемещаются когда слишком близко к краям браузера. По структуре каждое выпадающее меню просто определяется как обычный вложенный UL на странице, что делает его очень удобным. интуитивно понятен в настройке, не говоря уже о дружественности к поисковым системам. Давайте запустить функции скрипта:

    • Позволяет связать многоуровневое раскрывающееся меню с любой ссылкой на странице путем вставки пользовательского атрибута . "данные-flexmenu" внутри ссылки.
    • Контролируйте, выпадает ли меню вниз или справа от ссылки привязки, с помощью пользовательского атрибута "data-dir" .
    • Возможность тонкой настройки положения выпадающего меню относительно .anchor, указав собственное смещение по осям x и y с помощью атрибута "смещения данных" .
    • Каждое выпадающее меню просто определяется как обычное, скрытое вложенный UL на странице. Также поддерживает динамическое определение с использованием JavaScript.
    • Меню трансформируется в наложенное меню, когда пользователь экран устройства или браузера меньше определенной ширины, что обеспечивает плавное опыт независимо от размера экрана. функция v2.0
    • Главное меню и подменю перемещаются, когда находятся слишком близко к правому или нижнему краю экрана. окно браузера, чтобы они оставались в поле зрения.
    • Возможность настройки скорости анимации расширения.
    • Возможность указать задержку перед каждым меню и его подпунктами меню появляются/исчезают при наведении и выходе из них мышкой.
    Раскрывающееся меню:

    Dynamic Drive

    Перетащите вправо, с пользовательским смещением 8 пикселей по горизонтали, 0 пикселей по вертикали, добавлено:

    Ресурсы для веб-мастеров


    Направления

    Шаг 1: Этот сценарий использует три внешних файла, включая изображение. Загрузите их ниже (щелкните правой кнопкой мыши и выберите «Сохранить как»):

    • flexdropdown.js
    • flexdropdown.css
    • Два изображения:

    Шаг 2: Вставьте следующее код в разделе вашей страницы:

    Выбрать все

    Шаг 3:  Добавьте приведенный ниже код меню в раздел BODY вашей страницы, который содержит две произвольные якорные ссылки и их соответствующие выпадающие меню:

    Выбрать все

    Раскрывающееся меню:

    Динамический привод

    Перетащите вправо, с пользовательским смещением 8 пикселей по горизонтали, 0 пикселей по вертикали, добавлено:

    Ресурсы для веб-мастеров

    Ну вот и все по установке. Подробнее о настройке читайте далее Раскрывающийся список уровней гибкости меню.

    Базовая информация о настройке

    Определить и добавить выпадающее меню Flex к ссылке достаточно просто. Во-первых, определить сами выпадающие меню в любом месте страницы, каждое из которых должно быть обычным Список UL , вложенные, если вы хотите несколько уровней. Например:

    <ул. id=" flexmenu1 «>

  • Элемент 1a

  • Элемент 2a
  • Папка элементов 3a


  • Подпункт 4a

  • Папка элементов 5a


  • Элемент 6a

  • Обратите внимание, что меню UL имеет уникальный идентификатор и класс CSS « flexdropdownmenu ». Это необходимо. Атрибут ID может быть произвольным, но уникальным по значению.

    Когда раскрывающееся меню определено, чтобы связать его со ссылкой на странице, просто вставьте атрибут « data-flexmenu «внутри него указывает на ID нужного выпадающего меню:

    data-flexmenu =»flexmenu1″>Динамический диск

    Вот и все. Теперь при наведении курсора мыши на ссылку «Динамический привод» выше показать выпадающее меню с идентификатором « flexmenu1 «.

    Вместо того, чтобы определять ваши гибкие меню как UL буквально на странице, вы можете также делайте это динамически, используя JavaScript, например, внутри внешнего .js файл. См. «Динамическое применение flex меню на ссылку, определяющую содержимое гибкого меню» для получения дополнительной информации.

    Настройка направления раскрывающегося меню, пользовательские смещения

    Поведение по умолчанию каждого выпадающего меню должно отображаться под якорем. ссылка без дополнительного смещения x или y. Вы можете изменить оба этих аспекта со следующими двумя пользовательскими необязательными атрибутами, которые вставляются внутри ваша якорная ссылка точно так же, как « data-flexmenu »:

    • data-dir : введите « h » чтобы меню выпадало горизонтально или справа от привязки связь. Это обычно полезно для якорных ссылок боковой панели, которые расположены в самый левый или правый столбец на странице. Значение по умолчанию: « в «, который должен опуститься.
    • смещения данных : введите два числа в формате [x,y] для указать смещение x и y выпадающего меню относительно его нормального позиция. Значение по умолчанию: [0,0] . Например, скажем, вы хотите переместить выпадающее меню на 5 пикселей вправо и на 3 пикселя вниз- введите значение [5,3] .

    Следующее приводит к тому, что выпадающее меню перемещается на 2 пикселя вниз от его позиция по умолчанию:

    dynamicdrive.com» data-flexmenu=»flexmenu1″ data-offsets=»[0,3]»>Динамический диск

    Другие глобальные настройки

    Внутри flexdropdown.js также есть несколько переменных, которые вы, возможно, захотите редактировать, которые влияют на такие вещи, как полный путь изображения стрелки, анимация скорость плюс задержка перед появлением/исчезновением меню при наведении мыши:

    arrowpath: ‘arrow.gif’, //полный URL-адрес или путь к изображению со стрелкой вправо
    backarrowpath: ‘left.gif’, //полный URL-адрес или путь к изображению со стрелкой назад (внутри мобильного меню)
    animspeed: 200, // показать скорость анимации (в миллисекундах)
    showhidedelay: [150, 150], // задержка перед появлением и исчезновением меню при нажатии мыши прокручивает его, в миллисекундах
    mobilemediaquery: «screen and (max-width: 800px)», // строка медиа-запроса CSS что при совпадении активирует мобильное меню (скрывая значение по умолчанию)

    Стилизация активной ссылки привязки и родительской привязки LI

    Всякий раз, когда вы наводите указатель мыши на якорную ссылку, чтобы открыть ее раскрывающееся меню, скрипт временно добавляет класс CSS » выбрал » на якорную ссылку. Это дает вам возможность легко стилизовать якорную ссылку во время ее активного состояния. с помощью CSS. Учитывая следующую якорную ссылку для выпадающего меню Flex:

    Динамический Диск

    Чтобы применить желтый фон к ссылке, когда ее раскрывающееся меню открыто, вы можете просто сделать следующее внутри своего CSS:

    a.selected{
    фон: желтый;
    }

    Или, чтобы быть более конкретным в вашем таргетинге, вместо этого введите следующее:

    a[data-flexmenu=»flexmenu1″].selected{
    фон: желтый;
    }

    Внутри раскрывающегося меню скрипт также добавляет класс CSS « selected ». к родительскому LI UL мышь в настоящее время находится над. Это позволяет вам «подсветить» текущий выбранный элемент LI. Чтобы настроить этот «выбранный» класс, внутри flexdropdown.css найдите и отредактируйте следующую часть, выделенную жирным шрифтом:

    .flexdropdownmenu li a:hover, . flexdropdownmenu li.selected>a {
    background: #F0CE7D;
    }

    Настройка мобильной части меню

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


    Скриншот: Меню в мобильном режиме

    Вместо обычного выпадающего меню в его место поверх наложения. Щелчок за пределами меню закрывает его.

    — Установка мобильного порога

    Вам нужно установить порог, когда пользователь среда считается «мобильной», поэтому мобильная версия меню активирован. Внутри flexdropdown.js, изменить строку:

    mobilemediaquery: «экран и (max-width: 600px)», // Строка медиа-запроса CSS, которая при совпадении активирует мобильное меню (при этом скрывает значение по умолчанию)

    Часть, выделенная красным, должна быть действительной Медиа-запрос CSS для соответствия при переключении меню на мобильную версию. Ниже приведены некоторые примеры допустимых медиа-запросов CSS: 9.0005

    • экран и (макс. ширина: 600 пикселей)  //когда браузер ширина 700 пикселей или меньше, настольный компьютер или мобильный телефон
    • экран и (max-device-width: 480px)  //когда ширина устройства составляет 480 пикселей или меньше, что обычно означает только для мобильных устройств. среды
    • экран и (максимальная ширина устройства: 480 пикселей) и (ориентация: книжная) // когда ширина устройства 480 пикселей или меньше и только в портретном режиме

    Чаще всего приходится принимать решение о том, использовать ли максимальная ширина или max-device-width — первое означает, что установленное значение применяется к обоим настольных и мобильных браузерах, в то время как последний ограничивает результирующее совпадение только мобильные устройства, а настольные браузеры всегда отображают обычное меню.

    ВАЖНО: Ваша страница должна содержать META-тег в разделе HEAD вашей страницы, чтобы обеспечить лучший мобильный опыт с этим меню.

    Автор записи

    Добавить комментарий

    Ваш адрес email не будет опубликован. Обязательные поля помечены *