От автора: учебник о том, как воспроизвести эффект маленького меню слева на сайте YouTube. Идея состоит в том, чтобы иконка соскальзывала вправо, показывая при этом список пунктов меню.
Сегодня мы покажем вам, как воспроизвести эффект маленького меню, которое можно видеть слева на YouTube при просмотре видео (где написано «Гид»). Меню состоит из маленькой иконки, метки и списка пунктов, который появляется при щелчке по метке или иконке. При щелчке иконка меню скользит вправо, а метка сдвигается вверх при последовательном появлении пунктов списка. Чтобы стало интереснее, мы добавим к нему еще немного стилей и эффектов.
РАЗМЕТКА
Для HTML мы применим элемент nav, а внутрь добавим div, который будет содержать иконку меню и метку. Для пунктов меню используем неупорядоченный список:
1 2 3 4 5 6 7 8 9 10 11 12 |
<nav id="dr-menu" class="dr-menu"> <div class="dr-trigger"><span class="dr-icon dr-icon-menu"></span><a class="dr-label">Account</a></div> <ul> <li><a class="dr-icon dr-icon-user" href="#">Xavier Densmore</a></li> <li><a class="dr-icon dr-icon-camera" href="#">Videos</a></li> <li><a class="dr-icon dr-icon-heart" href="#">Favorites</a></li> <li><a class="dr-icon dr-icon-bullhorn" href="#">Subscriptions</a></li> <li><a class="dr-icon dr-icon-download" href="#">Downloads</a></li> <li><a class="dr-icon dr-icon-settings" href="#">Settings</a></li> <li><a class="dr-icon dr-icon-switch" href="#">Logout</a></li> </ul> </nav> |
У каждого пункта меню будет маленькая иконка, поэтому мы назначим им всем разные классы. Используемые нами иконки взяты с IcoMoon, а также с помощью этого великолепного приложения создан пользовательский набор иконок. Давайте взглянем на CSS.
CSS
Обратите внимание, что в CSS нет никаких префиксов, но в файлах они будут. Сначала включим шрифт-иконку:
1 2 3 4 5 6 7 8 9 10 |
@font-face { font-family: 'icomoon'; src:url('../fonts/icomoon.eot'); src:url('../fonts/icomoon.eot?#iefix') format('embedded-opentype'), url('../fonts/icomoon.woff') format('woff'), url('../fonts/icomoon.ttf') format('truetype'), url('../fonts/icomoon.svg#icomoon') format('svg'); font-weight: normal; font-style: normal; } |
У основного контейнера nav будет несколько общих стилей, вроде размера шрифта, высоты строки, цвета и размеров. Мы хотим, чтобы он был гибким, но не нужно, чтобы он становился слишком большим или маленьким, поэтому назначим ему максимальную и минимальную ширину:
1 2 3 4 5 6 7 8 9 10 11 |
.dr-menu { width: 100%; max-width: 400px; min-width: 300px; position: relative; font-size: 1.3em; line-height: 2.5; font-weight: 400; color: #fff; padding-top: 2em; } |
Раздел, содержащий диапазон иконок меню и ссылку на метку, будет абсолютно позиционирован, и мы установим курсор в значение pointer. Ему потребуется z-индекс, чтобы гарантировать, что неупорядоченный список не останется сверху него:
1 2 3 4 5 6 |
.dr-menu > div { cursor: pointer; position: absolute; width: 100%; z-index: 100; } |
Диапазон иконок меню в разделе запуска также абсолютно позиционируем и добавим переход:
1 2 3 4 5 6 7 8 9 |
.dr-menu > div .dr-icon { top: 0; left: 0; position: absolute; font-size: 150%; line-height: 1.6; padding: 0 10px; transition: all 0.4s ease; } |
При щелчке на раздел мы добавим к nav класс под названием “dr-menu-open”. Иконка меню тогда скользнет влево, и мы переместим ее на величину ее собственной ширины так, чтобы она красиво возвращалась на место без перетекания:
1 2 3 4 5 |
.dr-menu.dr-menu-open > div .dr-icon { color: #60a773; left: 100%; transform: translateX(-100%); } |
В конце CSS добавим классы иконок из IcoMoon. В диапазоне меню иконка будет немного отличаться, и мы применим псевдокласс :after для добавления маленького треугольника. Итак, определим все таким образом:
1 2 3 4 5 6 7 8 |
.dr-menu > div .dr-icon:after { content: "\e008"; position: absolute; font-size: 50%; line-height: 3.25; left: -10%; opacity: 0; } |
Иконка будет позиционирована абсолютно, и мы поставим ее на место, сдвинув на 10% влево. Изначально непрозрачность установлена на 0, потому что нам не нужно ее показывать, когда меню закрыто. При открытии меню она становится видимой:
1 2 3 |
.dr-menu.dr-menu-open > div .dr-icon:after { opacity: 1; } |
Метка, которая является ссылкой в нашем HTML, получит общие стили и отступ, чтобы находиться рядом с иконкой меню. Мы также добавим переход, потому что хотим анимировать ее при открытии меню, что и сделаем с помощью переноса на ось Y:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
.dr-menu > div .dr-label { padding-left: 3em; position: relative; display: block; color: #60a773; font-size: 0.9em; font-weight: 700; letter-spacing: 1px; text-transform: uppercase; line-height: 2.75; transition: all 0.2s ease-in; } .dr-menu.dr-menu-open > div .dr-label { transform: translateY(-90%); } |
Неупорядоченный список изначально будет невидим, так как его непрозрачность равна 0:
1 2 3 4 5 6 7 8 9 10 |
.dr-menu ul { padding: 0; margin: 0 3em 0 0; list-style: none; opacity: 0; position: relative; z-index: 0; pointer-events: none; transition: opacity 0s linear 205ms; } |
Нужно, чтобы при открытии меню список становился видимым и с большим z-индексом, чтобы его не закрывал div:
1 2 3 4 5 6 |
.dr-menu.dr-menu-open ul { opacity: 1; z-index: 200; pointer-events: auto; transition: opacity 0s linear 0s; } |
Для открытия и закрытия меню имеются два перехода. При открытии нам нужно, чтобы оно открывалось без задержки, а при закрытии, т.е. удалении класса, нужно, чтобы оно происходило с задержкой. Эта задержка определяется задержкой последнего пункта списка, как мы это вскоре увидим. Пункты меню тоже будут невидимы, и мы установим переход для непрозрачности:
1 2 3 4 5 6 7 8 9 10 |
.dr-menu ul li { display: block; margin: 0 0 5px 0; opacity: 0; transition: opacity 0.3s ease; } .dr-menu.dr-menu-open ul li { opacity: 1; } |
Теперь каждый пункт списка будет появляться с разной задержкой: первый проявится сразу же, а последний – в конце:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
.dr-menu.dr-menu-open ul li:nth-child(2) { transition-delay: 35ms; } .dr-menu.dr-menu-open ul li:nth-child(3) { transition-delay: 70ms; } .dr-menu.dr-menu-open ul li:nth-child(4) { transition-delay: 105ms; } .dr-menu.dr-menu-open ul li:nth-child(5) { transition-delay: 140ms; } .dr-menu.dr-menu-open ul li:nth-child(6) { transition-delay: 175ms; } .dr-menu.dr-menu-open ul li:nth-child(7) { transition-delay: 205ms; } |
У ссылок будет отступ, и мы установим их как inline-block:
1 2 3 4 5 |
.dr-menu ul li a { display: inline-block; padding: 0 20px; color: #fff; } |
И изменим цвет при проведении мышью:
1 2 3 |
.dr-menu ul li a:hover { color: #60a773; } |
И последнее, но не менее важное – давайте определим псевдоэлементы иконок:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
.dr-icon:before, .dr-icon:after { position: relative; font-family: 'icomoon'; speak: none; font-style: normal; font-weight: normal; font-variant: normal; text-transform: none; -webkit-font-smoothing: antialiased; } .dr-menu ul .dr-icon:before { margin-right: 15px; } .dr-icon-bullhorn:before { content: "\e000"; } .dr-icon-camera:before { content: "\e002"; } .dr-icon-heart:before { content: "\e003"; } .dr-icon-settings:before { content: "\e004"; } .dr-icon-switch:before { content: "\e005"; } .dr-icon-download:before { content: "\e006"; } .dr-icon-user:before { content: "\e001"; } .dr-icon-menu:before { content: "\e007"; } |
Вот и все стили. Займемся JavaScript’ом.
JAVASCRIPT
Мы создадим небольшой скрипт, который позаботится о функциональности меню. При щелчке на раздел запуска нужно, чтоб оболочка меню получала класс “dr-menu-open”. Так как мы будем анимировать метку и иконку меню вправо, нужно, чтобы закрытие происходило только при щелчке на иконку меню, как в YouTube’е:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
var YTMenu = (function() { function init() { [].slice.call( document.querySelectorAll( '.dr-menu' ) ).forEach( function( el, i ) { var trigger = el.querySelector( 'div.dr-trigger' ), icon = trigger.querySelector( 'span.dr-icon-menu' ), open = false; trigger.addEventListener( 'click', function( event ) { if( !open ) { el.className += ' dr-menu-open'; open = true; } }, false ); icon.addEventListener( 'click', function( event ) { if( open ) { event.stopPropagation(); open = false; el.className = el.className.replace(/\bdr-menu-open\b/,''); return false; } }, false ); } ); } init(); })(); |
Вот и все! Надеюсь, этот учебник вам понравился и оказался полезен!
Автор: Mary Lou
Источник: //tympanus.net/
Редакция: Команда webformyself.