Подходы к реализации адаптивного меню

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

Статья: http://habrahabr.ru/post/159359/
Автор перевода: druf
Оригинал: http://css-tricks.com/responsive-menu-concepts/

Введение

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

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

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

1. Горизонтальное меню

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

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

Преимущества

  • Не требуется JavaScript
  • Никакой лишней разметки
  • Простой код стилей

Недостатки

  • Занимает слишком много места на экране

Пример горизонтального меню можно увидеть на сайте CodePen.

2. Выпадающий список

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

Чтобы добиться такого эффекта нам нужно добавить в базовую разметку выпадающий список. Чтобы он работал нам придется добавить JavaScript код, который изменяет значение window.location.href когда происходит событие onchange

Скрываем список на больших экранах.

На маленьких экранах скрываем базовое меню и показываем выпадающий список. Чтобы помочь пользователю понять, что это меню — мы добавим псевдо-элемент с тектом «Меню»

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

Преимущества

  • Не занимает много места
  • Использует «собственные» элементы управления

Недостатки

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

Пример этого меню.

3. Пользовательское ниспадающее меню

В данном подходе на небольших экранах скрывается базовое меню и показывается input и label вместо них (используется хак с чекбоксом). Когда пользователь кликает на label, базовое меню показывается под ним.

Проблемы с использованием хака с чекбоксом

Две основных проблемы с этим решением:

  1. Оно не работает на мобильных версиях Safari (iOS < 6.0). Невозможно кликнуть на label в браузере под iOS < 6.0, чтобы сработал input из-за бага. Решается добавлением пустого события onclick на label
  2. Оно не работает на основном браузере ОС Android версии меньше или равной 4.1.2. Давным давно был баг в WebKit движке, который не позволял использовать псевдо-классы с комбинацией селекторов + и ~

Это не оказывало никакого эффекта, потому что хак с чекбоксом использовал псевдокласс :checked с селектором ~. И пока баг не был исправлен в WebKit 535.1 (Chrome 13) и в актуальном для Android 4.1.2 WebKit 534.30, хак не работал ни на каком устройстве с ОС Android.

Лучшее решение — это использовать анимацию только для WebKit-браузеров для тега <body>

Комбинация всех вариантов создает расширенный хак для чекбоксов:
Для больших экранов мы скрываем label:
Для небольших экранов мы скрываем базовое меню и показываем label. Чтобы помочь пользователю понять, чтобы это меню, мы добавим псевдоэлемент с текстом «≡» в label (представим в виде кода «\2261″, чтобы использовать как содержимое псевдоэлемента). Когда пользователь кликает на input, базовое меню показывается и список элементов раскрывается во всю ширину.

Так меню выглядит на маленьких экранах:

Закрытое
Закрытое

Преимущества

  • Не занимает много места в закрытом состоянии
  • Целиком стилизуется
  • Не требует JavaScript

Недостатки

  • Не семантичный код (input / label)
  • Требуется дополнительный HTML

Пример работы этого меню.

4. Canvas

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

На больших экранах мы скрываем label.

На маленьких экранах мы помешаем меню вне содержимого окна и показываем label и input. Чтобы скрыть меню мы устанавливаем для него ширину и отрицательное значение положения. Чтобы помочь пользователю понять, чтобы это меню, мы так же добавим псевдоэлемент с текстом «≡» в label (в виде кода «\2261″, чтобы использовать как содержимое псевдоэлемента).

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

Закрытое
Открытое

Преимущества

  • Не занимает много места в закрытом состоянии
  • Целиком стилизуется
  • Не требует JavaScript
  • Работает как Facebook / Google+ приложения

Недостатки

  • Не семантичный код (input / label)
  • Требуется дополнительный HTML
  • Абсолютное позиционирование элемента body вызывает ощущение зафиксированного положения

Пример этого меню.

Работает ли это под IE?

Все использованные техники преследуют одну цель: создать адаптивное меню для современных браузеров! И все потому, что нет никаких IE8 или ниже ни на каких мобильных устройствах и, поэтому, мы можем совершенно не беспокоиться об этом вопросе.