ClickorKeyboard shortcut Alt + L

Dragto resize

Nord Design System SearchDeveloperDeveloperGetting startedUsing Web ComponentsWebfontsCDNLocalizationCSS Framework Legacy ESLint PluginWorking with AIFAQDesignDesignGetting startedFoundationsThemesBrand assetsToolsComponentsComponentsAccordion New Aside New Autocomplete New AvatarBadgeBanner Updated ButtonButton GroupCalendar Updated CardCheckbox Updated Collapsible New Combobox New Command MenuDate Picker Updated Date Range Picker New DividerDrawerDropdownEmpty StateField New FieldsetFilter Bar New FooterHeaderIconInput Updated Item New Kbd New LayoutMessageMeter New ModalNavigationNotificationNumber Field New Otp Field New Outline New Pagination New Popout Updated ProgressProgress BarQrcodeRadio Updated Range Updated Scroll Area New Segmented ControlSelect Updated SkeletonSpinnerStackTabTableTagTextarea Updated Time Picker New ToastToggle Updated TooltipTop BarTruncate New Visually HiddenDesign TokensDesign TokensTailwind CSSTailwind CSSBlocksBlocksTemplatesTemplatesIconsIconsPlaygroundPlaygroundLatest UpdatesLatest UpdatesChangelogChangelogMigration guidesMigration guides
GitHub

Clickto expandKeyboard shortcut Alt + L

Aside New

Open in Storybook

A right-side rail and drawer layout for surfacing secondary content alongside the main view.

Loading...

Usage

Aside is the container for the app shell's right-side rail + drawer pattern. A persistent rail of Aside Trigger buttons sits against the edge of the screen, and each one opens an Aside Drawer panel of secondary content next to the main view.

Import the parts you need — each import registers its custom element:

import "@nordhealth/components/lib/Aside"
import "@nordhealth/components/lib/AsideDrawer"
import "@nordhealth/components/lib/AsideTrigger"

Then compose the triggers in the rail slot and the drawers in the default slot:

Composition

Aside lays out a fixed-width rail and, when a drawer is active, a resizable drawer panel beside it. The active-drawer attribute holds the id of the open drawer (empty closes them all), so a trigger, its drawer and the container stay in sync.

Aside
├── rail (slot)
│   └── AsideTrigger        (one per drawer, toggles it)
└── AsideDrawer             (one or more panels, default slot)
    └── Drawer content
<nord-aside active-drawer="details">
  <nord-aside-trigger slot="rail" drawer="details" icon="interface-info" label="Details"></nord-aside-trigger>
  <nord-aside-trigger slot="rail" drawer="activity" icon="interface-time" label="Activity"></nord-aside-trigger>

  <nord-aside-drawer id="details">
    <!-- drawer content -->
  </nord-aside-drawer>
  <nord-aside-drawer id="activity">
    <!-- drawer content -->
  </nord-aside-drawer>
</nord-aside>

Aside

Aside owns the layout and the open state. Set active-drawer to the id of the drawer to show (or "" to close), tune the rail with rail-width and rail-gap, and choose what the resize handle does with handle-click (toggle, close or none). It emits active-drawer-change, drawer-open, drawer-close, drawer-resize and handle-mode-change so your app can react to or persist the state.

Aside Drawer

Aside Drawer is a panel of content shown beside the rail. Give each one a unique id that its trigger and the container's active-drawer reference. It is resizable between min-width and max-width (starting at default-width), can expand to fullscreen, and emits width-change as it resizes.

Aside Trigger

Aside Trigger is a rail button that toggles a drawer. Point drawer at the target drawer's id, give it an icon and a label (used as the accessible name and the hover tooltip), and optionally a badge. Place it in the container's rail slot.

A trigger can also act as a navigation link: set href (with optional target and rel) instead of drawer, and it renders a real anchor — so a rail can mix drawer toggles and page links with the same look. drawer and href are mutually exclusive; when both are set, href wins.

<nord-aside>
  <!-- opens a drawer -->
  <nord-aside-trigger slot="rail" drawer="chat" icon="interface-chat" label="Chat"></nord-aside-trigger>
  <!-- navigates like a link -->
  <nord-aside-trigger slot="rail" href="/notifications" icon="navigation-notifications" label="Notifications"></nord-aside-trigger>

  <nord-aside-drawer id="chat">
    <!-- drawer content -->
  </nord-aside-drawer>
</nord-aside>

Examples

Rail collapse layout

Embedded in an app shell, the rail tucks against the edge of the layout and the active drawer opens beside the main content.

Multiple drawers

Add a trigger and a drawer per panel. Opening one drawer closes the others, since only one active-drawer is open at a time.

Badges and disabled triggers

A trigger can carry a badge to flag new or pending content, and be disabled when its drawer isn't available.

Resizable drawers

Drag the handle between the drawer and the main view to resize it between its min-width and max-width; arrow keys nudge it while the handle is focused.

Fullscreen

A drawer can expand to fill the available space for focused, content-heavy tasks.

