Skip to content

NbAccordion is a stack of headings that reveal their content when clicked. It is the plain disclosure for page body: NbShellPanel looks similar but is an inspector section, carrying a size control and expecting a panel rail around it.

vue
<NbAccordion>
  <NbAccordionItem title="What a blueprint card is">
    A node in a graph.
  </NbAccordionItem>
  <NbAccordionItem title="What a port is"> One element. </NbAccordionItem>
</NbAccordion>

When to use it ​

Carbon's guidance holds here, and it is mostly about restraint.

  • Do use it to shorten a page whose content is not all essential, and to group related detail a reader can choose to open.
  • Don't use it when the reader is likely to want everything. An accordion then charges them a click per section for no benefit; a scrolling page with ordinary headings is better.
  • Don't use it for nested hierarchy. Reach for NbTree instead.

Content inside a closed panel stays in the DOM, so find-in-page still reaches it. That is deliberate: an accordion is progressive disclosure, not lazy loading. If a section is genuinely expensive, defer it yourself from the toggle event.

One open, or several ​

By default opening a section closes the last one, which keeps the page short. Set multiple when sections are meant to be compared.

Icons and meta ​

icon puts a mark before the title; meta puts a count or a status after it, before the chevron.

Flush, for panels and sidebars ​

flush drops the side inset so titles line up with the content above them, and stops two nearly-touching rule lines appearing where a bordered accordion meets a bordered panel. Hover and focus still reach into the gutter, so a row is still a row.

Sizes ​

Chevron placement ​

The chevron sits at the end by default, so every title starts on the same line as the type around it. align="start" puts it in front, which makes the accordion read as a tree; use it only when the content really is hierarchical.

Controlled ​

Bind v-model to drive which sections are open from outside, for example to open one from a URL. The value is always an array, including when multiple is false, so the binding does not change shape if you change your mind later.

vue
<script setup>
const open = ref(['shipping'])
</script>

<template>
  <NbAccordion v-model="open" multiple>
    <NbAccordionItem id="shipping" title="Shipping" />
    <NbAccordionItem id="returns" title="Returns" />
  </NbAccordion>
</template>

Pass an explicit id on every item when you do this. Without one an id is generated, and a generated id is not a thing you can meaningfully persist.

Keyboard ​

KeyDoes
TabMoves to the next header, skipping the panels' contents
Enter / SpaceOpens or closes the focused section
↑ / ↓Moves between headers, wrapping
Home / EndJumps to the first or last header

Each header is a <button> inside a role="heading" element. The heading is what lets a screen reader list the sections; the button is what operates them.

Set headingLevel to fit the accordion into the page's outline. It defaults to 3.

vue
<NbAccordion :heading-level="2">
  <NbAccordionItem title="Under an h1" />
</NbAccordion>

The heading is a role="heading" div rather than an <h3> on purpose. A real <h3> inherits any some-container h3 { margin } the host page has, and an element selector inside a class outranks a component's own scoped rule, so the component cannot defend against it. That is not theoretical: it was adding 20px above every title in these very docs.

NbAccordion props ​

PropTypeDefaultDescription
modelValuestring[]—Ids of the open items. Always an array, whatever multiple is set to.
multiplebooleanfalseAllow more than one item open at once.
flushbooleanfalseDrop the side inset and the outer border, for panels and sidebars.
align'start' | 'end''end'Chevron placement. start reads as a tree; prefer end.
size'sm' | 'md' | 'lg''md'Row height: 32, 40 or 48px.

NbAccordion events ​

EventPayloadDescription
update:modelValuestring[]The new set of open ids.
toggle[id: string, open: boolean]One item changed. Cheaper than diffing modelValue to lazily load a section.

NbAccordionItem props ​

PropTypeDefaultDescription
idstringautoStable identifier used in modelValue. Pass one if the state is persisted.
titlestring''Header text. Use the title slot for anything richer.
iconstring—Icon name, rendered before the title.
metastring''Short text after the title: a count, a status.
disabledbooleanfalseRenders muted and cannot be toggled.

NbAccordionItem slots ​

SlotDescription
defaultThe panel's content.
titleReplaces the title prop.
metaReplaces the meta prop.