App bar

An app bar is a <header> with a row inside it. The pieces are separate so you can arrange them: appBarNav() for links, appBarSpacer() to push what follows to the far end, and appBarActions() for the buttons at the end.

Basic app bar

sitelo
appBar({ brand: 'sitelo' },
  appBarSpacer(),
  appBarActions(
    button({ size: 'sm', variant: 'soft' }, 'Sign in'),
  ),
)

With navigation

navLink() is the link style for a bar; current marks the active page with aria-current as well as colour.

sitelo
appBar({ brand: 'sitelo' },
  appBarNav(
    navLink({ href: '#docs', current: true }, 'Docs'),
    navLink({ href: '#ui' }, 'UI'),
    navLink({ href: '#examples' }, 'Examples'),
  ),
  appBarSpacer(),
  appBarActions(
    button({ size: 'sm', variant: 'outline', color: 'neutral' }, 'GitHub'),
    button({ size: 'sm' }, 'Get started'),
  ),
)

A brand with a mark

The brand takes any markup, and links to / unless href says otherwise.

Ssitelo
v2.6.3
appBar({
  href: '#home',
  brand: stack({ direction: 'row', gap: 'sm', inline: true, align: 'center' },
    avatar({ name: 'S', size: 'sm', square: true, color: 'primary' }),
    'sitelo',
  ),
},
  appBarSpacer(),
  appBarActions(chip({ size: 'sm', color: 'neutral' }, 'v2.6.3')),
)

Sticky and blurred

sticky pins the bar to the top of the scroll container; blur makes it translucent so content passes under it. Both are shown here inside a scrolling box rather than on the page itself.

sitelo
sticky

Scroll me — paragraph 1.

Scroll me — paragraph 2.

Scroll me — paragraph 3.

Scroll me — paragraph 4.

Scroll me — paragraph 5.

Scroll me — paragraph 6.

div({ style: 'height: 12rem; overflow: auto; border: 1px solid var(--su-border); border-radius: 0.6rem' },
  appBar({ brand: 'sitelo', sticky: true, blur: true },
    appBarSpacer(),
    appBarActions(chip({ size: 'sm', color: 'primary' }, 'sticky')),
  ),
  container({ size: 'sm', style: 'padding-block: 1rem' },
    stack({ gap: 'md' },
      ...Array.from({ length: 6 }, (unused, index) =>
        text({ variant: 'small', tone: 'muted' }, 'Scroll me — paragraph ' + (index + 1) + '.'),
      ),
    ),
  ),
)

With a drawer on small screens

The usual pattern: links in the bar on desktop, a button that opens a drawer() on a phone. The drawer is a popover, so the button needs no script.

fragment(
  appBar({ brand: 'sitelo' },
    appBarSpacer(),
    appBarActions(
      themeToggle(),
      iconButton({
        label: 'Open navigation',
        variant: 'ghost',
        color: 'neutral',
        popovertarget: 'app-bar-drawer',
        icon: icon('menu'),
      }),
    ),
  ),
  drawer({ id: 'app-bar-drawer', title: 'Navigation' },
    navLink({ href: '#docs' }, 'Docs'),
    navLink({ href: '#ui' }, 'UI'),
    navLink({ href: '#examples' }, 'Examples'),
  ),
)

Props

appBar():

PropTypeDefaultDescription
brandChildContent of the brand link at the start.
hrefstring'/'Where the brand links to.
stickybooleanfalsePins the bar to the top on scroll.
blurbooleanfalseTranslucent background with a backdrop blur.
asstring'header'Element to render.

The pieces:

PiecePropsDefaultDescription
appBarNavA nav element holding the links.
appBarSpacerFlexible gap; everything after it goes to the far end.
appBarActionsTrailing cluster of buttons.
navLinkhref, current, colorA link styled for the bar; current marks the active page.