Accessibility

  • Give every Aside Trigger a label. It becomes the button's accessible name and its hover tooltip, so the icon-only rail is understandable to assistive technology.
  • The container reflects each drawer's open state with aria-expanded on its trigger, so screen reader users hear whether a panel is open or closed.
  • A trigger's badge is decorative; convey the same information in the drawer's content or the trigger's label so it isn't lost to assistive technology.
  • The resize handle is keyboard operable — it is focusable and responds to the arrow keys — so a drawer can be resized without a pointer.

API reference

Aside

Container for the right-side rail + drawer pattern in the app shell.

<nord-accordion></nord-accordion>

Props

PropertyAttribute Description TypeDefault
activeDraweractive-drawerThe id of the currently-active <nord-aside-drawer>. Empty string means no drawer is open. Setting to an unknown / disabled id is a silent no-op.string''
railWidthrail-widthWidth of the rail column in px.number48
railGaprail-gapGap between rail and the active drawer panel in px.number0
handleClickhandle-clickControls what clicking (no-drag) the resize handle does. Drag-for-resize is independent of this attribute.AsideHandleClick'toggle'

Slots

Slot name Description
railFree-form content placed in the rail column.
tooltip-dividerTooltip anchored to the resize handle on hover.
Default slotDefault slot for <nord-aside-drawer> panels.
EventDetail TypeDescription
active-drawer-changeAsideActiveDrawerChangeEventDispatched when active-drawer changes, with activeDrawer / previousDrawer properties. Fires on every transition including open, switch, and close.
drawer-openAsideDrawerOpenEventDispatched when transitioning from no active drawer to an active one (i.e. a drawer opened from the closed state). Has an activeDrawer property.
drawer-closeAsideDrawerCloseEventDispatched when all drawers close (active-drawer went from a non-empty value to empty). Has a previousDrawer property.
drawer-resizeAsideDrawerResizeEventDispatched when the active drawer's width changes, with drawerId (the specific drawer that changed) and width properties. Unlike active-drawer-change, this names a single drawer by id rather than describing a transition between drawers.
handle-mode-changeAsideHandleModeChangeEventDispatched when the resize handle's mode changes (col-resize / pointer / default). Mirrors the current value to the host's data-handle-mode attribute so consumers can also read it synchronously. Has mode / previous properties.

CSS Properties

CSS Custom Properties provide more fine grain control over component presentation. We advise utilizing existing properties on the component before using these.

