Skip to content
WovenUI LogoWovenUI

Blocks

Navbar pattern

A top navigation bar with a wordmark, four page links and an account link. Below the md breakpoint the links move to their own row.

Preview

Live preview of the navbar, rendered from the HTML on this page.

HTML to copy

The markup of the preview, in WovenUI core utility classes. It needs only the prebuilt@wovenui/core/dist/wovenui.min.css, or your own build with $generate-utility-classes: true. No components package and no JavaScript.

HTML
<header class="bg-surface text-regular border-b">
    <nav class="flex wrap between x-center gap-x-6 gap-y-3 px-4 px-6@md py-3" aria-label="Primary">
        <a class="text-lg font-semibold text-regular" href="/">Northwind</a>
        <ul class="flex gap-5 m-0 p-0 text-sm w-full w-auto@md order-last order-none@md" role="list">
            <li><a class="text-regular font-medium" href="/" aria-current="page">Overview</a></li>
            <li><a class="text-muted hover:text-regular" href="/projects/">Projects</a></li>
            <li><a class="text-muted hover:text-regular" href="/reports/">Reports</a></li>
            <li><a class="text-muted hover:text-regular" href="/team/">Team</a></li>
        </ul>
        <a class="border rounded-md px-3 py-1 text-sm font-medium text-regular hover:bg-hover" href="/account/">Account</a>
    </nav>
</header>

With apply()

The same result with BEM class names and no utility classes. @use "@wovenui/core" as *; emits the tokens and base styles, and each apply() writes one rule.

SCSS
@use "@wovenui/core" as *;

.navbar {
    @include apply(
        bg(surface), // surface background, follows the theme
        text-color(regular), // regular text color, follows the theme
        border-bottom(1) // 1px bottom border (width key 1), regular color
    );
}

.navbar__inner {
    @include apply(
        flex, // display: flex
        wrap, // let items wrap onto new lines
        between, // main axis: space between (justify-content)
        x-center, // cross axis: center (align-items)
        gap-x(6), // column gap: spacing key 6 (1.5rem)
        gap-y(3), // row gap: spacing key 3 (0.75rem)
        px(4), // horizontal padding: spacing key 4 (1rem)
        px(6) md, // horizontal padding key 6 (1.5rem) from md (768px) up
        py(3) // vertical padding: spacing key 3 (0.75rem)
    );
}

.navbar__brand {
    @include apply(
        font-size(lg), // font size key lg (1.25rem)
        font(semibold), // font weight: semibold (600)
        text-color(regular) // regular text color, follows the theme
    );
}

// Own row below md, back between the brand and the action from md
.navbar__links {
    @include apply(
        flex, // display: flex
        gap(5), // gap: spacing key 5 (1.25rem)
        m(0), // margin: 0
        p(0), // padding: 0
        w-full, // width: 100%
        w-auto md, // width: auto from md (768px) up
        font-size(sm) // font size key sm (0.875rem)
    );

    order: 1;

    @include media-up(md) {
        order: 0;
    }
}

.navbar__link {
    @include apply(
        text-color(muted), // muted text color, follows the theme
        text-color(regular) hover // regular text color on hover
    );

    &[aria-current="page"] {
        @include apply(
            text-color(regular), // regular text color, follows the theme
            font(medium) // font weight: medium (500)
        );
    }
}

.navbar__action {
    @include apply(
        px(3), // horizontal padding: spacing key 3 (0.75rem)
        py(1), // vertical padding: spacing key 1 (0.25rem)
        border(1), // 1px border (width key 1), regular color
        rounded(md), // corner radius: size key md (0.5rem)
        font-size(sm), // font size key sm (0.875rem)
        font(medium), // font weight: medium (500)
        text-color(regular), // regular text color, follows the theme
        bg(hover) hover // hover background on hover
    );
}

.navbar a:focus-visible {
    outline: token(border-focus-width) solid token(border-focus);
    outline-offset: token(border-focus-offset);
}
HTML
<header class="navbar">
    <nav class="navbar__inner" aria-label="Primary">
        <a class="navbar__brand" href="/">Northwind</a>
        <ul class="navbar__links" role="list">
            <li><a class="navbar__link" href="/" aria-current="page">Overview</a></li>
            <li><a class="navbar__link" href="/projects/">Projects</a></li>
            <li><a class="navbar__link" href="/reports/">Reports</a></li>
            <li><a class="navbar__link" href="/team/">Team</a></li>
        </ul>
        <a class="navbar__action" href="/account/">Account</a>
    </nav>
</header>

Tokens used

Every color comes from a theme token, so the pattern follows the light, dark and inverse themes with no extra CSS.

bg-surface, text-regular
Bar background and the wordmark.
border-regular
The bottom rule and the account link outline.
text-muted
Links at rest; text-regular on hover and for the current page.
bg-hover
Account link hover.
border-focus, border-focus-width, border-focus-offset
The keyboard focus ring in the SCSS version.