Быстрое, удобное, адаптивное меню для 1075 категорий (36000 товаров)

    image

    Коротко о меню


    • 99% меню HTML5 + CSS3, 1% JavaScript (закрытие открытой категории по клику).
    • На мобильных устройствах «горизонтальное» меню становится «аккордеон-меню».
    • В первичном состоянии показаны 10 основных пунктов меню из 33, остальные пункты появляются при нажатии на 11-ый (крайне правый пункт) «Ещё...».
    • «Время загрузки для взаимодействия» страницы категории с меню и товарами на компьютере 1 секунда, на мобильных 5,2 секунд (по данным developers.google.com).
    • «Время загрузки первого контента» страницы категории с меню и товарами на компьютере 0,3 секунды, на мобильных 1 секунда (по данным developers.google.com).
    • Категории меню открываются и закрываются по нажатию, после открытия символ "+" меняется на "-".
    • При открытии других пунктов меню, открытые ранее закрываются.
    • Подпункты-категорий и подпункты-подпунктов-категорий меню на desktop помещаются в область просмотра без полосы прокруток.

    Требования к меню


    • Открытие меню по нажатию… Про меню с открытием при наведении: при открытие страницы 99% людей пересечет мышкой меню, что вызовет его незапланированное появление закрыв видимую часть экрана тем самым расстроив посетителя. Решить можно включив задержку при наведении (чтоб не открывалось сразу), но тогда меню «тормозное» становится.
    • Простое меню для возможной дальнейшей корректировки сотрудниками магазина после инструктажа.
    • Меню должно быть адаптивное, страница с меню проходить полную валидацию css3 html5. Скорость загрузки страницы должна оставаться быстрой.

    Полную версию меню можно посмотреть codepen.io/andrej-sh/pen/eYOrNEZ

    Начало HTML кода


    Часть кода

    Пояснение к коду JavaScript


    Планировал обойтись без JavaScript, но реализация закрытия открытого меню при повторном нажатии на CSS мне не представилась реализуемой для radio + checkbox. А код простой и понятный и даже при его случайном удалении не способен сделать сайт не рабочим (при тестировании меню с jQuery сайт не работал 5 минут из-за того, что сперва подключил скрипт удаленно и в ссылке был http вместо https).

    <script>
    function clickRadio(el) {
      var siblings = document.querySelectorAll("input[type='radio'][name='" + el.name + "']");
      for (var i = 0; i < siblings.length; i++) {
        if (siblings[i] != el)
          siblings[i].oldChecked = false;
      }
      if (el.oldChecked)
        el.checked = false;
      el.oldChecked = el.checked;
    }</script>

    Аналогичное меню с использованием jQuery


    Первая версия меню была на jQuery, реализована через input «checkbox». Еще через скрипт было настроено появление символов "+ -" при открытии-скрытии меню. По функционалу и внешнему виду абсолютно такое же как и про меню описанному ранее. Но! скорость загрузки была заметно хуже. Например «Максимальная потенциальная задержка FID» становится больше на 1 секунду. «Время загрузки для взаимодействия» больше на 0,6-0,8 секунды. «Время загрузки первого контента» на 0,3-0,4 секунды. Скрипты грузятся на 0,5 секунды дольше.

    Изображения с сервисов проверки скорости загрузок


    Для компьютеров

    Для мобильных

    Lighthouse
    Поделиться публикацией
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама

    Комментарии 15

      +4

      Меню не закрывается при клике "вне меню". А это довольно-таки, привычная вещь для пользователей, и является неотъемленной частью UX таких меню.


      А вообще, на продакшене использовать "только css"-меню довольно затруднительно. Слишком много возможных "хотелок" приведут к переписыванию на javascript.


      А если замените дефис на минус, выглядеть будет приятнее. Кстати, Accessibility тоже надо доводить до 100%

        0
        Меню не закрывается при клике «вне меню».А это довольно-таки, привычная вещь для пользователей,..
        Полностью согласен, в планах.
        А если замените дефис на минус
        Спасибо за решение!
        Accessibility не 100% так как загрузка каталога товаров через «яндекс поиск для им» который через iframe работает, а другой вид загрузки через json еще не настроен.
          0
          Меню не закрывается при клике «вне меню».А это довольно-таки, привычная вещь для пользователей

          добавил для себя закрытие меню по клику вне меню — варианты на jquery и ванильном js — может кому еще пригодится.

          vanilla ja
          jquery

          upd. только заметил, с 7 по последний дочерние элементы первого уровня, там где подменю начинают открываться слева, клик справа от меню не закрывает открытое меню, поскольку затрагивает дочерний элемент — промежуточный список.
          Несмотря на то, что все элементы списка сдвинуты влево, пространство список занимает, поэтому надо будет доработать…
        0
        Меню — прям огонь! Шутка, конечно же. Это какой-то привет из 2000х.
        Минусы — слишком много текста, нужно слишком много прочесть, пока выберешь нужное, нужно сделать несколько кликов и не промахнуться. Кнопку «еще+» нажмет один процент, остальные просто не найдут то, что искали.
        Лучше сделать так как сделано на али, амазоне, озоне. Для того чтобы войти в нужный раздел, порой нужно пройти пару страниц. Но чисто психологически это комфортнее, чем лазить по представленной в статье менюшке, поэтому такие менюшки и померли. Такая менюшка будет работать только если человек зашел на сайт с ясным желанием, что ему нужно прямо сейчас и он знает где искать. Т.е. для какой-нибудь внутренней erp/crm будет нормально, для интернет-магазина — нет. Все сказанное ИМХО.
          +1
          jQuery какой версии?
            0
            jQuery v1.6.4
              0
              нууу… 2011 года релиз. Там еще ie7 поддерживется, конечно это старая и медленная версия.
                0
                Скачал jquery-3.4.1.min.js замеряю скорость…
                Максимальная потенциальная задержка FID теперь почти не отличается от версии меню без jquery… Разница у «Время загрузки первого контента» и «Время загрузки для взаимодействия» стали меньше…
                Спасибо что обратили внимание на версию jquery
                  0
                  можно еще jQuery slim с вырезанным ajax и эффектами, если они не используются на сайте
            +3
            1. Меню такого объема лучше делать вертикальным: нет лимита по длине, избавляет от «Ещё...», можно интуитивно сортировать и фильтровать (расположив инпут/панель фильтров над меню). Плюс это позволит выполнить пункт 2.

            2. Минимальные габариты кликабельной плашки желательно делать такими, чтобы туда влезал палец (48x48 px и более). Это очень сильно снижает количество мискликов и, след-но, отказов. На десктопе тоже! Не забывайте, что не все люди обладают точной моторикой и зрением, а с возрастом всё это проседает. Чем старше аудитория, тем критичнее размеры областей клика.

            3. В идеале меню должно управляться и табуляцией. Включая перемещение по подпунктам с клавиатуры. У нас все забивают, но в зарубежных проектах это бывает базовым требованием. Там больше доля ридеров и всяких гаджетов, поэтому все помешаны на accessibility. В разметке желательно следить за семантикой (nav), в некоторых случаях внедрятьARIA-roles и т.д.

            4. Нежелательно делать «выворотку» (светлый текст на темном фоне) для светлых тем. Контраст цветов фона и текста лучше держать повыше (примерно как у вас в выделенных пунктах).

            5. Минимальный размер шрифта сейчас желательно делать минимум 16px для десктопа, причем брать гротески а не антиквы. Для сжатых и мелких гарнитур (Pt Sans и др) размер шрифта надо брать даже чуть больше — ~18 или выше.

            6. В меню такой вложенности желательно показывать кол-во дочерних элементов и товаров, особенно если вы требуете полный клик, чтобы показать подуровень. Иначе у вас будут ситуации, когда человек делает 3-6 кликов, а в итоге оказывается в пустой или почти пустой подподкатегории, где нечего выбирать.

            7. Желательно обрабатывать не только состояние hover, но и active и pressed/selected. Т.е. меню должно чем-то реагировать на нажатие и различать текущую цепочку навигации (на какой странице находимся) от простой подсветки пунктов при их просмотре (какой пункт меню под мышкой).

            8. Не очень удачно делать два ряда горизонтальных меню друг под другом. См п.1.

            9. Про скрытие меню по клику на оверлей (вне меню) уже написали выше. В идеале ещё по клавише Esc (и «назад» на телефонах)

            10. В идеале (без прямолинейного сео) вложенность основного меню надо уменьшать до 1-2 уровней. А более глубокую рубиркацию показывать после перехода внутрь. Точкой входа в магазин почти всегда становится не главная, а внутренняя страница. Т.е. человеку, который пришел по запросу «Сантехника», выгоднее на первом же уровне (без кликов) показать Унитазы и Раковины, а не Инструмент и Краску. Верхний уровень на внутряках как раз лучше показывать по прямому запросу, то есть по клику на общую кнопку типа «Все рубрики», «Полный каталог» и т.п.

            P.S. 36k — это не настолько много) Норма для большого тематического магазина. А ведь есть ещё гипермаркеты)

            Успехов!
              0
              Спасибо за подробные идеи!
              1. Пробовал, на компьютерах очень много места занимает и далеко листать вниз. Даже если 2х уровневое делать то получается до 58 строчек 33+25 подкатегорий у нажатого пункта. Такое меню не устроило руководство.
              2. Я бы с радостью крупней меню делал, но тогда будет полоса прокрутки, а при ней люди часто нажимают рядом с меню (а в этой ситуации меню должно закрываться Пункт 9)
              3-5 согласен
              6. Возможна ситуация: человек подумает что это не количество подпунктов, а количество товаров и тогда даже не нажмет на пункт меню. А подписывать что это количество категорий грамозко. У конечных категорий вполне можно добавить количество товаров в категории.
              7-10. согласен, это очень нужно
              P.S 36к это и есть гипермаркет. У Леруа Мерлен 30-44к в зависимости от города. У нас уже 37к
              0
              В целом интересное решение.
              Думаю не повредило бы еще заблокировать выделение текста внутри пунктов меню.
                0
                Нуу даже не знаю, вроде бы уже всё давно придумано, вон теми же ситилинк и технопоинт\днс
                  0
                  nix еще держится)
                  0
                  Открытие меню по нажатию… Про меню с открытием при наведении: при открытие страницы 99% людей пересечет мышкой меню, что вызовет его незапланированное появление закрыв видимую часть экрана тем самым расстроив посетителя. Решить можно включив задержку при наведении (чтоб не открывалось сразу), но тогда меню «тормозное» становится.

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

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

                  Самое читаемое