PropertyDescriptionDefault
--n-aside-rail-widthControls the inline-size of the rail column.48px
--n-aside-rail-gapControls the gap between the rail and the active drawer.var(--n-space-s)
--n-aside-rail-background-colorControls the background color of the rail column.var(--n-color-surface)
--n-aside-background-colorControls the background color of the aside container (matches the layout's main area by default).var(--n-color-background)
--n-aside-drawers-margin-inline-startInline-start margin of the drawers wrapper — creates a gap between the layout's main area and the active drawer card. The resize handle follows this margin so it stays at the drawer's edge.0
--n-aside-rail-narrow-block-sizeBlock-size of the rail when it renders as a bottom bar at <768px.56px
--n-aside-rail-narrow-padding-inlineInline padding inside the bottom rail at <768px.var(--n-space-m)
--n-aside-rail-narrow-padding-blockBlock padding inside the bottom rail at <768px.var(--n-space-s)
--n-aside-rail-narrow-border-block-start-widthTop border width of the bottom rail at <768px. Set to 0 to remove.1px
--n-aside-rail-narrow-border-colorTop border color of the bottom rail at <768px.var(--n-aside-rail-border-color)
--n-aside-drawer-floating-inset-block-startDistance from the viewport top to the floating drawer at <768px (clears the layout header).var(--n-layout-header-size, 60px)
--n-aside-drawer-floating-inset-inlineInline gap between the floating drawer and each viewport edge at <768px. Default 0 = full viewport width.0px
--n-aside-drawer-slide-durationDuration of the slide-up animation when a drawer opens at <768px.300ms
--n-aside-drawer-slide-easingEasing of the slide-up animation when a drawer opens at <768px.cubic-bezier(0.4, 0, 0.2, 1)
--n-aside-drawer-floating-inset-block-endDistance from the viewport bottom to the floating drawer at <768px. By default the drawer's bottom edge meets the rail's top edge.calc(rail-size - bottom-offset)
--n-aside-drawer-floating-bottom-offsetSubtracts from the floating drawer's inset-block-end to let the drawer extend past the rail's top edge (visual overlap). Default 0.0
--n-aside-backdrop-backgroundBackground color of the backdrop behind the floating drawer at <768px.rgb(0 0 0 / 0.4)
--n-aside-z-backdropz-index of the backdrop at <768px (above the sticky footer so it dims the footer too).calc(var(--n-index-top-bar) + 2)
--n-aside-z-drawer-floatingz-index of the floating drawer overlay at <768px (above the backdrop).calc(var(--n-index-top-bar) + 3)
--n-aside-z-rail-narrowz-index of the bottom rail at <768px (above the drawer so it remains tappable).calc(var(--n-index-top-bar) + 4)

Parts

This component is made up of the following parts.

Aside Drawer

A drawer panel inside <nord-aside>.

<nord-accordion-header></nord-accordion-header>

Props

PropertyAttribute Description TypeDefault
defaultWidthdefault-widthInitial width in px. The persisted value overrides this on load; if default-width changes between sessions, the persisted value is re-seeded to the new default.number420
minWidthmin-widthResize clamp lower bound in px.number280
maxWidthmax-widthResize clamp upper bound in px. Defaults to Number.MAX_SAFE_INTEGER so an unset max-width doesn't constrain the drawer — the consumer's layout (or the rail / nav anchoring) determines the practical ceiling. Set an explicit value to clamp. Not reflected: an unset cap is the Number.MAX_SAFE_INTEGER sentinel, which must never render into the DOM as max-width="9007199254740991".number
maxFullscreenWidthmax-fullscreen-widthMaximum inline-size in px the drawer can reach when [fullscreen] is active. Independent of max-width (which only caps the docked drag / keyboard resize) — fullscreen typically wants to grow larger than the docked maximum. Defaults to Number.MAX_SAFE_INTEGER so an unset value lets fullscreen fill all available room (bounded by the layout's left-cap rule in <nord-aside>). Not reflected: an unset cap is the Number.MAX_SAFE_INTEGER sentinel, which must never render into the DOM.number
disableddisabledWhen set, the drawer cannot be opened. Programmatic opens are silently ignored; if the drawer is already open and this flips on, the drawer stays open until closed normally.booleanfalse
fullscreenfullscreenReflected. Phase 3 wires the overlay sizing internally.booleanfalse
floatingfloatingSet by the parent <nord-aside> when the drawer renders as a narrow floating overlay (rather than a docked region). When true the host becomes an accessible modal dialog (role="dialog" + aria-modal); when false the host is a role="region" landmark. Drive this only through the parent — it owns the floating-vs-docked decision.booleanfalse

Slots

Slot name Description
Default slotDefault slot. Place arbitrary drawer content here.
EventDetail TypeDescription
width-changeAsideDrawerWidthChangeEventDispatched when the drawer's width changes. The event exposes width (the new applied inline-size in px) and source ('drag' | 'keyboard' | 'attribute' | 'storage').

Aside Trigger

Rail button that toggles a <nord-aside-drawer> inside <nord-aside>, or navigates like a link when href is set.

<nord-accordion-item></nord-accordion-item>

Props

PropertyAttribute Description TypeDefault
drawerdrawerThe id of the <nord-aside-drawer> this trigger toggles. Mutually exclusive with href — when both are set, href wins and the trigger acts as a link instead of a drawer toggle.string''
hrefhrefWhen provided, renders the trigger as a link that navigates to the given URL instead of toggling a drawer. Mutually exclusive with drawer. Mirrors nord-button's link mode, so middle-click, cmd/ctrl-click and right-click behave like a real anchor.string | undefined
targettargetWhen provided together with a href property, determines where to open the linked URL. Forwarded to the underlying anchor.'_self' | '_blank' | '_parent' | '_top' | undefined
relrelWhen provided together with a href property, sets the relationship between the linked URL and the current document, e.g. “noopener noreferrer” when linking to untrusted content in a new tab.string | undefined
iconiconNord icon name. Shortcut for the common case; equivalent to placing <nord-icon name="…"> in the default slot.string | undefined
labellabelAccessible label (used for aria-label on the host).string''
badgebadgeOptional badge content (forwarded to inner <nord-badge>).string | number | undefined
disableddisabledMakes the trigger disabled. Takes precedence over the target drawer's disabled state.booleanfalse
tooltiptooltipWhether to render a <nord-tooltip> showing label on hover/focus. Defaults to true — set tooltip="false" (or omit label) to opt out.booleantrue

Slots

Slot name Description
Default slotOverrides the icon attribute for custom leading content.
tooltipOverrides the tooltip body (falls back to label). Lets consumers add icons, shortcut hints, etc. — anything beyond the plain string label.
Design guidelinesFor designers

Usage

This section includes guidelines for designers and developers about the usage of this component in different contexts.

Do

  • Use as the right-side rail + drawer container in the app shell.
  • Mix <nord-aside-trigger>s with plain <nord-button>s or <a>s in the rail slot — triggers toggle drawers, plain buttons/links are for navigation-only items.
  • Place one or more <nord-aside-drawer> panels in the default slot; the aside shows the one whose id matches active-drawer.
  • Let consumers drive the open state via the active-drawer attribute and the active-drawer-change event.

Don’t

  • Don’t put more than one <nord-aside> on the page — it owns app-shell-level state.
  • Don’t open multiple drawers at once. The aside is single-active by design.
  • Don’t wrap navigation-only rail items in <nord-aside-trigger> — use a plain <nord-button> or <a> instead.

Additional considerations

  • Owns the single-active drawer state and the inline-start resize handle. Drag-for-resize is independent of handle-click, which only controls the click (no-drag) behaviour: toggle, close, or none.
  • Width and gap of the rail column are configurable via --n-aside-rail-width and --n-aside-rail-gap.
  • Emits active-drawer-change with { activeDrawer, previousDrawer } and drawer-resize with { drawerId, width }.