Sections
Navigation
Our navigation component is a collection of pill-shaped buttons that respond gracefully to various window sizes and parent containers.
Classes
Section titled ClassesClass | Applies to | Description |
---|---|---|
.s-navigation |
N/A | Base parent container for navigation |
.s-navigation__vertical |
.s-navigation |
Renders the navigation vertically |
.s-navigation__muted |
.s-navigation |
Secondary navigation style. To be used on pages that already have a primary navigation |
.s-navigation__scroll |
.s-navigation |
When the navigation items overflow the width of the component, enable horizontal scrolling. By default, navigation items will wrap. This should not be applied to vertical navigations. |
.s-navigation__sm |
.s-navigation |
Tightens up the overall spacing and reduces the text size |
.s-navigation--item |
Child of .s-navigation |
The individual pill-shaped link in a navigation |
.is-selected |
.s-navigation--item |
Applies to a navigation item that’s currently selected / active |
Horizontal
Section titled HorizontalCare should be taken to only include at most one primary and one secondary navigation per page. Using multiple navigations with the same style can cause user confusion.
Forcing a navigation to scroll is an established pattern on mobile devices, so it may be appropriate to use it in that context. Wrapping tends to make more sense on larger screens, where the user isn’t forced to scroll passed a ton of navigation chrome.
Default
Section titled Default<nav>
<ul class="s-navigation">
<li><a href="…" class="s-navigation--item is-selected">…</a></li>
<li><a href="…" class="s-navigation--item">…</a></li>
<li><a href="…" class="s-navigation--item">…</a></li>
<li><a href="…" class="s-navigation--item">…</a></li>
<li><a href="…" class="s-navigation--item">…</a></li>
</ul>
</nav>
Full width
Wrapped
Muted
Section titled Muted<nav>
<ul class="s-navigation s-navigation__muted">
<li><a href="…" class="s-navigation--item is-selected">…</a></li>
<li><a href="…" class="s-navigation--item">…</a></li>
<li><a href="…" class="s-navigation--item">…</a></li>
<li><a href="…" class="s-navigation--item">…</a></li>
<li><a href="…" class="s-navigation--item">…</a></li>
</ul>
</nav>
Full width
Wrapped
Scrolling
Section titled Scrolling<nav>
<ul class="s-navigation s-navigation__scroll">
<li><a href="…" class="s-navigation--item is-selected">…</a></li>
<li><a href="…" class="s-navigation--item">…</a></li>
<li><a href="…" class="s-navigation--item">…</a></li>
<li><a href="…" class="s-navigation--item">…</a></li>
<li><a href="…" class="s-navigation--item">…</a></li>
</ul>
</nav>
Small
Section titled Small<nav>
<ul class="s-navigation s-navigation__sm">
<li><a href="…" class="s-navigation--item is-selected">…</a></li>
<li><a href="…" class="s-navigation--item">…</a></li>
<li><a href="…" class="s-navigation--item">…</a></li>
<li><a href="…" class="s-navigation--item">…</a></li>
<li><a href="…" class="s-navigation--item">…</a></li>
</ul>
</nav>
Vertical
Section titled VerticalStacks also provides a vertical variation with support for section headers.
Default
Section titled Default<nav>
<ul class="s-navigation s-navigation__vertical">
<li><a href="…" class="s-navigation--item is-selected">…</a></li>
<li><a href="…" class="s-navigation--item">…</a></li>
<li><a href="…" class="s-navigation--item">…</a></li>
<li><a href="…" class="s-navigation--item">…</a></li>
<li><a href="…" class="s-navigation--item">…</a></li>
</ul>
</nav>
Titles
Section titled Titles<nav>
<ul class="s-navigation s-navigation__vertical">
<li class="s-navigation--title">…</li>
<li><a href="…" class="s-navigation--item is-selected">…</a></li>
<li><a href="…" class="s-navigation--item">…</a></li>
<li class="s-navigation--title">…</li>
<li><a href="…" class="s-navigation--item">…</a></li>
<li><a href="…" class="s-navigation--item">…</a></li>
<li><a href="…" class="s-navigation--item">…</a></li>
<li><a href="…" class="s-navigation--item">…</a></li>
<li><a href="…" class="s-navigation--item">…</a></li>
</ul>
</nav>
Buttons
Section titled ButtonsThis component can be used for in-page navigation patterns, using button
elements in place of link. When doing so, it may be appropriate to annotate elements with role="tablist"
to indicate the dynamic behavior.
<nav>
<ul role="tablist" class="s-navigation">
<li><button type="button" class="s-navigation--item is-selected" role="tab" aria-selected="true">…</button></li>
<li><button type="button" class="s-navigation--item" role="tab" aria-selected="false">…</button></li>
<li><button type="button" class="s-navigation--item" role="tab" aria-selected="false">…</button></li>
</ul>
</nav>
Interactive tabs
Section titled Interactive tabsStacks provides a Stimulus controller for interactive tab-style navigation within a single document.
Attributes
Section titled AttributesAttribute | Applied to | Description |
---|---|---|
data-controller="s-navigation-tablist" |
.s-navigation |
Wires up the element to the tooltip controller. |
role="tablist" |
.s-navigation |
Indicates to accessibility tools that the navigation element is a tab list. |
role="tab" |
.s-navigation--item |
Indicates to accessibility tools that the navigation item is a tab. Used by the controller to automatically connect mouse and keyboard events. |
class="s-navigation--item is-selected" |
Initially selected .s-navigation--item elements |
Provides visual indication that the tab is selected. |
aria-selected="{true|false}" |
.s-navigation--item |
Indicates to accessibility tools which tab is selected. Used by the controller to track the selected tab. |
id="{TAB_ID}" |
.s-navigation--item |
A unique id for the tab. Will be used by the tab panel to refer back to the button via aria-labelledby="{TAB_ID}" . |
aria-controls="{PANEL_ID}" |
.s-navigation--item |
A unique id for the panel element corresponding to the tab. |
tabindex="-1" |
Initially unselected .s-navigation--item elements |
Indicates to the browser that the element should be excluded from tab navigation. When interacting with the control, arrow keys will be used to switch tabs. |
role="tabpanel" |
Tab panel elements | Indicates to accessibility tools that the element is a panel corresponding to a tab. |
id="{PANEL_ID}" |
Tab panel elements | A unique id for the panel. Used by the tab to identify the panel that will be shown when it is active, via aria-controls="{PANEL_ID}" . |
aria-labelledby="{TAB_ID}" |
Tab panel elements | Refers to the id of the tab element that corresponds to the panel. |
class="d-none" |
Initially hidden tab panel elements | Suppressed display of tab panels. |
Events
Section titled EventsEvent | Element | Description |
---|---|---|
s-navigation-tablist:select |
Controller element | Default preventable Fires immediately before a new tab is selected. Calling .preventDefault() cancels the display of the tab and keeps the state unchanged. |
s-navigation-tablist:selected |
Controller element | Fires immediately after the new tag has been selected. |
event.detail | Applicable events | Description |
---|---|---|
oldTab |
s-navigation-tablist:* |
Contains HTMLElement | null representing the previously selected tab, if one was selected. This is the element with role="tab" , not the panel itself which can be found using the tab's aria-controls attribute. |
newTab |
s-navigation-tablist:* |
Contains HTMLElement representing the newly selected tab. This is the element with role="tab" , not the panel itself which can be found using the tab's aria-controls attribute. |
Example
Section titled Example<nav>
<ul class="s-navigation" role="tablist" data-controller="s-navigation-tablist">
<li>
<button type="button"
role="tab"
id="tab-question"
aria-selected="true"
aria-controls="panel-question"
class="s-navigation--item is-selected">Task</button>
</li>
<li>
<button type="button"
role="tab"
id="tab-answers"
aria-selected="false"
aria-controls="panel-answers"
tabindex="-1"
class="s-navigation--item">Answers</button>
</li>
</ul>
</nav>
<div id="panel-question" aria-labelledby="tab-question">
…
</div>
<div id="panel-answers" aria-labelledby="tab-answers" class="d-none">
…
</div>
…
…
…
…