- Создание компонента Sidenav
- Обзор
- Подходы
- CSS-псевдокласс :target
- CSS Grid
- Стопки
- Подложка
- CSS трансформации и переходы
- Доступная анимация
- Переход, трансформация, смещение
- Улучшения доступности
- Ссылки
- :is(:hover, :focus)
- Добавление JavaScript
- Заключение
- 16 CSS Sidebar Menus
- Related Articles
- Author
- Links
- Made with
- About a code
- App Admin Menus
- Author
- Links
- Made with
- About a code
- Menu Hover Slide Fill
- Author
- Links
- Made with
- About a code
- Pure CSS Single Page Application
- Author
- Links
- Made with
- About the code
- Menu Effect
- Author
- Links
- Made with
- About the code
- CSS Only Navigation for Sidebar
- Author
- Links
- Made with
- About the code
- CSS Sidebar Menu
- Author
- Links
- Made with
- About the code
- Purple Sidebar Menu
- Author
- Links
- Made with
- About the code
- Pure CSS Fly in Sidebar Navigation
- Author
- Links
- Made with
- About the code
- Sidebar Navigation Animation
- Author
- Links
- Made with
- About the code
- Fixed Hover Navigation
- Author
- Links
- Made with
- About the code
- Fully Responsive CSS3 Sidebar Menu
- Author
- Links
- Made with
- About the code
- Sidebar Sliding Menu CSS
- Author
- Links
- Made with
- About the code
- 3D Rotating Sidebar Navigation
- Author
- Links
- Made with
- About the code
- Pure CSS3 Sidebar Menu
- Author
- Links
- Made with
- About the code
- Sidebar Menu CSS
- Author
- Links
- Made with
- About the code
- CSS Sidebar Menu
- Author
- Исходники для старта из Github
- Разметка бокового меню
- Стили бокового меню
Создание компонента Sidenav
В данной статье я хочу поделиться одним из способов создания адаптивной боковой панели навигации (sidenav), поддерживающей управление с клавиатуры, работающей как с JavaScript, так и без него, и поддерживаемой всеми браузерами. Посмотреть демонстрацию можно здесь
Если Вы предпочитаете видео, ниже представлена YouTube-ролик по данной статье:
Обзор
Создать адаптивную навигацию непросто. Некоторые пользователи могут работать с помощью клавиатуры, одни при входе на сайт будут использовать мощный компьютер, другие — маленькое мобильное устройство. Но каждый из посетителей должен иметь возможность открыть и закрыть меню.
Демонстрация адаптивности макета на десктопе и мобильных:
Светлая и тёмная тема на iOS и Android
Подходы
При исследовании данного компонента я совместил несколько концепций веб-разработки:
- CSS-псевдокласс :target
- CSS Grid
- CSS-трансформации
- CSS-медиазапросы для области видимости и предпочтений пользователей
- JS для увеличения удобства использования
В моём решении на больших экранах боковая панель статична, а «выезжающей» становится только когда ширина области видимости меньше 540px . Данный размер будет контрольной точкой для переключения между интерактивной раскладкой для мобильных и статической для десктопов.
CSS-псевдокласс :target
Нажатие на эти ссылки изменяет состояние (отображение или скрытие) боковой панели в зависимости от URL в адресной строке:
@media (max-width: 540px) < #sidenav-open < visibility: hidden; >#sidenav-open:target < visibility: visible; >>
CSS Grid
Раньше для компонента боковой панели я использовал только абсолютное или фиксированное позиционирование. Технология CSS Grid с её синтаксисом grid-area , открывает ещё один способ, позволяя нам на одну строку или колонку назначить несколько элементов.
Стопки
Основной элемент макета #sidenav-container является grid-элементом, который создаёт 1 строку и 2 колонки, а первая ячейка получает имя stack . Когда пространство ограничено, CSS назначает все элементы, дочерние по отношению к в одну и ту же grid-область, размещая все элементы в одну ячейку в виде стопки.
#sidenav-container < display: grid; grid: [stack] 1fr / min-content [stack] 1fr; min-height: 100vh; >@media (max-width: 540px) < #sidenav-container >* < grid-area: stack; >>
Подложка
— это анимированный элемент, который содержит боковую навигацию. У него есть два дочерних элемента: контейнер , которому задано имя [nav] и подложка с именем [escape] , которая используется для закрытия меню.
С помощью изменения значений 2fr & 1fr можно настроить соотношение между панелью и оставшимся пространством при открытом боковом меню.
Демонстрация результата изменения размера панели
CSS трансформации и переходы
Теперь наш макет умещается и в небольшую область видимости мобильного устройства. Пока что боковая панель по умолчанию накладывается на основное содержимое. Вот функционал, который я хочу дополнить в следующем разделе:
- Анимированное открытие и закрытие
- Анимация только в том случае, если пользователь не предпочитает её отключать
- Анимирование visibility , чтобы фокус клавиатуры не выходил за пределы экрана
Так как дело дошло до реализации анимированного движения, прежде всего я бы хотел начать с доступности
Доступная анимация
Не все хотят видеть анимацию выезжающего меню. В нашем примере от предпочтения пользователя зависит значение CSS-переменной —duration , определяющей длительность анимации. Данная переменная находится внутри медиазапроса, который учитывает настройки операционной системы пользователя.
#sidenav-open < --duration: .6s; >@media (prefers-reduced-motion: reduce) < #sidenav-open < --duration: 1ms; >>
Демонстрация работы интерфейса с разными настройками анимирования
Теперь, если пользователь предпочитает уменьшенное количество анимации, панель будет появляться мгновенно.
Переход, трансформация, смещение
Скрытая панель (по умолчанию)
Чтобы на мобильных по умолчанию панель находилась за пределами экрана, я смещаю её с помощью transform: translateX(-110vw).
Обратите внимание, что в дополнение к обычной ширине области видимости -100vw я дополнительно добавил 10vw , чтобы быть уверенным, что в скрытом состоянии тень от боковой панели не будет видна на экране.
Открытая панель
Когда элемент #sidenav соответствует псевдоклассу :target , установите позиционирование с помощью translateX() на стандартное значение 0 и посмотрите, как CSS в течение времени, установленного в переменной var(—duration) , сместит элемент с его исходной позиции «скрыто», равной -110vw в позицию «открыто», равную 0 .
Переход для свойства visibility
Теперь, когда панель находится за пределами области видимости, её нужно скрыть и от скринридеров, чтобы они не переводили фокус на её элементы. Я реализовал это с помощью перехода (transition) для свойства visibility , который выполняется при смене псевдокласса :target .
- При открытии переход применять не нужно, чтобы сразу видимая панель выезжала из-за пределов экрана
- При закрытии панели для свойства visibility нужно применить переход, но с задержкой, чтобы она становилась невидимой только после завершения перехода
Улучшения доступности
Ссылки
Для управления состоянием панели, приведённое выше решение полагается на изменения URL-адреса. Естественно, здесь нужно использовать элемент , который имеет некоторые преимущества в плане доступности. Давайте дополним наши интерактивные элементы доступными подписями, отражающими их назначение.
Демонстрация взаимодействия с помощью клавиатуры и скринридера
Теперь наши основные кнопки взаимодействия содержат понятное обозначение для пользователей как мыши, так и клавиатуры.
:is(:hover, :focus)
Этот удобный псевдокласс позволяет нам задать стили одновременно для состояний hover и focus
.hamburger:is(:hover, :focus) svg > line
Добавление JavaScript
Escape для закрытия
Кнопка Escape на клавиатуре должна закрывать меню, правильно? Давайте реализуем такую возможность
const sidenav = document.querySelector('#sidenav-open'); sidenav.addEventListener('keyup', event => < if (event.code === 'Escape') document.location.hash = ''; >);
История браузера
Чтобы каждое открытие и закрытие панели не создавало отдельную запись в истории браузера, для кнопки закрытия добавьте следующий код
При закрытии панели запись в истории будет удалена, как если бы панель никогда и не открывалась
Следующий фрагмент кода помогает нам поместить фокус на кнопки открытия и закрытия при соответствующем действии панели. Я хочу сделать переключение простым
sidenav.addEventListener('transitionend', e => < const isOpen = document.location.hash === '#sidenav-open'; isOpen ? document.querySelector('#sidenav-close').focus() : document.querySelector('#sidenav-button').focus(); >)
Когда боковая панель открывается, фокус попадает на кнопку закрытия. Когда же панель закрывается, фокус попадает на кнопку открытия. Я делаю это с помощью JavaScript, вызывая на элементе focus() .
Заключение
Теперь вы знаете о моём подходе в реализации данного компонента. Как бы его реализовали Вы?
16 CSS Sidebar Menus
Collection of hand-picked free HTML and CSS sidebar menu code examples from codepen and other resources. Update of July 2018 collection. 3 new items.
Related Articles
Author
Links
Made with
About a code
App Admin Menus
App admin menus. light/dark modes.
Compatible browsers: Chrome, Edge, Firefox, Opera, Safari
Author
Links
Made with
About a code
Menu Hover Slide Fill
Compatible browsers: Chrome, Edge, Firefox, Opera, Safari
Author
Links
Made with
About a code
Pure CSS Single Page Application
Compatible browsers: Chrome, Edge, Firefox, Opera, Safari
Author
Links
Made with
About the code
Menu Effect
Reverse text color menu effects.
Compatible browsers: Chrome, Firefox, Opera, Safari
Author
Links
Made with
About the code
CSS Only Navigation for Sidebar
CSS only mirror like navigation for sidebar.
Compatible browsers: Chrome, Edge, Firefox, Opera, Safari
Author
Links
Made with
About the code
CSS Sidebar Menu
HTML and CSS navbar and sidebar mega menu.
Compatible browsers: Chrome, Edge, Firefox, Opera, Safari
Dependencies: bootstrap.css, font-awesome.css
Author
Links
Made with
About the code
Purple Sidebar Menu
This is a reverse engineering of the «Hyperspace» design from HTML5 Up! https://html5up.net/hyperspace
Compatible browsers: Chrome, Edge, Firefox, Opera, Safari
Author
Links
Made with
About the code
Pure CSS Fly in Sidebar Navigation
A simple, multi-level sidebar navigation. Features pure css «fly in» subnav, that leaves icons of parent nav visible. Nav items will scroll ( overflow-y ) if needed. Uses transform s and transition s.
Compatible browsers: Chrome, Edge, Firefox, Opera, Safari
Author
Links
Made with
About the code
Sidebar Navigation Animation
Nothing like a little trendy body pushin.
Compatible browsers: Chrome, Edge, Firefox, Opera, Safari
Author
Links
Made with
About the code
Fixed Hover Navigation
Fixed sidebar drawer navigation, that expands on hover.
Compatible browsers: Chrome, Edge, Firefox, Opera, Safari
Author
Links
Made with
About the code
Fully Responsive CSS3 Sidebar Menu
A fully responsive sidebar menu without any need of JavaScript and using less than 200 lines of functional CSS code.
Compatible browsers: Chrome, Edge, Firefox, Opera, Safari
Author
Links
Made with
About the code
Sidebar Sliding Menu CSS
CSS sliding sidebar menu with scroll, no JS were used
Compatible browsers: Chrome, Edge, Firefox, Opera, Safari
Author
Links
Made with
About the code
3D Rotating Sidebar Navigation
A vertical navigation bar that switches from an icon to text with a cool animation.
Compatible browsers: Chrome, Edge, Firefox, Opera, Safari
Author
Links
Made with
About the code
Pure CSS3 Sidebar Menu
Pure CSS3 mega dropdown sidebar menu with animation..
Compatible browsers: Chrome, Edge, Firefox, Opera, Safari
Author
Links
Made with
About the code
Sidebar Menu CSS
CSS sidebar menu with hover show/hide.
Compatible browsers: Chrome, Edge, Firefox, Opera, Safari
Author
Links
Made with
About the code
CSS Sidebar Menu
Easy to use sidebar menu with HTML and CSS.
Compatible browsers: Chrome, Edge, Firefox, Opera, Safari
Author
Исходники для старта из Github
Все исходники для начала проекта вы сможете скачать по ссылке с моего Github. Там содержатся SVG-иконки, базовые настройки стилей, а также сброс стилей.
Разметка бокового меню
Первым делом сделаем разметку бокового меню в файле index.html. Разметка содержит в себе само меню (класс .menu), а также основной контент (класс .content).
Drivefile Home Recents Starred Photos Shared File Delete
Get help Logout
Стили бокового меню
Важно сделать само меню фиксированным, а также растянуть его на всю высоту экрана.
body < width: 100%; min-height: 100vh; background-color: #f5f6fb; >/* Основные свойства для бокового меню */ .menu < display: flex; flex-direction: column; /* размещаем элементы к колонку */ width: 240px; min-height: 100vh; /* на всю высоту экрана */ position: fixed; /* чтобы меню было фиксированным */ top: 0; /* прижимаем к верхнему */ left: 0; /* .. и нижнему краю */ background-color: #343951; box-shadow: 4px 4px 8px 0 rgba(34, 60, 80, 0.2); /* задаем тень, чтобы отделить от фона */ >/* Свойства для контента */ .content < padding-left: 280px; /* отступ от бокового меню 240px + 40px */ padding-top: 40px; padding-right: 40px; padding-bottom: 40px; >.logo < display: flex; align-items: center; /* центрируем логотип с текстом */ color: #fff; font-size: 24px; text-decoration: none; font-family: "Rubik", sans-serif; font-weight: bold; >/* Задаем псеводоэлемент для иконки */ .logo:before < content: url(./img/logo.svg); /* путь от иконки-лого */ padding-right: 8px; /* немного отступим справа */ >/* Позиционирование лого в меню */ .menu__logo < padding-top: 50px; padding-left: 30px; margin-bottom: 59px; >/* Позиционирование элементов в меню */ .menu__link, .admin__link < padding-left: 30px; >/* Свойства для элементов меню */ .link < position: relative; /* чтобы задать потом псевдоэлемент */ display: flex; /* чтобы элемент тянулся на всю ширину */ align-items: center; /* по центру текст и иконка */ height: 45px; /* высота элемента 45px */ text-decoration: none; >/* Свойства иконки внутри ссылки */ .link > img < width: 25px; margin-right: 20px; >/* Свойства текста внутри ссылки */ .link > span < font-family: "Karla", sans-serif; font-size: 20px; color: #fff; >/* При наведении на ссылку - полупрозрачный белый фон */ .link:hover < background-color: rgba(255, 255, 255, 0.1); >/* Выводим оранжевую линию слева */ .link:hover:before < display: flex; >/* Создаем оранжевую линию слева */ .link:before < content: ""; display: none; position: absolute; left: 0; top: 0; width: 5px; height: 100%; background-color: #ffa000; >/* Позиционирование админ-меню */ .menu__admin