Адаптивное меню только с помощью css3. Большой обзор красивых многоуровневых меню с codepen

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

Введение В коде, представленном в статье, я не использую браузерные префиксы, чтобы код стилей оставался простым к прочтению и пониманию. В более сложных примерах используется SCSS. Каждый из примеров размещен на сайте CodePen , где вы можете увидеть скомпилированный CSS.

Все подходы в этой статье используют простой HTML код, который я называю «базовое меню». Атрибут role используется чтобы указать определенный тип: горизонтальное меню (full-horizontal), выпадающий список (select), ниспадающее меню (custom-dropdown) и canvas.

  • Stream
  • Lab
  • Projects
  • About
  • Contact

Для стилей я использую один и тот же медиа запрос для всех вариантов:

@media screen and (max-width: 44em) { }

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

  • Stream
  • Lab
  • Projects
  • About
  • Contact

@media screen and (max-width: 44em) { nav { ul > li { width: 100%; } } }



Преимущества
  • Не требуется JavaScript
  • Никакой лишней разметки
  • Простой код стилей
Недостатки
  • Занимает слишком много места на экране
Пример горизонтального меню можно увидеть на сайте CodePen. В данном подходе скрывается базовое меню и показывается выпадающий список вместо него.

Чтобы добиться такого эффекта нам нужно добавить в базовую разметку выпадающий список. Чтобы он работал нам придется добавить JavaScript код, который изменяет значение window.location .href когда происходит событие onchange
Stream Lab Projects About Contact
Скрываем список на больших экранах:
nav { > select { display:none; } }
На маленьких экранах скрываем базовое меню и показываем выпадающий список. Чтобы помочь пользователю понять, что это меню - мы добавим псевдо-элемент с тектом «Меню»
@media screen and (max-width: 44em) { nav { ul { display: none; } select { display: block; width: 100%; } &:after { position: absolute; content: "Menu"; right: 0; bottom: -1em; } } }
С дополнительным оформлением так оно выглядит на экранах с небольшим разрешением:

Преимущества
  • Не занимает много места
  • Использует «собственные» элементы управления
Недостатки
  • Для работы требуется JavaScript
  • Происходит дублирование содержимого
  • Выпадающий список не удается стилизовать во всех браузерах
