Vertical Navigation
The <nys-verticalnav> component renders a side navigation menu on desktop and collapses into a <nys-accordion> on tablet and mobile. It is commonly used on sites and applications with many links that may not fit in a horizontal navigation.
<nys-verticalnav heading="Freshwater Fishing" headingLevel="h2">
<ul>
<li><a href="/">Home</a></li>
<li><a href="/services">Services</a></li>
<li>
<h3>Freshwater Fishing Regulations</h3>
<ul>
<li><a href="">Places to Fish</a></li>
<li><a href="">Learn to Fish</a></li>
<li><a href="">Ice Fishing</a></li>
</ul>
</li>
</ul>
</nys-verticalnav>
Can't use NYS Design System web components in your project? Try using the CSS Variables instead.
Accessibility
The <nys-verticalnav> component includes the following accessibility-focused features:
- The nav region is labeled via
aria-labelledby(pointing to the header) oraria-labelwhen the header is hidden. - On mobile, the nav becomes an accordion, keeping all links reachable with the same keyboard interactions as
nys-accordion. - A link with
aria-current="page"automatically gets active styling, and any containingnys-verticalnavgroupauto-expands so the active link is visible on load. nys-verticalnavgrouptriggers are real<button>elements witharia-expandedreflecting open/closed state.
Note: <a> elements have no native disabled attribute, so <nys-verticalnavgroup disabled> only disables the group's own toggle button — it doesn't affect the links inside. To mark an individual link as disabled, add aria-disabled="true" to that <a> directly:
Options
Header slot
Replace the default heading with custom markup using the header slot.
<style>
[slot="header"] {
padding-left: var(--nys-space-100, 8px);
padding-top: var(--nys-space-100, 8px);
}
[slot="header"] h2 {
margin: 0;
font-size: var(--nys-font-size-h4, 1.25rem);
color: var(--nys-color-theme, #154973);
}
[slot="header"] p {
font-size: var(--nys-font-size-xs, 0.75rem);
color: var(--nys-color-success, #2e7d32);
font-weight: 500;
margin: 0;
}
</style>
<nys-verticalnav heading="Freshwater Fishing" headingLevel="h2">
<div slot="header">
<h2>Freshwater Fishing</h2>
<p>2026 Season Open</p>
</div>
<ul>
<li><a href="/">Home</a></li>
<li><a href="/services">Services</a></li>
</ul>
</nys-verticalnav>
Footer slot
Add extra content below the links, like a divider and contact info.
<style>
[slot="footer"] {
display: flex;
flex-direction: column;
gap: var(--nys-space-100, 8px);
padding: 0 var(--nys-space-100, 8px) var(--nys-space-100, 8px);
}
[slot="footer"] p {
margin: 0;
font-size: var(--nys-font-size-xs, 0.75rem);
color: var(--nys-color-text-weak, #4a4d4f);
}
[slot="footer"] a {
font-size: var(--nys-font-size-sm, 0.875rem);
color: var(--nys-color-theme, #154973);
}
</style>
<nys-verticalnav heading="Freshwater Fishing" headingLevel="h2">
<ul>
<li><a href="/">Home</a></li>
<li><a href="/services">Services</a></li>
</ul>
<div slot="footer">
<nys-divider></nys-divider>
<p>Regulations last updated: January 2026</p>
<a href="/contact-dec">Contact the DEC for fishing inquiries</a>
</div>
</nys-verticalnav>
Collapsible groups
Use <nys-verticalnavgroup> for a set of links that expand and collapse. Add expanded to open it by default, or disabled to prevent interaction.
<nys-verticalnav heading="NYS Design System" headingLevel="h2">
<ul>
<li><a href="/">Foundations</a></li>
<li>
<nys-verticalnavgroup label="Accessibility">
<ul>
<li><a href="">WCAG Guidelines</a></li>
<li><a href="">Screen Readers</a></li>
<li><a href="">Color Contrast</a></li>
</ul>
</nys-verticalnavgroup>
</li>
</ul>
</nys-verticalnav>
Active link
Set aria-current="page" on a link to mark it active. If it's inside a nys-verticalnavgroup, the group auto-expands.
<nys-verticalnav heading="NYS Design System" headingLevel="h2">
<ul>
<li><a href="/">Foundations</a></li>
<li>
<nys-verticalnavgroup label="Accessibility">
<ul>
<li><a aria-current="page" href="">WCAG Guidelines</a></li>
<li><a href="">Screen Readers</a></li>
</ul>
</nys-verticalnavgroup>
</li>
</ul>
</nys-verticalnav>
Disabled state
Add disabled to nys-verticalnavgroup to prevent the whole group from being toggled. For individual links outside a group, add aria-disabled="true" directly to the <a>. Links have no native disabled attribute, so this is the only way to mark one as unavailable.
<nys-verticalnav heading="NYS Design System" headingLevel="h2">
<ul>
<li><a href="/">Foundations</a></li>
<li><a href="/components">Components</a></li>
<li>
<nys-verticalnavgroup disabled label="Accessibility">
<ul>
<li><a aria-disabled="true">WCAG Guidelines</a></li>
<li><a href="">Screen Readers</a></li>
<li><a href="">Color Contrast</a></li>
</ul>
</nys-verticalnavgroup>
</li>
<li>
<h3>Resources</h3>
<ul>
<li><a aria-disabled="true">Design Tokens</a></li>
<li><a href="">Utilities</a></li>
</ul>
</li>
</ul>
</nys-verticalnav>
Hidden heading
A heading is required for the vertical navigation. If a visible heading is not needed on desktop, use hideHeading to visually hide it.
Note: The heading text is still used as the accessible label for the accordion on smaller screens and mobile devices (resize the screen to see this in action).
<nys-verticalnav heading="Section nav" hideHeading>
<ul>
<li><a href="/home">Home</a></li>
</ul>
</nys-verticalnav>
Page layout
Use <nys-verticalnav> alongside a global header and footer to build a full page layout. On screens below 1024px, the nav collapses into an accordion automatically.
This example uses the NYSDS grid to lay out the nav and main content side by side, switching to a stacked layout at the nys-desktop breakpoint (1024px). This approach matches the width at which <nys-verticalnav> itself collapses into an accordion.
Note: The example below is for guidance only. Adjust the styles to fit your application's layout needs. <nys-verticalnav> doesn't add its own outer spacing, so wrap it (like .page-layout__nav below) and add padding yourself to match your site's layout.
Place content here.
<style>
.page-layout__body {
background-color: var(--nys-color-white, #ffffff);
}
.page-layout__nav {
padding: var(--nys-space-300, 24px) var(--nys-space-50, 4px) var(--nys-space-300, 24px) 0;
}
.page-layout__main {
padding: var(--nys-space-400, 32px);
}
</style>
<div>
<nys-unavheader></nys-unavheader>
<nys-globalheader homepageLink="https://ny.gov" agencyName="Office of Information Technology Services">
<ul>
<li><a href="https://its.ny.gov/services">Services</a></li>
<li><a href="https://its.ny.gov/get-help">Help Center</a></li>
</ul>
</nys-globalheader>
<div class="page-layout__body">
<div class="nys-grid-container nys-grid-gap-400">
<div class="nys-grid-row">
<div class="nys-desktop:nys-grid-col page-layout__nav">
<nys-verticalnav heading="NYS Design System" headingLevel="h2">
<ul>
<li><a href="/">Foundations</a></li>
<li><a href="/components">Components</a></li>
<li>
<nys-verticalnavgroup label="Accessibility">
<ul>
<li><a href="">WCAG Guidelines</a></li>
<li><a href="">Screen Readers</a></li>
<li><a href="">Color Contrast</a></li>
</ul>
</nys-verticalnavgroup>
</li>
<li>
<h3>Resources</h3>
<ul>
<li><a href="">Design Tokens</a></li>
<li><a href="">Utilities</a></li>
</ul>
</li>
</ul>
</nys-verticalnav>
</div>
<main class="nys-desktop:nys-grid-col page-layout__main">
<p>Place content here.</p>
</main>
</div>
</div>
</div>
<nys-globalfooter agencyName="Agency Name" homepageLink="https://ny.gov">
<ul>
<li><a href="https://"> Privacy Policy </a></li>
<li><a href="https://"> Terms of Service </a></li>
</ul>
</nys-globalfooter>
<nys-unavfooter></nys-unavfooter>
</div>
Mobile controls
Call open(), close(), or toggle() on the mobile version of nys-verticalnav to control the mobile accordion programmatically.
Note: useful for a hamburger button or other trigger placed outside the nav itself. These methods only have a visible effect below the 1024px breakpoint, where the nav renders as an accordion; at desktop widths the nav is always visible.
<nys-verticalnav id="my-nav">
<ul>
<li><a href="/">Foundations</a></li>
<li><a href="/components">Components</a></li>
<li>
<nys-verticalnavgroup label="Accessibility">
<ul>
<li><a href="">WCAG Guidelines</a></li>
<li><a href="">Screen Readers</a></li>
<li><a href="">Color Contrast</a></li>
</ul>
</nys-verticalnavgroup>
</li>
<li>
<h3>Resources</h3>
<ul>
<li><a href="">Design Tokens</a></li>
<li><a href="">Utilities</a></li>
</ul>
</li>
</ul>
</nys-verticalnav>
<nys-button label="Toggle navigation (mobile view only)" onclick="document.querySelector('#my-nav').toggle()"></nys-button>
Usage
Do
- Use for navigation where every item links to a different page.
- Use for section-level navigation within a site.
- Support up to two levels of navigation: top-level links and one level of nested links.
- Set
aria-current="page"on the active link so the component can apply active styles and expand the current group. - Avoid excessive use of icons, colors, or badges in navigation items.
Don't
- Don't use for in-page navigation, such as scrolling to sections on the same page.
- Don't use for linear task flows, such as multi-step forms or wizards.
- Don't use for filtering, tab switching, or other in-page interactions.
- Don't nest more than one level of sub-items.
- Don't overload with excessive use of icons, colors, or badges in navigation items.
Properties
nys-verticalnav
| Property | Type | Default | Description |
|---|---|---|---|
heading |
String | "Page navigation" |
Heading text, and the accessible label when hideHeading is set. |
headingLevel |
"h1" | "h2" | "h3" | "h4" | "h5" | "h6" |
"h2" |
Heading tag used for the auto-generated heading. |
hideHeading |
Boolean | false |
Hides the visible heading. heading is still used as the nav's accessible label. |
nys-verticalnavgroup
| Property | Type | Default | Description |
|---|---|---|---|
label |
String | — | Text shown on the toggle button. |
expanded |
Boolean | false |
Opens the group by default. |
disabled |
Boolean | false |
Prevents the group from being toggled. |
active |
Boolean | false |
Set automatically when the group contains the active link. Not meant to be set manually. |
Style Overrides
There are no existing CSS variables for this component. Explore existing options, or propose a new one with a Component Proposal.
Events
The <nys-verticalnav> component emits one custom Javascript event:
nys-verticalnav-toggle– Fired when the mobile accordion is expanded or collapsed. This only applies on smaller screens, where the nav collapses into an accordion (see Page layout). On desktop the nav is always visible and this event does not fire.
Event details
The nys-verticalnav-toggle event includes a detail object with the following properties:
- id (string): The id of the vertical nav.
- expanded (boolean): Whether the nav is now expanded.
You can listen to these events using JavaScript:
Suggest a New Component
Do you have an idea for a new NYS Design System web component? Look through the existing proposals in our GitHub discussions board to see if someone already proposed something similar. If not, feel free to submit one.
Edit this page on GitHub (Permissions required)
Last updated: August 13, 2026