CSS реализация меню без использования <canvas>.

Перевод статьи:  Off Canvas Menu with css target.
Автор:  Chris Coyier.

«Off Canvas» шаблоны представляют собой различные способы реализации макета документа в случаях, когда ширина вертикальной колонки не позволяет вместить необходимый контент. К примеру, панель навигации может быть скрыта за левой гранью видимой области окна браузера и выдвигаться при необходимости. Разработчик Антони Коланжело создал jPanelMenu реализующее как раз такой случай. А Хаким Хаттаб представил более экстравагантный его вариант, но практически с тем же результатом.

В обоих случаях используется JavaScript. Я подумал, не плохо было бы попробовать реализовать jPanelMenu Антони исключительно средствами CSS. И это действительно возможно, хотя данный подход кроме определенных преимуществ имеет и недостатки.

Изображение.

Две колонки, одна из которых сжимается.

Технически, разметка нашего меню состоит из двухколончатого макета. Но по умолчанию левая колонка имеет 0% ширины, а правая 100%. Левая колонка, собственно, и представляет меню, которое мы намереваемся открыть при необходимости. Здесь используется свойство overflow и при установке его значения в hidden, полностью скрывается содержимое колонки, то есть меню.

<!—- эта колонка сжата по умолчанию —>
<nav id="main-navigation" class="navigation">
<a href="#">Nav Links</a>
<!—- другие ссылки —>
</nav>

<!—- эта колонка занимает всю область по умолчанию —>
<div class="page-wrap">
<header>
<a href="#main-navigation">Menu</a>
<h1>Title</h1>
</header>

<!—- контент —>
</div>

.navigation {

/* сжимаем */
width: 0;

overflow: hidden;
position: fixed;
top: 0;
left: 0;
height: 100%;
}

/* контент */

.page-wrap {
width: 100%;
float: right;
}

Используем :target для открытия меню.

Обратите внимание на эту ссылку:

<a href="#main-navigation">Menu</a>

Якорь которой соответствует вот этому идентификатору:

<nav id="main-navigation" class="navigation">

Здесь имеет место обычная хэш ссылка (которая применяется для реализации меню с использованием элементов неупорядоченных списков <ol>). При этом страница, как бы, «перепрыгивает» к требуемому элементу, чтобы отобразить его. Но в данный момент более важным для нас является тот факт, что при этом наш элемент будет соответствовать селектору:

#main-navigation:target {

}

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

.navigation {
transition: width 0.3s ease;
}
#main-navigation:target {
width: 20%;
}

Мы, конечно, можем оставить все как есть, и тогда панель меню будет частично перекрывать контент (необходимым условием в этом случае является то, что значение свойства z-index у реализующего меню элемента должно быть выше, чем у элемента, содержащего основной контент страницы). На этом можно было бы и остановиться, но у нас есть еще кое-какие варианты, позволяющие значительно улучшить представление меню, поэтому идем дальше. Мы можем сдвинуть сам контент, при этом он выйдет за правую границу основной области документа. Именно так, к примеру, сделано в мобильном приложении Facebook, при раскрытии левого меню. Или мы можем изменить соотношение размеров двух колонок в нашем макете на 20%/80%. Ну что ж давайте так и сделаем.

Но секундочку, а как же назначить свойства элементу с классом .page-wrap, которые будут применяться только в том случае, когда наше меню находится в открытом состоянии? Для этого мы вполне можем воспользоваться так называемыми «соседними» селекторами:

#main-navigation:target + .page-wrap {
width: 80%;
}

Совсем не сложно, правда?

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

<a href="#">Close Menu</a>

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

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

  • Используется исключительно CSS.
  • Сокращается общий объем кода.
  • Не используется JavaScript.
  • Открытие, закрытие значительно мягче чем в случае с JavaScript.

Недостатки.

  • Ограниченная поддержка браузерами. Поддержка псевдоселектора :target в IE реализована только начиная с девятой версии.
  • Поддержка свойства transition в IE реализована только начиная с 10 версии.
  • Манипуляция именами классов или использование необходимых методов для анимации меню средствами JavaScript позволяет решить проблему кроссбраузерности.

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

*Здесь я бы добавил еще один существенный недостаток такого способа реализации меню. В ситуации, когда пользователь, сделав несколько щелчков по элементам такого меню, пожелает вернуться на посещенную им ранее страницу, воспользовавшись при этом кнопками истории просмотра, то браузер будет поочередно отображать все предыдущие действия пользователя, связанные с использованием меню. Иными словами действия, касающиеся текущего документа (в данном случае они касаются исключительно пользовательского интерфейса), которые должны быть локальными, включаются в историю просмотра браузера, что не всегда удобно. Нечто подобное Крисс Койер предложил ранее в реализации панели закладок средствами CSS3. Проблема та же. Анкорный вариант меню, это не что иное, как способ представления содержания текущего документа. JavaScript позволяет добиться более приемлемого решения в случаях открытия и закрытия панели меню, исключающего подобные ситуации. Хотя применительно к адаптивному дизайну и использованию этого подхода для мобильных приложений, вполне достойный вариант.

* Примечание переводчика.

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

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