Пример этого меню .3. Пользовательское ниспадающее меню В данном подходе на небольших экранах скрывается базовое меню и показывается input и label вместо них (используется хак с чекбоксом). Когда пользователь кликает на label, базовое меню показывается под ним.
Проблемы с использованием хака с чекбоксом Две основных проблемы с этим решением:
  • Оно не работает на мобильных версиях Safari (iOS < 6.0) . Невозможно кликнуть на label в браузере под iOS < 6.0, чтобы сработал input из-за бага. Решается добавлением пустого события onclick на label
  • Оно не работает на основном браузере ОС Android версии меньше или равной 4.1.2. Давным давно, был баг в WebKit движке, который не позволял использовать псевдо-классы с комбинацией селекторов + и ~
  • H1 ~ p { color: black; } h1:hover ~ p { color: red; }
    Это не оказывало никакого эффекта, потому что хак с чекбоксом использовал псевдокласс:checked с селектором ~ . И пока баг не был исправлен в WebKit 535.1 (Chrome 13) и в актуальном для Android 4.1.2 WebKit 534.30, хак не работал ни на каком устройстве с ОС Android.

    4. Canvas В этом подходе, на небольших экранах, скрывается базовое меню и показывается input и label как в варианте 3. Когда пользователь кликает на label, базовое меню выплывает слева и содержимое перемещается вправо. Экран разделяется на части в пропорциях 80% меню и 20% содержимое (в зависимости от разрешения и единиц, используемых в CSS)


    На больших экранах мы скрываем label.
    label { position: absolute; left: 0; display: none; }
    На маленьких экранах мы помешаем меню вне содержимого окна и показываем label и input. Чтобы скрыть меню мы устанавливаем для него ширину и отрицательное значение положения. Чтобы помочь пользователю понять, чтобы это меню, мы так же добавим псевдоэлемент с текстом "≡" в label (в виде кода "\2261", чтобы использовать как содержимое псевдоэлемента).

    @media screen and (max-width: 44em) { $menu_width: 20em; body { overflow-x: hidden; } nav { position: absolute; left: -$menu_width; width: $menu_width; ul > li { width: 100%; } } label { display: block; } label:after { position: absolute; content: "\2261"; } input:checked ~ nav { left: 0; } input:checked ~ .content { margin-left: $menu_width + .5em; margin-right: -($menu_width + .5em); } }

    С дополнительным оформлением так оно выглядит на экранах с небольшим разрешением:



    ПреимуществаНедостатки
    • Не семантичный код (input / label)
    • Требуется дополнительный HTML
    • Абсолютное позиционирование элемента body вызывает ощущение зафиксированного положения
    Работает ли это под IE? Все использованные техники преследуют одну цель: создать адаптивное меню для современных браузеров! И все потому, что нет никаких IE8 или ниже ни на каких мобильных устройствах и, поэтому, мы можем совершенно не беспокоиться об этом вопросе.

    Привет. Очень давно не писал постов на тему работы html/css. Недавно как раз начал верстать новый макет и в процессе наткнулся на интересный прием, который позволяет сделать меню резиновым (в него можно будет добавлять новые пункты и размер не увеличиться, а всегда будет 100% родительского блока). Итак, сегодня реализуем на css резиновое меню.

    Кому лень читать статью, можно посмотреть это видео. Автор также все очень классно объясняет:

    Резиновое меню на CSS — шаг 1

    Первый шаг — это всегда html разметка, куда же без нее. Но в нашем случае все будет просто:

  • блок обертка для меню
  • само меню, выведенное через маркированный список (тег ul)
  • ну и пункты меню внутри, а в них, соответственно, уже ссылки
  • Все понятно, вот такой у меня код разметки:



    Выглядит это все стандартно, вот так:

    Теперь будем приводить все в нужный вид, за работу берется CSS.

    Шаг 2 — базовые стилиШаг 3 — реализуем резиновость

    Теперь беремся за само меню. У него (у тега ul) я уберу маркеры, сделаю фоновый , и, самое главное, свойством display: table-row заставлю контейнер для меню вести себя как табличный ряд. Это важно сделать для дальнейших манипуляций.

    R-menu{ background: linear-gradient(to right, #b0d4e3 0%,#88bacf 100%); display: table-row; list-style: none; }

    Как видите, приведенный код как раз решил все, о чем я писал. Кстати, градиенты удобно генерировать с помощью инструмента Ultimate CSS Gradient generator.

    R-menu li{ vertical-align: bottom; display: table-cell; width: auto; text-align: center; height: 50px; border-right: 1px solid #222; }

    • vertical-align: bottom — это свойство необходимо для того, чтобы в случае, если текст в пункте меню займет 2 строки, он отображался ровно. Когда мы сделаем меню, можете удалить это свойство, увеличить масштаб чтобы пункты сжались и текст перенесся на две строки и увидите проблему с отображением. Верните свойство и все будет нормально.
    • display: table-cell — поскольку мы задали самому меню отображения табличным рядом, логично будет задать его пунктам отображение как ячейки в таблице. Это обязательно.
    • width: auto — ширина будет вычисляться автоматически, в зависимости от длины текста в пункте
    • text-align: center — это просто для выравнивания текста внутри по центру
    • height: 50px — задаем высоту в 50 пикселей
    • ну и border-right это просто граница справа, такой разделитель для пунктов

    Пока меню выглядит неказисто, но ничего, настало время довести его до ума.

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

    R-menu li a{ text-decoration: none; width: 1000px; height: 50px; vertical-align: middle; display: table-cell; color: #fff; font: normal 14px Verdana; }

    И вот так теперь выглядит меню:

    Опять же, поясню некоторые строки:

    • свойство text-decoration отменяет подчеркивание у ссылок, которое ставится по умолчанию
    • width: 1000px — пожалуй, самая важная строка. Нужно задать ссылкам примерно такую ширину, можно и меньше, но обязательно больше максимально широкого пункта меню. Ссылки не станут в ширину 1000 пикселей, поскольку ширину ограничит пункт меню li, у которого ширина задана как auto, зато это позволит сделать так, чтобы при любом количестве пунктов в меню оно всегда было на 100 процентов ширины.
    • vertical-align: middle и display: table-cell — первое выровняет текст по вертикали по центру, а второе также делает отображение ссылок в виде ячеек. Оба свойства нужны.
    • font — ну это просто набор установок для шрифта. Читайте про css свойства для шрифтов в .
    Шаг 4 (по желанию) можно добавить интерактивности

    Например, чтобы при наведении изменялся цвет пункта меню. Реализуется это совсем просто, с помощью псевдокласса hover:

    R-menu li:hover{ background-color: #6bba70; }

    Тестируем меню на резиновость

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

    Меню осталось в ширину на 600 пикселей. Остальные пункты просто немного ужались, чтобы поместились 2 новых.

    Добавлю еще 1 длинный пункт:

    Как видите, меню еще немного ужалось и длинный пункт отобразился вполне себе нормально. А если бы не было свойства vertical-align: bottom , о котором я вам говорил, то меню выглядело бы хуже.

    Уменьшу меню до трех пунктов.

    Пунктам стало гораздо свободнее, но само меню не поменялось в ширине. Вот мы и сделали 100% резиновое меню!

    Как его адаптировать?

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

    Ну а если вы хотите как-то изменить или поправить меню на мобильных устройствах или широких экранах, то вам в помощь! Успехов в сайтостроении!

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

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


    HTML Разметка

    Перво-наперво нам необходимо выполнить разметку всей основной конструкции нашего меню. Мы создаем элемент навигации, а значит логичным и даже практичным, будет применение HTML5-элемента, тега с присвоенным ему одноименным классом, для последующего форматирования CSS стилей, а также создания и абсолютного позиционирования выпадающей навигационной панели. Класс current указывает на активную / текущую ссылку меню, внешний вид которой, сформируем с помощью css.

    • Главная
    • О Нас
    • Портфолио
    • Наши Услуги
    • Контакты

    Как видим, меню, это простой неупорядоченный список с определенным количеством ссылок. Количество пунктов может быть разным, но всё же не стоит городить огород, всё в разумных пределах.
    Далее, пока не ушли далеко, хочу напомнить, а тем кто не знает, пояснить, что HTML5 и запросы media query не поддерживается IE версии старше 9-й(совсем неудивительно). Дабы избежать головной боли в будущем и сделать всё правильно, существуют специальные скрипты и , с помощью которого, мы сможем решить задачу совместимости, предусмотрительно подключив их к документу в разделе .

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

    CSS Определяем стили

    Набор стилей CSS меню под экраны мониторов настольных компьютеров, довольно стандартный, вдаваться в подробности не вижу смысла. Хочу лишь обратить внимание, на то что я указал display:inline-block вместо float:left элемента

  • в контейнере навигации nav . Это позволит выравнивать пункты меню влево, вправо и точно по центру, указав свойство text-align элементу списка
      .

      /* меню */ .nav { margin : 20px 0 ; } .nav ul { margin : 0 ; padding : 0 ; } .nav li { margin : 0 5px 10px 0 ; padding : 0 ; list-style : none ; display : inline-block ; * display : inline ; /* ie7 */ } .nav a { padding : 3px 12px ; text-decoration : none ; color : #999 ; line-height : 100% ; } .nav a: hover { color : #000 ; } .nav .current a { background : #999 ; color : #fff ; border-radius : 3px ; }

      /* меню */ .nav { margin: 20px 0; } .nav ul { margin: 0; padding: 0; } .nav li { margin: 0 5px 10px 0; padding: 0; list-style: none; display: inline-block; *display:inline; /* ie7 */ } .nav a { padding: 3px 12px; text-decoration: none; color: #999; line-height: 100%; } .nav a:hover { color: #000; } .nav .current a { background: #999; color: #fff; border-radius: 3px; }

      За изменения цвета ссылок и фона активных/текущих пунктов меню отвечают секции.nav a:hover и.nav .current a соответственно. Я не стал особо мудрить в этом примере, всё сделал в духе минимализма, при наведении на ссылку меняется цвет, текст становится черным color: #000; , а для активных пунктов добавил фон background: #999; , заменил цвет шрифта на белый color: #fff; и чуточку закруглил края border-radius: 3px; у получившейся кнопки. Вы же можете фантазировать и экспериментировать в этом плане, сколь душе угодно.

      Выравнивание по центру и вправо

      Как я уже упоминал выше, мы можем изменять выравнивание пунктов навигации с помощью свойства text-align , для этого добавим в код CSS несколько строк:

      /* меню справа */ .nav .right ul { text-align : right ; } /* меню по центру */ .nav .center ul { text-align : center ; }

      /* меню справа */ .nav.right ul { text-align: right; } /* меню по центру */ .nav.center ul { text-align: center; }

      Адаптируем меню

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


      Будем исправлять ситуацию с помощью медиа запросов. В точке приложения медиа запроса в 600px, выставил относительное позиционирование position: relative; для элемента nav , чтобы мы смогли потом разместить список меню

        сверху в абсолютной позиции position: absolute; . С помощью свойства display: none скроем все пункты меню li , оставив только активные на текущий момент ссылки с классом current , прописав им свойство display: block
        При наведении на сгруппированную панель навигации все пункты меню должны показываться в виде выпадающего списка, для этого определяем правило.nav ul:hover li с функцией code>display: block . Для активных/текущих пунктов добавляем иконку, чтобы выделить из из остальных.
        Если необходимо сместить меню вправо или расположить по центру, воспользуйтесь left и right свойствами позиционирования для списка ul нашего меню.

        @media screen and (max-width : 600px ) { .nav { position : relative ; min-height : 40px ; } .nav ul { width : 180px ; padding : 5px 0 ; position : absolute ; top : 0 ; left : 0 ; border : solid 1px #aaa ; background : #FAFAFA url (images/icon-menu.png ) no-repeat 10px 11px ; border-radius : 5px ; box-shadow : 0 1px 2px rgba (0 , 0 , 0 , .3) ; } .nav li { display : none ; /* скрыть все
      • пункты */ margin : 0 ; } .nav .current { display : block ; /* показывать только текущие активные
      • пункты */ } .nav a { display : block ; padding : 5px 5px 5px 32px ; text-align : left ; } .nav .current a { background : none ; color : #666 ; } /* при наведении на пункты меню */ .nav ul: hover { background-image : none ; } .nav ul: hover li { display : block ; margin : 0 0 5px ; } .nav ul: hover .current { background : url (images/icon-check.png ) no-repeat 10px 7px ; } /* адаптивное меню справа */ .nav .right ul { left : auto ; right : 0 ; } /* адаптивное меню по центру */ .nav .center ul { left : 50% ; margin-left : -90px ; } }
      • @media screen and (max-width: 600px) { .nav { position: relative; min-height: 40px; } .nav ul { width: 180px; padding: 5px 0; position: absolute; top: 0; left: 0; border: solid 1px #aaa; background: #FAFAFA url(images/icon-menu.png) no-repeat 10px 11px; border-radius: 5px; box-shadow: 0 1px 2px rgba(0,0,0,.3); } .nav li { display: none; /* скрыть все

      • пункты */ margin: 0; } .nav .current { display: block; /* показывать только текущие активные
      • пункты */ } .nav a { display: block; padding: 5px 5px 5px 32px; text-align: left; } .nav .current a { background: none; color: #666; } /* при наведении на пункты меню */ .nav ul:hover { background-image: none; } .nav ul:hover li { display: block; margin: 0 0 5px; } .nav ul:hover .current { background: url(images/icon-check.png) no-repeat 10px 7px; } /* адаптивное меню справа */ .nav.right ul { left: auto; right: 0; } /* адаптивное меню по центру */ .nav.center ul { left: 50%; margin-left: -90px; } }

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

        Урок подготовлен по материалам
        Вольный перевод и адаптация: Андрей /driver/

        Хабр, привет!

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

        Раньше я их выкладывал в группе продукта облачной IDE mr. Gefest , это были сборки из 5-8 решений. Но теперь у меня стало скапливаться по 15-30 скриптов в разных тематиках (кнопки, меню, подсказки и так далее).

        Такие большие наборы следует показывать большему числу специалистов. Поэтому выкладываю их на Хабр. Надеюсь они будут Вам полезны.

        В этом обзоре мы рассмотрим многоуровневые меню.

        Flat Horizontal Navigation

        Красивая навигационная панель с плавно появляющимся подменю. Код хорошо структурирован, используется js. Судя по использованным возможностям, работает в ie8+.
        http://codepen.io/andytran/pen/kmAEy

        Material Nav Header w/ Aligned Dropdowns

        Адаптивная панель ссылок с двухколонным подменю. Все сделано на css и html. Применены css3 селекторы, которые не поддерживаются в ie8.
        http://codepen.io/colewaldrip/pen/KpRwgQ

        Smooth Accordion Dropdown Menu

        Стильное вертикальное меню с плавно раскрывающимися элементами. Используется transition, transform js-код.
        http://codepen.io/fainder/pen/AydHJ

        Pure CSS Dark Inline Navigation Menu

        Темная вертикальная навигационная панель с иконками из ionicons. Применяется javascript. В ie8 скорее всего будет работать без анимации.
        http://codepen.io/3lv3n_snip3r/pen/XbddOO

        Pure CSS3 Mega Dropdown Menu With Animation

        Стильное меню с двумя форматами вывода: горизонтальным и вертикальным. Используются иконки и css3-анимация. В ie8 точно будет ужасно выглядеть, но зато в других браузерах все круто.
        Ссылка на вертикальную: http://codepen.io/rizky_k_r/full/sqcAn/
        Ссылка на горизонтальную: http://codepen.io/rizky_k_r/pen/xFjqs

        CSS3 Dropdown Menu

        Горизонтальное меню с большими элементами и выпадающим списком ссылок. Чистый и минималистичный код без js.
        http://codepen.io/ojbravo/pen/tIacg

        Simple Pure CSS Dropdown Menu

        Простое, но стильное горизонтальное меню. Используется font-awesome. Все работает на css и html, без js. В ie8 будет работать.
        http://codepen.io/Responsive/pen/raNrEW

        Bootstrap 3 mega-dropdown menu

        Отличное решение для интернет-магазинов. Отображает несколько уровней категорий и большие изображения (например, товар по акции). В его основе лежит boostrap 3.
        http://codepen.io/organizedchaos/full/rwlhd/

        Flat Navigation

        Стильная навигационная панель с плавным подменю. В старых браузерах отобразится с проблемами.
        http://codepen.io/andytran/pen/YPvQQN

        3D nested navigation

        Горизонтальное меню с очень крутой анимацией без js!
        http://codepen.io/devilishalchemist/pen/wBGVor

        Responsive Mega Menu - Navigation

        Горизонтальное адаптивное меню. Выглядит неплохо, но мобильная версия немного "хромает". Используется css, html и js.
        http://codepen.io/samiralley/pen/xvFdc

        Pure Css3 Menu

        Оригинальное меню. С простым и чистым кодом без js. Применяйте для "вау" эффектов.
        http://codepen.io/Sonick/pen/xJagi

        Full CSS3 Dropdown Menu

        Красочное выпадающее меню с одним уровнем вложенности. Используются иконки из font-awesome, html и css.
        http://codepen.io/daniesy/pen/pfxFi

        Css3 only dropdown menu

        Достаточно неплохое горизонтальное меню с тремя уровнями вложенности. Работает без js.
        http://codepen.io/riogrande/pen/ahBrb

        Dropdown Menus

        Минималистичное меню с оригинальным эффектом появления вложенного списка элементов. Радует, что это решение тоже без javascript.
        http://codepen.io/kkrueger/pen/qfoLa

        Pure CSS DropDown Menu

        Примитивное, но эффективное решение. Только css и html.
        http://codepen.io/andornagy/pen/xhiJH

        Pull Menu - Menu Interaction Concept

        Интересный концепт меню для мобильного телефона. Я такого ещё не видел. Используется html, css и javascript.
        http://codepen.io/fbrz/pen/bNdMwZ

        Make Simple Dropdown Menu

        Чистый и простой код, без js. В ie8 точно работать будет.
        http://codepen.io/nyekrip/pen/pJoYgb

        Pure CSS dropdown

        Решение неплохое, но слишком уж много используется классов. Радует, что нет js.
        http://codepen.io/jonathlee/pen/mJMzgR

        Dropdown Menu

        Симпатичное вертикальное меню с минимальным javascript-кодом. JQuery не используется!
        http://codepen.io/MeredithU/pen/GAinq

        CSS 3 Dropdown Menu

        Горизонтальное меню с дополнительными подписями может хорошо украсить Ваш сайт. Код простой и понятный. Javascript не применяется.
        http://codepen.io/ibeeback/pen/qdEZjR

        Красивое решение с большим количеством кода (html, css и js). Придумано 3 формата подменю. Для интернет-магазинов решение хорошо подходит.
        http://codepen.io/martinridgway/pen/KVdKQJ

        CSS3 Menu Dropdowns (особенное решение)!

        Темное горизонтальное меню с тринадцатью (13) вариантами анимации! Обязательно советую ознакомиться, пригодится в быту.
        http://codepen.io/cmcg/pen/ofFiz

        П.С.
        Надеюсь, Вам понравилась сборка из 23 решений. Если хотите и дальше их читать, то пройдите снизу опрос.
        Всем приятной работы.

        Далеко не во всех проектах уместны излишние эффекты, которые могут значительно нагружать страницы, а особенно, если это касается адаптивной верстки, где пользователь может просматривать сайт на смартфонах или планшетах. Большинство таких эффектов, создаются с использованием JavaScript, поэтому, для примера, я решил показать, как можно сделать один из важнейших элементов сайта, а именно меню навигации , практически не прибегая к JS, а в основном только средствами CSS. Совсем нельзя отказаться от использования JS по той причине, что на мобильных устройствах и обычных компьютерах или ноутбуках, многие события отличаются и, если на компьютере в CSS мы можем спокойно использовать свойство :hover , то на планшете это уже не сработает так, как нам бы этого хотелось. Самые нетерпеливые, могут сразу (в примере изменяйте ширину окна браузера ).

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

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

        * { margin: 0; padding: 0; } header { background-color: #C0C0C0; } #menu { display: table; /* описание ниже */ width: 100%; border-collapse: collapse; -webkit-box-sizing: border-box; /* описание ниже */ -moz-box-sizing: border-box; /* описание ниже */ box-sizing: border-box; /* описание ниже */ } #menu ul { display: table-row; /* описание ниже */ background-color: #FFFFFF; list-style: none; } #menu ul li { display: table-cell; /* описание ниже */ border: 1px solid #999999; } #menu ul li a { display: inline-block; width: 100%; height: 50px; line-height: 50px; font-size: 1.2em; text-align: center; } #menu ul li a:hover { background-color: #990000; color: #FFFFFF; } #nav_button { display: none; width: 50px; height: 50px; font-size: 2.5em; text-align: center; background-color: #FFFFFF; border: 1px solid #949494; cursor: pointer; } @media screen and (max-width: 600px) { /* описание ниже */ #menu { display: inline-block; position: relative; width: auto; } #menu ul { display: none; position: absolute; top: 0; width: 100%; z-index: 20; } #menu ul li { display: list-item; border-top: none; } #nav_button { display: inline-block; } #menu:hover, #menu.open_nav { width: 100%; -webkit-user-select: none; /* описание ниже */ -moz-user-select: none; /* описание ниже */ -webkit-touch-callout: none; /* описание ниже */ } #menu:hover ul, #menu.open_nav ul { display: block; margin-top: 50px; } }

        На некоторые стили обращать внимание не нужно; цвет бекграунда, размер шрифта и т.д. - это только для демонстрации. А нас должны интересовать следующие свойства с их значениями:

        Display: table; Указывает, что элемент будет себя вести аналогично элементу

        display: table-row; Элемент будет себя вести, как display: table-cell; Элемент будет себя вести, как
        или box-sizing: border-box; (и с вендорными префиксами) При расчетах ширины и высоты элемента, свойства width и height, будут включать в себя значения полей (padding ) и границ (border ). Нужно для того, чтоб избежать появления горизонтальной прокрутки, т.к. без этого свойства, при ширине меню в 100%, добавится еще и толщина border , а если есть, то и padding . -webkit-user-select: none; и -moz-user-select: none; Запрещает выделять элемент или текст. Нужно для мобильной версии, чтоб избежать неувязок, когда пользователь проводит по элементам меню, вместо того, чтобы нажать на него. -webkit-touch-callout: none; Отменяет всплытие подсказки при нажатии и удержании элемента. Работает только в Chrome и Safari. Так же, как и в предыдущем свойстве, служит для отмены нежелательных действий при работе с элементом. @media (медиа-запрос) Тема довольно обширная, но если в двух словах, то указывает браузеру, какие свойства применять для определенных типов носителей или технических характеристик устройства. В нашем случае - применять для screen (экранов мониторов) и max-width: 600px (если ширина окна браузера меньше 600px).

        Самое интересное, что на этом можно было бы поставить точку, если бы мы не учитывали смартфоны, планшеты и с уверенностью сказать, что меню сделано полностью на HTML и CSS. Но придётся прибегнуть к помощи JS/jQuery, а в данном случае, раз уж решено было сделать с наименьшей нагрузкой, именно к чистому JavaScript.

        Var d = document, navBut = d.getElementById("nav_button"), // кнопка включение меню navMenu = d.getElementById("menu"); // выпадающее меню // функция определения наличия родительского элемента по ID function hasParent(el, sId){ while(el) { if (el.id == sId) return true; el = el.parentNode; } return false; } // по касанию на кнопке, добавляем класс менюшке, // который соответствует свойству в css "#menu:hover" // и разворачиваем меню navBut.addEventListener("touchstart", function(e) { e.preventDefault(); navMenu.classList.add("open_nav"); }, false); // по касанию в документе, // если событие не было на каком-нибудь элементе меню (определяем с помощью функции "hasParent"), // убираем класс "open_nav" из меню, что привод к его закрытию d.addEventListener("touchstart", function(e) { if(!hasParent(e.target, "menu")) navMenu.classList.remove("open_nav"); }, false);

        Записываем этот код в отдельный js-файл и подключаем его в самом низу страницы, перед закрывающим тегом . Теперь пару слов о кроссбраузерности... Если вы рассчитываете на Internet Explorer ниже девятой версии, то для корректной работы, нужно подключить два фиксящих скрипта внутри тега :

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

        Очень часто, особенно новички, в погоне за мнимой красочностью сайта, переполняют его лишней графикой, скриптами, которые выполняя какое-то маленькое действие, весят порой больше чем вся страница. Не впадайте в крайности и задумывайтесь о тех пользователях, которые могут заходить к вам не только с разных устройств, но еще и по низкоскоростному интернет-соединению. Успехов! ;)



        Понравилась статья? Поделиться с друзьями: