Клик, вложенность, наведение, длинные списки и составное содержимое.
Примеры используют VGApp и OKAUX 1.0.2. Подключите стили обоих пакетов
и выполняйте JavaScript после появления разметки. У VGNav нет автоматического
поиска всех меню: для каждого корня нужен один вызов VGNav.init().
Параметры из data-* дополняют ручную инициализацию. Откройте «Каталог», затем «Сервис». Для вложенных подменю прокрутка списка отключена через dropListScroll: false. Клик снаружи закрывает меню; повторный клик по вложенному пункту закрывает его.
Ссылки ведут к этому блоку примера.
Показать код
<nav id="nav-demo-click" class="vg-nav nav-demo nav-demo--dropdown" data-nav-demo
data-hover="false" data-breakpoint="false" data-hamburger-enable="false"
data-params='{"dropListScroll":false}'
aria-label="Каталог по клику">
<ul class="vg-nav-wrapper">
<li class="dropdown">
<a href="#nav-click-result">Каталог</a>
<div class="dropdown-content">
<ul class="vg-nav-drop-list">
<li><a href="#nav-click-result">Оборудование</a></li>
<li class="dropdown">
<a href="#nav-click-result">Сервис</a>
<div class="dropdown-content">
<ul class="vg-nav-drop-list">
<li><a href="#nav-click-result">Диагностика</a></li>
<li><a href="#nav-click-result">Обслуживание</a></li>
</ul>
</div>
</li>
</ul>
</div>
</li>
<li><a href="#nav-click-result">Контакты</a></li>
</ul>
</nav>
<p id="nav-click-result" class="nav-demo-result">Ссылки ведут к этому блоку примера.</p>
/**
* Описание: рабочий пример VGNav — click.
* Возможности: демонстрирует Data API и вложенные пункты.
*/
import { VGNav } from 'vgapp';
function initNavDemo() {
const root = document.querySelector('#nav-demo-click');
if (!root || VGNav.getInstance(root)) return;
VGNav.init(root);
}
initNavDemo();
/* Композиция примеров; поведение dropdown остаётся в VGNav. Токены — OKAUX. */
.vg-nav.nav-demo {
--vg-nav-item-padding: .75rem 1rem;
--vg-nav-item-white-space: normal;
--vg-nav-drop-width: min(16rem, calc(100vw - 3rem));
--vg-nav-drop-border-radius: .75rem;
--vg-nav-drop-item-bg-hover: var(--vg-background-tertiary);
--vg-nav-drop-item-color-hover: var(--vg-text-primary);
--vg-nav-drop-mega-min-height: 0;
--vg-nav-drop-mega-border-radius: .75rem;
--vg-nav-drop-mega-width: min(30rem, calc(100vw - 3rem));
min-width: 0;
}
.nav-demo > .vg-nav-wrapper {
flex-wrap: wrap;
}
.nav-demo.vg-nav-overflow-enabled > .vg-nav-wrapper {
flex-wrap: nowrap;
}
.nav-demo.vg-nav-overflow-enabled {
--vg-nav-item-white-space: nowrap;
}
.nav-demo-overflow-frame {
width: 100%;
max-width: 100%;
transition: width .25s ease;
}
.nav-demo-overflow-frame.is-narrow {
width: min(22rem, 100%);
}
.nav-demo-overflow-frame .vg-nav {
width: 100%;
}
/* Резерв места под dropdown, чтобы он не перекрывал кнопку раскрытия кода. */
.nav-demo--dropdown {
min-height: 14rem;
}
.vg-nav.nav-demo--directions {
--vg-nav-drop-width: min(13rem, calc(100vw - 3rem));
min-height: 22rem;
}
.nav-demo--directions > .vg-nav-wrapper {
justify-content: flex-end;
}
.nav-demo-directions {
white-space: pre-line;
}
@media (max-width: 600px) {
.vg-nav.nav-demo--directions {
min-height: 30rem;
}
}
.nav-demo .vg-nav-drop-list {
margin: 0;
padding: 0;
list-style: none;
}
.nav-demo--scroll {
--vg-nav-drop-max-height: 12rem;
min-height: 17rem;
}
.nav-demo-mega-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(min(100%, 10rem), 1fr));
gap: 1rem;
}
.nav-demo-mega-grid a {
display: block;
padding: .5rem 0;
}
.nav-demo-result {
display: block;
margin-top: 1rem;
padding: .75rem;
border: 1px solid var(--vg-border-default);
border-radius: .5rem;
background: var(--vg-background-secondary);
color: var(--vg-text-primary);
overflow-wrap: anywhere;
}
.nav-demo-actions {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: .75rem;
margin-bottom: 1rem;
}
.nav-demo-sidebar {
--vg-sidebar-horizontal-width: min(22rem, 100vw);
--vg-sidebar-padding: 1.25rem;
}
.nav-demo-log {
max-height: 12rem;
overflow-y: auto;
white-space: pre-wrap;
}
Четыре уровня от правого края
Откройте «Каталог справа» → «Разработка» → «Веб-приложения» → «Интерфейс». VGNav сам выбирает сторону для каждого подменю: у правой границы оно открывается влево, а при наличии места — вправо. На узком экране возможен переход вверх или вниз. Под примером показан фактический data-vg-placement; измените ширину окна и сравните.
Откройте «Каталог справа», затем «Разработка» → «Веб-приложения» → «Интерфейс».
Показать код
<nav id="nav-demo-directions" class="vg-nav nav-demo nav-demo--directions" data-nav-demo
aria-label="Четыре уровня у правого края">
<ul class="vg-nav-wrapper">
<li class="dropdown" data-nav-level="1">
<a href="#nav-directions-result">Каталог справа</a>
<div class="dropdown-content"><ul class="vg-nav-drop-list">
<li><a href="#nav-directions-result">Все услуги</a></li>
<li class="dropdown" data-nav-level="2">
<a href="#nav-directions-result">Разработка</a>
<div class="dropdown-content"><ul class="vg-nav-drop-list">
<li><a href="#nav-directions-result">Обзор проектов</a></li>
<li class="dropdown" data-nav-level="3">
<a href="#nav-directions-result">Веб-приложения</a>
<div class="dropdown-content"><ul class="vg-nav-drop-list">
<li><a href="#nav-directions-result">Архитектура</a></li>
<li class="dropdown" data-nav-level="4">
<a href="#nav-directions-result">Интерфейс</a>
<div class="dropdown-content"><ul class="vg-nav-drop-list">
<li><a href="#nav-directions-result">Компоненты</a></li>
<li><a href="#nav-directions-result">Дизайн-система</a></li>
</ul></div>
</li>
</ul></div>
</li>
</ul></div>
</li>
</ul></div>
</li>
</ul>
</nav>
<output id="nav-directions-result" class="nav-demo-result nav-demo-directions" aria-live="polite">
Откройте «Каталог справа», затем «Разработка» → «Веб-приложения» → «Интерфейс».
</output>
/**
* Описание: четыре уровня VGNav с началом у правого края и автоматическим выбором направления.
* Возможности: показывает реальные data-vg-placement открытых подменю при открытии, resize и прокрутке.
*/
import { VGNav } from 'vgapp';
function initNavDemo() {
const root = document.querySelector('#nav-demo-directions');
if (!root || VGNav.getInstance(root)) return;
const output = document.querySelector('#nav-directions-result');
const initialText = output.textContent.trim();
const directions = { left: 'влево', right: 'вправо', top: 'вверх', bottom: 'вниз' };
const update = () => {
const lines = [...root.querySelectorAll('.dropdown.active')].map((item) => {
const drop = item.querySelector(':scope > .dropdown-content');
const placement = drop.getAttribute('data-vg-placement') || '';
const direction = directions[placement.split('-')[0]] || placement;
const title = item.querySelector(':scope > a').textContent.trim();
return `Уровень ${item.dataset.navLevel} · ${title}: ${direction} (${placement})`;
});
output.textContent = lines.length ? lines.join('\n') : initialText;
};
root.addEventListener('vg.nav.shown', update);
root.addEventListener('vg.nav.hidden', update);
// Читаем результат после обработчиков позиционирования самого VGNav.
const updateAfterLayout = () => requestAnimationFrame(update);
window.addEventListener('resize', updateAfterLayout);
window.addEventListener('scroll', updateAfterLayout, { passive: true, capture: true });
VGNav.init(root, {
breakpoint: false,
hover: false,
dropListScroll: false,
hamburger: { enable: false }
});
}
initNavDemo();
/* Композиция примеров; поведение dropdown остаётся в VGNav. Токены — OKAUX. */
.vg-nav.nav-demo {
--vg-nav-item-padding: .75rem 1rem;
--vg-nav-item-white-space: normal;
--vg-nav-drop-width: min(16rem, calc(100vw - 3rem));
--vg-nav-drop-border-radius: .75rem;
--vg-nav-drop-item-bg-hover: var(--vg-background-tertiary);
--vg-nav-drop-item-color-hover: var(--vg-text-primary);
--vg-nav-drop-mega-min-height: 0;
--vg-nav-drop-mega-border-radius: .75rem;
--vg-nav-drop-mega-width: min(30rem, calc(100vw - 3rem));
min-width: 0;
}
.nav-demo > .vg-nav-wrapper {
flex-wrap: wrap;
}
.nav-demo.vg-nav-overflow-enabled > .vg-nav-wrapper {
flex-wrap: nowrap;
}
.nav-demo.vg-nav-overflow-enabled {
--vg-nav-item-white-space: nowrap;
}
.nav-demo-overflow-frame {
width: 100%;
max-width: 100%;
transition: width .25s ease;
}
.nav-demo-overflow-frame.is-narrow {
width: min(22rem, 100%);
}
.nav-demo-overflow-frame .vg-nav {
width: 100%;
}
/* Резерв места под dropdown, чтобы он не перекрывал кнопку раскрытия кода. */
.nav-demo--dropdown {
min-height: 14rem;
}
.vg-nav.nav-demo--directions {
--vg-nav-drop-width: min(13rem, calc(100vw - 3rem));
min-height: 22rem;
}
.nav-demo--directions > .vg-nav-wrapper {
justify-content: flex-end;
}
.nav-demo-directions {
white-space: pre-line;
}
@media (max-width: 600px) {
.vg-nav.nav-demo--directions {
min-height: 30rem;
}
}
.nav-demo .vg-nav-drop-list {
margin: 0;
padding: 0;
list-style: none;
}
.nav-demo--scroll {
--vg-nav-drop-max-height: 12rem;
min-height: 17rem;
}
.nav-demo-mega-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(min(100%, 10rem), 1fr));
gap: 1rem;
}
.nav-demo-mega-grid a {
display: block;
padding: .5rem 0;
}
.nav-demo-result {
display: block;
margin-top: 1rem;
padding: .75rem;
border: 1px solid var(--vg-border-default);
border-radius: .5rem;
background: var(--vg-background-secondary);
color: var(--vg-text-primary);
overflow-wrap: anywhere;
}
.nav-demo-actions {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: .75rem;
margin-bottom: 1rem;
}
.nav-demo-sidebar {
--vg-sidebar-horizontal-width: min(22rem, 100vw);
--vg-sidebar-padding: 1.25rem;
}
.nav-demo-log {
max-height: 12rem;
overflow-y: auto;
white-space: pre-wrap;
}
Наведение и переход к соседнему меню
На десктопе наведите курсор на «Продукты» и переведите горизонтально на «Ресурсы». На мобильном устройстве используются клики.
Ссылки ведут к этому блоку примера.
Показать код
<nav id="nav-demo-hover" class="vg-nav nav-demo nav-demo--dropdown" data-nav-demo aria-label="Меню по наведению">
<ul class="vg-nav-wrapper">
<li class="dropdown">
<a href="#nav-hover-result">Продукты</a>
<div class="dropdown-content"><ul class="vg-nav-drop-list">
<li><a href="#nav-hover-result">CRM</a></li>
<li><a href="#nav-hover-result">Каталог</a></li>
</ul></div>
</li>
<li class="dropdown">
<a href="#nav-hover-result">Ресурсы</a>
<div class="dropdown-content"><ul class="vg-nav-drop-list">
<li><a href="#nav-hover-result">Документация</a></li>
<li><a href="#nav-hover-result">Поддержка</a></li>
</ul></div>
</li>
</ul>
</nav>
<p id="nav-hover-result" class="nav-demo-result">Ссылки ведут к этому блоку примера.</p>
/**
* Описание: рабочий пример VGNav — hover.
* Возможности: демонстрирует наведение и переключение соседних dropdown.
*/
import { VGNav } from 'vgapp';
function initNavDemo() {
const root = document.querySelector('#nav-demo-hover');
if (!root || VGNav.getInstance(root)) return;
VGNav.init(root, {
breakpoint: false,
hover: true,
hamburger: { enable: false },
hoversmoothfirstlevel: { enable: true, horizontalOnly: true }
});
}
initNavDemo();
/* Композиция примеров; поведение dropdown остаётся в VGNav. Токены — OKAUX. */
.vg-nav.nav-demo {
--vg-nav-item-padding: .75rem 1rem;
--vg-nav-item-white-space: normal;
--vg-nav-drop-width: min(16rem, calc(100vw - 3rem));
--vg-nav-drop-border-radius: .75rem;
--vg-nav-drop-item-bg-hover: var(--vg-background-tertiary);
--vg-nav-drop-item-color-hover: var(--vg-text-primary);
--vg-nav-drop-mega-min-height: 0;
--vg-nav-drop-mega-border-radius: .75rem;
--vg-nav-drop-mega-width: min(30rem, calc(100vw - 3rem));
min-width: 0;
}
.nav-demo > .vg-nav-wrapper {
flex-wrap: wrap;
}
.nav-demo.vg-nav-overflow-enabled > .vg-nav-wrapper {
flex-wrap: nowrap;
}
.nav-demo.vg-nav-overflow-enabled {
--vg-nav-item-white-space: nowrap;
}
.nav-demo-overflow-frame {
width: 100%;
max-width: 100%;
transition: width .25s ease;
}
.nav-demo-overflow-frame.is-narrow {
width: min(22rem, 100%);
}
.nav-demo-overflow-frame .vg-nav {
width: 100%;
}
/* Резерв места под dropdown, чтобы он не перекрывал кнопку раскрытия кода. */
.nav-demo--dropdown {
min-height: 14rem;
}
.vg-nav.nav-demo--directions {
--vg-nav-drop-width: min(13rem, calc(100vw - 3rem));
min-height: 22rem;
}
.nav-demo--directions > .vg-nav-wrapper {
justify-content: flex-end;
}
.nav-demo-directions {
white-space: pre-line;
}
@media (max-width: 600px) {
.vg-nav.nav-demo--directions {
min-height: 30rem;
}
}
.nav-demo .vg-nav-drop-list {
margin: 0;
padding: 0;
list-style: none;
}
.nav-demo--scroll {
--vg-nav-drop-max-height: 12rem;
min-height: 17rem;
}
.nav-demo-mega-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(min(100%, 10rem), 1fr));
gap: 1rem;
}
.nav-demo-mega-grid a {
display: block;
padding: .5rem 0;
}
.nav-demo-result {
display: block;
margin-top: 1rem;
padding: .75rem;
border: 1px solid var(--vg-border-default);
border-radius: .5rem;
background: var(--vg-background-secondary);
color: var(--vg-text-primary);
overflow-wrap: anywhere;
}
.nav-demo-actions {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: .75rem;
margin-bottom: 1rem;
}
.nav-demo-sidebar {
--vg-sidebar-horizontal-width: min(22rem, 100vw);
--vg-sidebar-padding: 1.25rem;
}
.nav-demo-log {
max-height: 12rem;
overflow-y: auto;
white-space: pre-wrap;
}
Длинный список с прокруткой
Ограничение высоты применяется к прямому .vg-nav-drop-list внутри .dropdown-content. Прокрутите список до последнего раздела.
Последний пункт списка — «Настройки».
Показать код
Составное содержимое вместо обычного списка: две группы ссылок. Сетка внутри — композиция демо, открытие и позиционирование — VGNav.
Ссылки ведут к этому блоку примера.
Показать код
<nav id="nav-demo-mega" class="vg-nav nav-demo nav-demo--dropdown" data-nav-demo aria-label="Мегаменю">
<ul class="vg-nav-wrapper">
<li class="dropdown dropdown-mega">
<a href="#nav-mega-result">Возможности</a>
<div class="dropdown-content">
<div class="nav-demo-mega-grid">
<div><strong>Рабочие процессы</strong>
<a href="#nav-mega-result">Запись клиентов</a>
<a href="#nav-mega-result">Планирование</a>
</div>
<div><strong>Для команды</strong>
<a href="#nav-mega-result">База знаний</a>
<a href="#nav-mega-result">Обучение</a>
</div>
</div>
</div>
</li>
</ul>
</nav>
<p id="nav-mega-result" class="nav-demo-result">Ссылки ведут к этому блоку примера.</p>
/**
* Описание: рабочий пример VGNav — mega.
* Возможности: демонстрирует составное мегаменю.
*/
import { VGNav } from 'vgapp';
function initNavDemo() {
const root = document.querySelector('#nav-demo-mega');
if (!root || VGNav.getInstance(root)) return;
VGNav.init(root, {
breakpoint: false,
hover: false,
hamburger: { enable: false }
});
}
initNavDemo();
/* Композиция примеров; поведение dropdown остаётся в VGNav. Токены — OKAUX. */
.vg-nav.nav-demo {
--vg-nav-item-padding: .75rem 1rem;
--vg-nav-item-white-space: normal;
--vg-nav-drop-width: min(16rem, calc(100vw - 3rem));
--vg-nav-drop-border-radius: .75rem;
--vg-nav-drop-item-bg-hover: var(--vg-background-tertiary);
--vg-nav-drop-item-color-hover: var(--vg-text-primary);
--vg-nav-drop-mega-min-height: 0;
--vg-nav-drop-mega-border-radius: .75rem;
--vg-nav-drop-mega-width: min(30rem, calc(100vw - 3rem));
min-width: 0;
}
.nav-demo > .vg-nav-wrapper {
flex-wrap: wrap;
}
.nav-demo.vg-nav-overflow-enabled > .vg-nav-wrapper {
flex-wrap: nowrap;
}
.nav-demo.vg-nav-overflow-enabled {
--vg-nav-item-white-space: nowrap;
}
.nav-demo-overflow-frame {
width: 100%;
max-width: 100%;
transition: width .25s ease;
}
.nav-demo-overflow-frame.is-narrow {
width: min(22rem, 100%);
}
.nav-demo-overflow-frame .vg-nav {
width: 100%;
}
/* Резерв места под dropdown, чтобы он не перекрывал кнопку раскрытия кода. */
.nav-demo--dropdown {
min-height: 14rem;
}
.vg-nav.nav-demo--directions {
--vg-nav-drop-width: min(13rem, calc(100vw - 3rem));
min-height: 22rem;
}
.nav-demo--directions > .vg-nav-wrapper {
justify-content: flex-end;
}
.nav-demo-directions {
white-space: pre-line;
}
@media (max-width: 600px) {
.vg-nav.nav-demo--directions {
min-height: 30rem;
}
}
.nav-demo .vg-nav-drop-list {
margin: 0;
padding: 0;
list-style: none;
}
.nav-demo--scroll {
--vg-nav-drop-max-height: 12rem;
min-height: 17rem;
}
.nav-demo-mega-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(min(100%, 10rem), 1fr));
gap: 1rem;
}
.nav-demo-mega-grid a {
display: block;
padding: .5rem 0;
}
.nav-demo-result {
display: block;
margin-top: 1rem;
padding: .75rem;
border: 1px solid var(--vg-border-default);
border-radius: .5rem;
background: var(--vg-background-secondary);
color: var(--vg-text-primary);
overflow-wrap: anywhere;
}
.nav-demo-actions {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: .75rem;
margin-bottom: 1rem;
}
.nav-demo-sidebar {
--vg-sidebar-horizontal-width: min(22rem, 100vw);
--vg-sidebar-padding: 1.25rem;
}
.nav-demo-log {
max-height: 12rem;
overflow-y: auto;
white-space: pre-wrap;
}