Usage
Outline is an in-page table of contents for long documents, help centres, wikis and long settings pages. It lists the headings on a page, indents them by level, and highlights the section currently in view with an animated indicator as the reader scrolls.
Use it for navigation within a single page. For moving between application routes use Navigation instead, and for expandable, collapsible hierarchy reach for a tree.
Import the parts you need — each import registers its custom element:
import "@nordhealth/components/lib/Outline"
import "@nordhealth/components/lib/OutlineItem"
Then list your page's headings, linking each item to a heading id:
Composition
Outline combines a container with individual items. Each Outline Item links to a heading in your content via href and reports its nesting level (1–4), which drives its indentation.
Outline
├── OutlineItem (level 1)
├── OutlineItem (level 2)
└── OutlineItem (level 1)
<nord-outline>
<nord-outline-item href="#introduction" level="1">Introduction</nord-outline-item>
<nord-outline-item href="#installation" level="1">Installation</nord-outline-item>
<nord-outline-item href="#cdn" level="2">CDN</nord-outline-item>
<nord-outline-item href="#usage" level="1">Usage</nord-outline-item>
</nord-outline>
Outline
Outline is the container. It exposes a navigation landmark with a default accessible label, owns the sliding indicator, and tracks which section is active. Each href should point at the id of a heading on the same page; clicking an item smoothly scrolls to that heading.
Outline Item
Outline Item is a single link in the list. Set its href to the target heading's fragment (for example #installation) and its level (1–4) to match the heading depth — higher levels are indented further. Its active state is managed by the parent Outline, so you don't set it yourself.
Scroll-spy
By default Outline watches the headings referenced by its items and highlights the one currently in view, animating the indicator to follow as the reader scrolls. No configuration is required — just make sure every href matches a real heading id on the page.
<!-- Headings somewhere on the page -->
<h2 id="introduction">Introduction</h2>
<h2 id="installation">Installation</h2>
<h2 id="usage">Usage</h2>
<!-- The outline, typically sticky in a sidebar -->
<nord-outline class="n:sticky n:inset-bs-m">
<nord-outline-item href="#introduction">Introduction</nord-outline-item>
<nord-outline-item href="#installation">Installation</nord-outline-item>
<nord-outline-item href="#usage">Usage</nord-outline-item>
</nord-outline>
Generating from content
Instead of listing items by hand, point for at a content container and Outline builds the list automatically from that container's headings. Headings without an id are given one so they can be linked. Use heading-selector to control which headings are collected (it defaults to h1, h2, h3, h4).
<article id="docs-content">
<h2 id="introduction">Introduction</h2>
<h3 id="prerequisites">Prerequisites</h3>
<h2 id="usage">Usage</h2>
</article>
<nord-outline for="docs-content"></nord-outline>
Examples
Nesting levels
Heading levels 1–4 map to progressively deeper indentation, so a long document with sub-sections stays scannable.
Density
Use density="compact" in dense sidebars where vertical space is tight.
Controlled
Set active to the id of the section you want highlighted. Providing active puts the Outline in controlled mode and disables the built-in scroll-spy, so your own logic owns the highlight. Listen to the change event to react when the active section changes.
Accessibility
- Outline renders a
navigationlandmark with a default accessible label (“On this page”). Override it witharia-labelwhen a page has more than one navigation region, or to better describe the outline's scope. - Each item's
hrefmust match theidof a real heading on the page so the link, scroll-spy and the “skip to section” behaviour all work. - Set each item's
levelto match the depth of the heading it links to, so the visual nesting mirrors the document's heading structure. - The active item is exposed with
aria-current="location"for assistive technology. - The indicator animation respects the user's
prefers-reduced-motionsetting.
API reference
Outline
Outline is an in-page table of contents that lists a page's headings and
highlights the section currently in view as you scroll.
Provide Outline Item children, or point for at
a container to build the list from its headings.
<nord-outline></nord-outline>Props
| Property | Attribute | Description | Type | Default |
|---|---|---|---|---|
active | active | The id of the active heading. Setting this puts the Outline in controlled
mode and disables the built-in scroll-spy, so your own logic owns the
highlight (mirrors providing activeId in other libraries). | string | undefined | — |
density | density | Tightens spacing for dense sidebars where vertical space is at a premium. | 'default' | 'compact' | 'default' |
for | for | DOM-scan mode: the id (or any CSS selector) of the content container whose headings should populate the outline. When set, slotted children are ignored and items are generated from the matched headings. | string | undefined | — |
headingSelector | heading-selector | The selector used to find headings when for is set. | string | 'h1,h2,h3,h4' |
scrollContainer | scroll-container | CSS selector for the element that scrolls the content, used as the
scroll-spy IntersectionObserver root. Point this at your scroll container
when the page scrolls inside an element rather than the window — otherwise
the observer watches the window and never sees the headings move. If the
selector resolves to a nord-scroll-area, its scroll viewport is used.
When unset, the nearest ancestor nord-scroll-area of the scanned content
is detected automatically, falling back to the window. | string | undefined | — |
hideHeader | hide-header | Hides the header. By default Outline shows a localized "On this page"
heading (or the header slot's content) above the list. | boolean | false |
Slots
| Slot name | Description |
|---|---|
Default slot | The default slot for Outline Item children. |
header | Custom header content shown above the list. Overrides the default localized "On this page" heading. Set hide-header to remove the header entirely. |
| Event | Detail Type | Description |
|---|---|---|
change | NordOutlineChangeEvent | Dispatched when the active section changes. Includes an activeId property. |
CSS Properties
CSS Custom Properties provide more fine grain control over component presentation. We advise utilizing existing properties on the component before using these.
| Property | Description | Default |
|---|---|---|
--n-outline-indicator-color | Color of the sliding active indicator. | var(--n-color-accent) |
--n-outline-track-color | Color of the static track behind the indicator. | var(--n-color-border) |
--n-outline-indicator-width | Thickness of the track and indicator. | 2px |
--n-outline-indent | Indentation step applied per heading level. | var(--n-space-m) |
--n-outline-header-color | Color of the default header text. | var(--n-color-text-weaker) |
--n-outline-header-font-size | Font size of the default header text. | var(--n-font-size-s) |
Parts
This component is made up of the following parts.
Outline Item
Outline Item is a single link within an Outline. It
points at an in-page heading via its href and indents according to its
level. Its active state is managed by the parent Outline — you normally
don't set it yourself.
<nord-outline-item></nord-outline-item>Props
| Property | Attribute | Description | Type | Default |
|---|---|---|---|---|
href | href | The URL fragment of the heading this item links to, e.g. #installation. | string | '' |
level | level | Heading depth from 1 to 4. Controls how far the item is indented. | 1 | 2 | 3 | 4 | 1 |
active | active | Whether this item represents the currently active section. Managed by the
parent Outline via its scroll-spy or active property. | boolean | false |
Slots
| Slot name | Description |
|---|---|
Default slot | The label text for the heading this item links to. |
CSS Properties
CSS Custom Properties provide more fine grain control over component presentation. We advise utilizing existing properties on the component before using these.
| Property | Description | Default |
|---|---|---|
--n-outline-item-color | Text color in the default state. | var(--n-color-text-weak) |
--n-outline-item-color-hover | Text color on hover. | var(--n-color-text) |
--n-outline-item-color-active | Text color when the item is active. | var(--n-color-text-link) |
Design guidelinesFor designers
Usage
This section includes guidelines for designers and developers about the usage of this component in different contexts.
Do
- Use Outline as a table of contents for navigation within a single long page, such as documentation, help articles or long settings pages.
- Pass a flat, ordered list of Outline Item children and let
levelcontrol the indentation. - Set
activewhen your own scroll logic owns the active section — this disables the built-in scroll-spy. - Use
density="compact"in dense sidebars where vertical space is tight. - Use
forto generate the outline from a content container's headings automatically.
Don’t
- Don’t use Outline for application navigation between routes — use Navigation instead.
- Don’t use Outline for expandable, collapsible hierarchy.
- Don’t place a
<nav>element inside the outline, as the host already exposes a navigation landmark.
Content guidelines
Outline item labels should match the headings they link to. Write them in sentence case, keep them short, and avoid ending in punctuation: