Открыть меню    

Адаптивное меню

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

Три из них основаны на чистом CSS, одна техника содержит немного javascript.

До того как начать

В коде для статьи не используются вендорные префиксы, это сделано для лучшего понимания CSS. Более сложные примеры на CSS представлены в SCSS.

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

<nav role="">
  <ul>
    <li><a href="#">Stream</a></li>
    <li><a href="#">Lab</a></li>
    <li><a href="#">Projects</a></li>
    <li><a href="#">About</a></li>
    <li><a href="#">Contact</a></li>
  </ul>
</nav>?

Для экранов с маленьким разрешением я буду использовать media query .

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

}

Полностью горизонтальное адаптивное меню

Наиболее простой путь, так как для маленьких экранов мы всего лишь сделаем у элементов полную ширину.

HTML

<nav role="full-horizontal">
  <ul>
    <li><a href="#">Stream</a></li>
    <li><a href="#">Lab</a></li>
    <li><a href="#">Projects</a></li>
    <li><a href="#">About</a></li>
    <li><a href="#">Contact</a></li>
  </ul>
</nav>

CSS

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

    .first nav[role="full-horizontal"] ul > li {
    width: 100%;
    }

    }

На экранах с большим разрешением:

горизонтальное адаптивное меню на большом экране

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

горизонтальное адаптивное меню на маленьком экране

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

  1. отсутствует javascript
  2. Простой CSS и HTML

Недостатки:

  1. Резервирует под себя много пространства

Адаптивное меню: "Выборка"

Концепция построена так: на маленьких экранах основное меню скрывается и показывается выпадающий список.

Чтобы добиться такого эффекта, нам нужно расширить базовую HTML-структуру и добавить код для выпадающего списка. Также потребуется код javascript, который по событию onchange тега select будет менять window.location на текущее значение атрибута value .

HTML

<nav role="select">
  <!-- basic menu goes here -->

  <select onchange="if (this.value) window.location.href = this.value;">
    <option value="#">Stream</option>
    <option value="#">Lab</option>
    <option value="#">Projects</option>
    <option value="#">About</option>
    <option value="#">Contact</option>
  </select>
</nav>

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

CSS

  .second nav[role="select"] > select {
    display: none;
    }

На маленьких экранах мы скроем основное меню и откроем выпадающий список. Чтобы помочь пользователю распознать наше меню добавим псевдо-элемент с текстом "меню".

CSS

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

    nav[role="select"] ul {
    display: none;
    }

    nav[role="select"]:after {
    position: absolute;
    z-index: -1;
    content: "Menu";
    right: 0;
    bottom: -1.75em;
    background: rgba(174, 86, 168, 0.4);
    padding: .15em .55em;
    }

    nav[role="select"] select {
    display: block;
    user-select: none;
    cursor: pointer;
    width: 100%;
    padding: .55em .45em;
    border: none;
    background-color: rgba(174, 86, 168, 0.25);
    font: 1.2em 'Exo', sans-serif;
    }
    }

Вот как это выглядит на маленьком экране со стилями используемыми в статье:

адаптивное меню - выборка

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

  1. Не требуется много пространства
  2. Нативные элементы управления

Недостатки:

  1. Требуется javascript
  2. Дублируемый контент
  3. Чтобы стилизовать select потребуется приложить усилия

Обычный раскрывающийся список

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

HTML

<nav role="custom-dropdown">
    <!-- Advanced Checkbox Hack (see description below) -->

    <!-- basic menu goes here -->
</nav>

Проблемы, связанные с checkbox hack

Существуют две проблемы с настройками checkbox hack:

  1. Не работает на мобильных версиях Safari (IOA < 6). Невозможно кликом по label переключить input из-за бага. Чтобы решить это проблему необходимо элементу label добавить пусть onclick .
  2. Не работает в браузере Android (Android <= 4.1.2). Одно время у webkit присутствовал баг, суть которого в том, что родственный комбинатор, или смежный комбинатор, не мог работать в связке с псевдоклассом.

CSS

h1 ~ p { color: black; }
h1:hover ~ p { color: red; }

Поэтому не добьемся никакого эффекта, используя псевдокласс :checked совместно с родственным комбинатором. Баг был исправлен в WebKit 535.1 (Chrome 13) и в WebKit для Android 4.1.2 is 534.30.

Лучшее решение использовать фейковую анимацию для тега body .

Собирая все вместе воедино, мы получим расширенный checkbox hack:

HTML

<!-- Fix for iOS -->
<input type="checkbox" id="menu">
<label for="menu" onclick></label>

CSS

/* Fix for Android */
body {
  -webkit-animation: bugfix infinite 1s;
}
@-webkit-keyframes bugfix {
  from { padding: 0; }
  to { padding: 0; }
}

/* default checkbox */
input[type=checkbox] {
  position: absolute;
  top: -9999px;
  left: -9999px;
}

label {
  cursor: pointer;
  user-select: none;
}

Для больших экранов скрываем элемент label :

CSS

nav[role="custom-dropdown"] label {
    display: none;
    }

Для экранов с маленьким разрешением мы скрываем основное меню и открываем label . Чтобы помочь пользователю опознать меню, добавим псевдоэлемент с текстом = (в качестве значения для content будем использовать код “ \2261 ”). Когда пользователь кликает по элементу label то открывается меню, причем ширина элементов меню равна 100%.

CSS

 nav[role="custom-dropdown"] label {
    position: relative;
    display: block;
    width: 100%;
    }
    nav[role="custom-dropdown"] label:after {
    position: absolute;
    content: "\2261";
    }
    nav[role="custom-dropdown"] input[type=checkbox]:checked ~ ul {
    display: block;
    }
    nav[role="custom-dropdown"] input[type=checkbox]:checked ~ ul > li {
    width: 100%;
    }
    nav[role="custom-dropdown"] input[type=checkbox]:checked ~ ul > li:after {
    position: absolute;
    content: "\203A";
    }
    }

В закрытом состоянии:

Адаптивное меню - Обычный раскрывающийся список

В открытом состоянии:

Адаптивное меню - Обычный раскрывающийся список - в открытом состоянии

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

  1. Не занимает много места в закрытом состоянии
  2. Не используется javascript
  3. Элементы полностью стилизуются

Недостатки:

  1. Плохая семантика (input/html)
  2. Дополнительный HTML

Canvas

Базовая идея та же: на экранах с маленьким разрешением скрываем основное меню и вместо него показываем элементы input и label (как их использовать смотрите в пункте 3 и checkbox hack). Когда пользователь кликает по label , основное меню "выплывает" с левой стороны , а контент смещается вправо.

HTML

<input type="checkbox" id="menu">
<label for="menu" onclick></label>

<!-- basic menu goes here -->

<div class="content">
  <!-- content goes here -->
</div>

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

CSS

label {
  position: absolute;
  left: 0;
  display: none;
}

На маленьких экранах мы прячем основное меня за пределами окна браузера и показываем label / input . Скрытие происходит за счет абсолютного позиционирования и отрицательного значения для свойства left . Чтобы помочь пользователю опознать меню, добавим псевдоэлемент с текстом = (в качестве значения для content будем использовать код “ \2261 ”). Когда пользователь кликает по label , отрицательное значение у свойства left блока с меню обнуляется, за счет чего меню выдвигается вправо и одновременно с этим смещаем контент при помощи правого поля.

CSS

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

    .four {
    margin: 0;
    overflow-x: hidden;
    }

    nav[role="off-canvas"] {
    left: -20em;
    width: 20em;
    }

    nav[role="off-canvas"] ul > li {
    width: 100%;
    }

    label {
    display: block;
    }


    label:after {
    position: absolute;
    content: "\2261";
    }

    input:checked ~ nav[role="off-canvas"] {
    left: 0;
    }


    input:checked ~ nav[role="off-canvas"] ul > li:after {
    position: absolute;
    right: .25em;
    content: "\203A";
    }

    input:checked ~ .content {
    margin-left: 20.5em;
    margin-right: -20.5em;
    }
    }

На маленьких экранах в закрытом состоянии:

адаптивное меню - canvas - в закрытом состоянии

На маленьких экранах в открытом состоянии:

адаптивное меню - canvas - в открытом состоянии

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

  1. Не занимает много места в закрытом состоянии
  2. Не используется javascript
  3. Элементы полностью стилизуются
  4. Договоренность с Facebook / Google+ app

Недостатки:

  1. Плохая семантика (input/html)
  2. Дополнительный HTML
  3. Абсолютное позиционирование относительно body практически идентично фиксированному положению.

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

По материалам статьи адаптивное меню, концепция

Комментарии к статье

аватарка пользователя
2016-09-18
максим

плохо работает все примеры

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

аппарат для plasmolifting в косметологии