Skip to content

Header

Experimental Alpha

This library is a work-in-progress. We are releasing it early to gather feedback, but it is not ready for production.

The Header component provides a semantic, accessible, and responsive page header with support for branding/logo and navigation content. It features sticky positioning, flexible content alignment, and responsive behavior.

Examples

Vue
Lit
React
Live Preview

Basic Header

A simple header with logo and navigation. On mobile, content stacks vertically. On desktop (≥960px), it displays horizontally.

Header with Logo Image

Content Justification

Control how content is aligned within the header using the contentJustify prop.

Justify: Between (Default)

Logo

Justify: Start

Logo

Justify: End

Logo

Justify: Center

Logo

Justify: Around

Logo

Sticky Header

Sticky headers remain visible at the top of the viewport when scrolling. Scroll down in the demo below to see it in action.

Sticky Header

Section 1

Scroll down to see the sticky behavior. The header stays at the top.

Section 2

The header remains visible as you scroll through content.

End of scrollable content.

CSS Shadow Parts Customization

Use CSS Shadow Parts to customize the header's appearance without affecting its internal structure.

View Vue Code
<template>
  <section class="ag-header-examples">
    <div class="mbe4">
      <h2>Basic Header</h2>
      <p class="mbs2 mbe3">
        A simple header with logo and navigation. On mobile, content stacks vertically. On desktop (≥960px), it displays horizontally.
      </p>
    </div>
    <div class="mbe4">
      <VueHeader>
        <template #logo>
          <a
            href="#"
            style="text-decoration: none; color: var(--vp-c-brand-1); font-weight: 700; font-size: 1.25rem;"
          >
            AgnosticUI
          </a>
        </template>
        <nav>
          <ul style="display: flex; gap: 1.5rem; list-style: none; margin: 0; padding: 0;">
            <li><a
                href="#home"
                style="text-decoration: none; color: inherit;"
              >Home</a></li>
            <li><a
                href="#about"
                style="text-decoration: none; color: inherit;"
              >About</a></li>
            <li><a
                href="#contact"
                style="text-decoration: none; color: inherit;"
              >Contact</a></li>
          </ul>
        </nav>
      </VueHeader>
    </div>

    <div class="mbe4">
      <h2>Header with Logo Image</h2>
    </div>
    <div class="mbe4">
      <VueHeader>
        <template #logo>
          <a
            href="#"
            style="display: flex; align-items: center; gap: 0.5rem; text-decoration: none; color: inherit;"
          >
            <svg
              width="32"
              height="32"
              viewBox="0 0 32 32"
              fill="currentColor"
              style="color: var(--vp-c-brand-1);"
            >
              <circle
                cx="16"
                cy="16"
                r="14"
                fill="var(--ag-primary)"
              />
              <text
                x="16"
                y="22"
                text-anchor="middle"
                fill="white"
                font-size="16"
                font-weight="bold"
              >A</text>
            </svg>
            <span style="font-weight: 700; font-size: 1.25rem;">MyApp</span>
          </a>
        </template>
        <nav>
          <ul style="display: flex; gap: 2rem; list-style: none; margin: 0; padding: 0;">
            <li><a
                href="#dashboard"
                style="text-decoration: none; color: inherit;"
              >Dashboard</a></li>
            <li><a
                href="#settings"
                style="text-decoration: none; color: inherit;"
              >Settings</a></li>
            <li><a
                href="#profile"
                style="text-decoration: none; color: inherit;"
              >Profile</a></li>
          </ul>
        </nav>
      </VueHeader>
    </div>

    <div class="mbe4">
      <h2>Content Justification</h2>
      <p class="mbs2 mbe3">
        Control how content is aligned within the header using the <code>contentJustify</code> prop.
      </p>
    </div>
    <div class="mbe4">
      <div class="mbe3">
        <h3
          class="mbe2"
          style="font-size: 1rem; font-weight: 600;"
        >Justify: Between (Default)</h3>
        <VueHeader contentJustify="between">
          <template #logo>
            <a
              href="#"
              style="text-decoration: none; color: inherit; font-weight: 600;"
            >Logo</a>
          </template>
          <nav>
            <a
              href="#nav"
              style="text-decoration: none; color: inherit;"
            >Navigation</a>
          </nav>
        </VueHeader>
      </div>

      <div class="mbe3">
        <h3
          class="mbe2"
          style="font-size: 1rem; font-weight: 600;"
        >Justify: Start</h3>
        <VueHeader contentJustify="start">
          <template #logo>
            <a
              href="#"
              style="text-decoration: none; color: inherit; font-weight: 600;"
            >Logo</a>
          </template>
          <nav style="margin-left: 2rem;">
            <a
              href="#nav"
              style="text-decoration: none; color: inherit;"
            >Navigation</a>
          </nav>
        </VueHeader>
      </div>

      <div class="mbe3">
        <h3
          class="mbe2"
          style="font-size: 1rem; font-weight: 600;"
        >Justify: End</h3>
        <VueHeader contentJustify="end">
          <template #logo>
            <a
              href="#"
              style="text-decoration: none; color: inherit; font-weight: 600;"
            >Logo</a>
          </template>
          <nav style="margin-left: 2rem;">
            <a
              href="#nav"
              style="text-decoration: none; color: inherit;"
            >Navigation</a>
          </nav>
        </VueHeader>
      </div>

      <div class="mbe3">
        <h3
          class="mbe2"
          style="font-size: 1rem; font-weight: 600;"
        >Justify: Center</h3>
        <VueHeader contentJustify="center">
          <template #logo>
            <a
              href="#"
              style="text-decoration: none; color: inherit; font-weight: 600;"
            >Logo</a>
          </template>
          <nav style="margin-left: 2rem;">
            <a
              href="#nav"
              style="text-decoration: none; color: inherit;"
            >Navigation</a>
          </nav>
        </VueHeader>
      </div>

      <div class="mbe3">
        <h3
          class="mbe2"
          style="font-size: 1rem; font-weight: 600;"
        >Justify: Around</h3>
        <VueHeader contentJustify="around">
          <template #logo>
            <a
              href="#"
              style="text-decoration: none; color: inherit; font-weight: 600;"
            >Logo</a>
          </template>
          <nav>
            <a
              href="#nav"
              style="text-decoration: none; color: inherit;"
            >Navigation</a>
          </nav>
        </VueHeader>
      </div>
    </div>

    <div class="mbe4">
      <h2>Sticky Header</h2>
      <p class="mbs2 mbe3">
        Sticky headers remain visible at the top of the viewport when scrolling. Scroll down in the demo below to see it in action.
      </p>
    </div>
    <div
      class="mbe4"
      style="border: 1px solid var(--ag-border); border-radius: var(--ag-radius-md); overflow: hidden;"
    >
      <div style="height: 300px; overflow-y: scroll;">
        <VueHeader :sticky="true">
          <template #logo>
            <a
              href="#"
              style="text-decoration: none; color: var(--vp-c-brand-1); font-weight: 700; font-size: 1.25rem;"
            >
              Sticky Header
            </a>
          </template>
          <nav>
            <ul style="display: flex; gap: 1.5rem; list-style: none; margin: 0; padding: 0;">
              <li><a
                  href="#section1"
                  style="text-decoration: none; color: inherit;"
                >Section 1</a></li>
              <li><a
                  href="#section2"
                  style="text-decoration: none; color: inherit;"
                >Section 2</a></li>
            </ul>
          </nav>
        </VueHeader>
        <div style="padding: 2rem;">
          <h3 id="section1">Section 1</h3>
          <p style="margin-bottom: 200px;">Scroll down to see the sticky behavior. The header stays at the top.</p>
          <h3 id="section2">Section 2</h3>
          <p style="margin-bottom: 200px;">The header remains visible as you scroll through content.</p>
          <p>End of scrollable content.</p>
        </div>
      </div>
    </div>

    <div class="mbe4">
      <h2>CSS Shadow Parts Customization</h2>
      <p class="mbs2 mbe3">
        Use CSS Shadow Parts to customize the header's appearance without affecting its internal structure.
      </p>
    </div>
    <div class="mbe4">
      <div class="mbe3">
        <h3
          class="mbe2"
          style="font-size: 1rem; font-weight: 600;"
        >Gradient Background</h3>
        <VueHeader class="custom-header-gradient">
          <template #logo>
            <a
              href="#"
              style="text-decoration: none; color: white; font-weight: 700; font-size: 1.25rem;"
            >
              Gradient Header
            </a>
          </template>
          <nav>
            <ul style="display: flex; gap: 1.5rem; list-style: none; margin: 0; padding: 0;">
              <li><a
                  href="#home"
                  style="text-decoration: none; color: white;"
                >Home</a></li>
              <li><a
                  href="#about"
                  style="text-decoration: none; color: white;"
                >About</a></li>
            </ul>
          </nav>
        </VueHeader>
      </div>

      <div class="mbe3">
        <h3
          class="mbe2"
          style="font-size: 1rem; font-weight: 600;"
        >Custom Border</h3>
        <VueHeader class="custom-header-border">
          <template #logo>
            <a
              href="#"
              style="text-decoration: none; color: var(--vp-c-brand-1); font-weight: 700; font-size: 1.25rem;"
            >
              Bordered Header
            </a>
          </template>
          <nav>
            <ul style="display: flex; gap: 1.5rem; list-style: none; margin: 0; padding: 0;">
              <li><a
                  href="#home"
                  style="text-decoration: none; color: inherit;"
                >Home</a></li>
              <li><a
                  href="#about"
                  style="text-decoration: none; color: inherit;"
                >About</a></li>
            </ul>
          </nav>
        </VueHeader>
      </div>
    </div>
  </section>
</template>

<script lang="ts">
import { defineComponent } from "vue";
import { VueHeader } from "agnosticui-core/header/vue";

export default defineComponent({
  name: "HeaderExamples",
  components: {
    VueHeader,
  },
});
</script>

<style>
/* CSS Shadow Parts customization examples */
.custom-header-gradient::part(ag-header) {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
  border-bottom: none;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
}

.custom-header-border::part(ag-header) {
  background: var(--ag-background-secondary);
  border-bottom: 3px solid var(--ag-primary);
  box-shadow: none;
}
/* Vitepress override */
.vp-doc li + li {
  margin-top: 0;
}
</style>
Live Preview
View Lit / Web Component Code
import { LitElement, html } from "lit";
import "agnosticui-core/header";

export class HeaderLitExamples extends LitElement {
  // Render in light DOM to access global utility classes
  createRenderRoot() {
    return this;
  }

  render() {
    return html`
      <style>
        /* CSS Shadow Parts customization examples */
        .custom-header-gradient::part(ag-header) {
          background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
          color: white;
          border-bottom: none;
          box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
        }

        .custom-header-border::part(ag-header) {
          background: var(--ag-background-secondary);
          border-bottom: 3px solid var(--ag-primary);
          box-shadow: none;
        }
      </style>

      <section class="ag-header-examples">
        <div class="mbe4">
          <h2>Basic Header</h2>
          <p class="mbs2 mbe3">
            A simple header with logo and navigation. On mobile, content stacks vertically. On
            desktop (≥960px), it displays horizontally.
          </p>
        </div>
        <div class="mbe4">
          <ag-header>
            <a
              slot="logo"
              href="#"
              style="text-decoration: none; color: var(--vp-c-brand-1); font-weight: 700; font-size: 1.25rem;"
            >
              AgnosticUI
            </a>
            <nav>
              <ul style="display: flex; gap: 1.5rem; list-style: none; margin: 0; padding: 0;">
                <li>
                  <a href="#home" style="text-decoration: none; color: inherit;">Home</a>
                </li>
                <li>
                  <a href="#about" style="text-decoration: none; color: inherit;">About</a>
                </li>
                <li>
                  <a href="#contact" style="text-decoration: none; color: inherit;">Contact</a>
                </li>
              </ul>
            </nav>
          </ag-header>
        </div>

        <div class="mbe4">
          <h2>Header with Logo Image</h2>
        </div>
        <div class="mbe4">
          <ag-header>
            <a
              slot="logo"
              href="#"
              style="display: flex; align-items: center; gap: 0.5rem; text-decoration: none; color: inherit;"
            >
              <svg
                width="32"
                height="32"
                viewBox="0 0 32 32"
                fill="currentColor"
                style="color: var(--vp-c-brand-1);"
              >
                <circle cx="16" cy="16" r="14" fill="var(--ag-primary)" />
                <text x="16" y="22" text-anchor="middle" fill="white" font-size="16" font-weight="bold">
                  A
                </text>
              </svg>
              <span style="font-weight: 700; font-size: 1.25rem;">MyApp</span>
            </a>
            <nav>
              <ul style="display: flex; gap: 2rem; list-style: none; margin: 0; padding: 0;">
                <li>
                  <a href="#dashboard" style="text-decoration: none; color: inherit;">Dashboard</a>
                </li>
                <li>
                  <a href="#settings" style="text-decoration: none; color: inherit;">Settings</a>
                </li>
                <li>
                  <a href="#profile" style="text-decoration: none; color: inherit;">Profile</a>
                </li>
              </ul>
            </nav>
          </ag-header>
        </div>

        <div class="mbe4">
          <h2>Content Justification</h2>
          <p class="mbs2 mbe3">
            Control how content is aligned within the header using the
            <code>contentJustify</code> prop.
          </p>
        </div>
        <div class="mbe4">
          <div class="mbe3">
            <h3 class="mbe2" style="font-size: 1rem; font-weight: 600;">
              Justify: Between (Default)
            </h3>
            <ag-header contentJustify="between">
              <a
                slot="logo"
                href="#"
                style="text-decoration: none; color: inherit; font-weight: 600;"
              >
                Logo
              </a>
              <nav>
                <a href="#nav" style="text-decoration: none; color: inherit;">Navigation</a>
              </nav>
            </ag-header>
          </div>

          <div class="mbe3">
            <h3 class="mbe2" style="font-size: 1rem; font-weight: 600;">Justify: Start</h3>
            <ag-header contentJustify="start">
              <a
                slot="logo"
                href="#"
                style="text-decoration: none; color: inherit; font-weight: 600;"
              >
                Logo
              </a>
              <nav style="margin-left: 2rem;">
                <a href="#nav" style="text-decoration: none; color: inherit;">Navigation</a>
              </nav>
            </ag-header>
          </div>

          <div class="mbe3">
            <h3 class="mbe2" style="font-size: 1rem; font-weight: 600;">Justify: End</h3>
            <ag-header contentJustify="end">
              <a
                slot="logo"
                href="#"
                style="text-decoration: none; color: inherit; font-weight: 600;"
              >
                Logo
              </a>
              <nav style="margin-left: 2rem;">
                <a href="#nav" style="text-decoration: none; color: inherit;">Navigation</a>
              </nav>
            </ag-header>
          </div>

          <div class="mbe3">
            <h3 class="mbe2" style="font-size: 1rem; font-weight: 600;">Justify: Center</h3>
            <ag-header contentJustify="center">
              <a
                slot="logo"
                href="#"
                style="text-decoration: none; color: inherit; font-weight: 600;"
              >
                Logo
              </a>
              <nav style="margin-left: 2rem;">
                <a href="#nav" style="text-decoration: none; color: inherit;">Navigation</a>
              </nav>
            </ag-header>
          </div>

          <div class="mbe3">
            <h3 class="mbe2" style="font-size: 1rem; font-weight: 600;">Justify: Around</h3>
            <ag-header contentJustify="around">
              <a
                slot="logo"
                href="#"
                style="text-decoration: none; color: inherit; font-weight: 600;"
              >
                Logo
              </a>
              <nav>
                <a href="#nav" style="text-decoration: none; color: inherit;">Navigation</a>
              </nav>
            </ag-header>
          </div>
        </div>

        <div class="mbe4">
          <h2>Sticky Header</h2>
          <p class="mbs2 mbe3">
            Sticky headers remain visible at the top of the viewport when scrolling. Scroll down in
            the demo below to see it in action.
          </p>
        </div>
        <div
          class="mbe4"
          style="border: 1px solid var(--ag-border); border-radius: var(--ag-radius-md); overflow: hidden;"
        >
          <div style="height: 300px; overflow-y: scroll;">
            <ag-header sticky>
              <a
                slot="logo"
                href="#"
                style="text-decoration: none; color: var(--vp-c-brand-1); font-weight: 700; font-size: 1.25rem;"
              >
                Sticky Header
              </a>
              <nav>
                <ul style="display: flex; gap: 1.5rem; list-style: none; margin: 0; padding: 0;">
                  <li>
                    <a href="#section1" style="text-decoration: none; color: inherit;">Section 1</a>
                  </li>
                  <li>
                    <a href="#section2" style="text-decoration: none; color: inherit;">Section 2</a>
                  </li>
                </ul>
              </nav>
            </ag-header>
            <div style="padding: 2rem;">
              <h3 id="section1">Section 1</h3>
              <p style="margin-bottom: 200px;">
                Scroll down to see the sticky behavior. The header stays at the top.
              </p>
              <h3 id="section2">Section 2</h3>
              <p style="margin-bottom: 200px;">
                The header remains visible as you scroll through content.
              </p>
              <p>End of scrollable content.</p>
            </div>
          </div>
        </div>

        <div class="mbe4">
          <h2>CSS Shadow Parts Customization</h2>
          <p class="mbs2 mbe3">
            Use CSS Shadow Parts to customize the header's appearance without affecting its
            internal structure.
          </p>
        </div>
        <div class="mbe4">
          <div class="mbe3">
            <h3 class="mbe2" style="font-size: 1rem; font-weight: 600;">Gradient Background</h3>
            <ag-header class="custom-header-gradient">
              <a
                slot="logo"
                href="#"
                style="text-decoration: none; color: white; font-weight: 700; font-size: 1.25rem;"
              >
                Gradient Header
              </a>
              <nav>
                <ul style="display: flex; gap: 1.5rem; list-style: none; margin: 0; padding: 0;">
                  <li>
                    <a href="#home" style="text-decoration: none; color: white;">Home</a>
                  </li>
                  <li>
                    <a href="#about" style="text-decoration: none; color: white;">About</a>
                  </li>
                </ul>
              </nav>
            </ag-header>
          </div>

          <div class="mbe3">
            <h3 class="mbe2" style="font-size: 1rem; font-weight: 600;">Custom Border</h3>
            <ag-header class="custom-header-border">
              <a
                slot="logo"
                href="#"
                style="text-decoration: none; color: var(--vp-c-brand-1); font-weight: 700; font-size: 1.25rem;"
              >
                Bordered Header
              </a>
              <nav>
                <ul style="display: flex; gap: 1.5rem; list-style: none; margin: 0; padding: 0;">
                  <li>
                    <a href="#home" style="text-decoration: none; color: inherit;">Home</a>
                  </li>
                  <li>
                    <a href="#about" style="text-decoration: none; color: inherit;">About</a>
                  </li>
                </ul>
              </nav>
            </ag-header>
          </div>
        </div>
      </section>
    `;
  }
}

customElements.define("header-lit-examples", HeaderLitExamples);

Interactive Preview: Click the "Open in StackBlitz" button below to see this example running live in an interactive playground.

View React Code
import { ReactHeader } from "agnosticui-core/header/react";

const HeaderReactExamples = () => {
  return (
    <section className="ag-header-examples">
      <div className="mbe4">
        <h2>Basic Header</h2>
        <p className="mbs2 mbe3">
          A simple header with logo and navigation. On mobile, content stacks vertically. On
          desktop (≥960px), it displays horizontally.
        </p>
      </div>
      <div className="mbe4">
        <ReactHeader>
          <a
            slot="logo"
            href="#"
            style={{
              textDecoration: "none",
              color: "var(--vp-c-brand-1)",
              fontWeight: 700,
              fontSize: "1.25rem",
            }}
          >
            AgnosticUI
          </a>
          <nav>
            <ul style={{ display: "flex", gap: "1.5rem", listStyle: "none", margin: 0, padding: 0 }}>
              <li>
                <a href="#home" style={{ textDecoration: "none", color: "inherit" }}>
                  Home
                </a>
              </li>
              <li>
                <a href="#about" style={{ textDecoration: "none", color: "inherit" }}>
                  About
                </a>
              </li>
              <li>
                <a href="#contact" style={{ textDecoration: "none", color: "inherit" }}>
                  Contact
                </a>
              </li>
            </ul>
          </nav>
        </ReactHeader>
      </div>

      <div className="mbe4">
        <h2>Header with Logo Image</h2>
      </div>
      <div className="mbe4">
        <ReactHeader>
          <a
            slot="logo"
            href="#"
            style={{
              display: "flex",
              alignItems: "center",
              gap: "0.5rem",
              textDecoration: "none",
              color: "inherit",
            }}
          >
            <svg
              width="32"
              height="32"
              viewBox="0 0 32 32"
              fill="currentColor"
              style={{ color: "var(--vp-c-brand-1)" }}
            >
              <circle cx="16" cy="16" r="14" fill="var(--ag-primary)" />
              <text x="16" y="22" textAnchor="middle" fill="white" fontSize="16" fontWeight="bold">
                A
              </text>
            </svg>
            <span style={{ fontWeight: 700, fontSize: "1.25rem" }}>MyApp</span>
          </a>
          <nav>
            <ul style={{ display: "flex", gap: "2rem", listStyle: "none", margin: 0, padding: 0 }}>
              <li>
                <a href="#dashboard" style={{ textDecoration: "none", color: "inherit" }}>
                  Dashboard
                </a>
              </li>
              <li>
                <a href="#settings" style={{ textDecoration: "none", color: "inherit" }}>
                  Settings
                </a>
              </li>
              <li>
                <a href="#profile" style={{ textDecoration: "none", color: "inherit" }}>
                  Profile
                </a>
              </li>
            </ul>
          </nav>
        </ReactHeader>
      </div>

      <div className="mbe4">
        <h2>Content Justification</h2>
        <p className="mbs2 mbe3">
          Control how content is aligned within the header using the <code>contentJustify</code>{" "}
          prop.
        </p>
      </div>
      <div className="mbe4">
        <div className="mbe3">
          <h3 className="mbe2" style={{ fontSize: "1rem", fontWeight: 600 }}>
            Justify: Between (Default)
          </h3>
          <ReactHeader contentJustify="between">
            <a
              slot="logo"
              href="#"
              style={{ textDecoration: "none", color: "inherit", fontWeight: 600 }}
            >
              Logo
            </a>
            <nav>
              <a href="#nav" style={{ textDecoration: "none", color: "inherit" }}>
                Navigation
              </a>
            </nav>
          </ReactHeader>
        </div>

        <div className="mbe3">
          <h3 className="mbe2" style={{ fontSize: "1rem", fontWeight: 600 }}>
            Justify: Start
          </h3>
          <ReactHeader contentJustify="start">
            <a
              slot="logo"
              href="#"
              style={{ textDecoration: "none", color: "inherit", fontWeight: 600 }}
            >
              Logo
            </a>
            <nav style={{ marginLeft: "2rem" }}>
              <a href="#nav" style={{ textDecoration: "none", color: "inherit" }}>
                Navigation
              </a>
            </nav>
          </ReactHeader>
        </div>

        <div className="mbe3">
          <h3 className="mbe2" style={{ fontSize: "1rem", fontWeight: 600 }}>
            Justify: End
          </h3>
          <ReactHeader contentJustify="end">
            <a
              slot="logo"
              href="#"
              style={{ textDecoration: "none", color: "inherit", fontWeight: 600 }}
            >
              Logo
            </a>
            <nav style={{ marginLeft: "2rem" }}>
              <a href="#nav" style={{ textDecoration: "none", color: "inherit" }}>
                Navigation
              </a>
            </nav>
          </ReactHeader>
        </div>

        <div className="mbe3">
          <h3 className="mbe2" style={{ fontSize: "1rem", fontWeight: 600 }}>
            Justify: Center
          </h3>
          <ReactHeader contentJustify="center">
            <a
              slot="logo"
              href="#"
              style={{ textDecoration: "none", color: "inherit", fontWeight: 600 }}
            >
              Logo
            </a>
            <nav style={{ marginLeft: "2rem" }}>
              <a href="#nav" style={{ textDecoration: "none", color: "inherit" }}>
                Navigation
              </a>
            </nav>
          </ReactHeader>
        </div>

        <div className="mbe3">
          <h3 className="mbe2" style={{ fontSize: "1rem", fontWeight: 600 }}>
            Justify: Around
          </h3>
          <ReactHeader contentJustify="around">
            <a
              slot="logo"
              href="#"
              style={{ textDecoration: "none", color: "inherit", fontWeight: 600 }}
            >
              Logo
            </a>
            <nav>
              <a href="#nav" style={{ textDecoration: "none", color: "inherit" }}>
                Navigation
              </a>
            </nav>
          </ReactHeader>
        </div>
      </div>

      <div className="mbe4">
        <h2>Sticky Header</h2>
        <p className="mbs2 mbe3">
          Sticky headers remain visible at the top of the viewport when scrolling. Scroll down in
          the demo below to see it in action.
        </p>
      </div>
      <div
        className="mbe4"
        style={{
          border: "1px solid var(--ag-border)",
          borderRadius: "var(--ag-radius-md)",
          overflow: "hidden",
        }}
      >
        <div style={{ height: "300px", overflowY: "scroll" }}>
          <ReactHeader sticky={true}>
            <a
              slot="logo"
              href="#"
              style={{
                textDecoration: "none",
                color: "var(--vp-c-brand-1)",
                fontWeight: 700,
                fontSize: "1.25rem",
              }}
            >
              Sticky Header
            </a>
            <nav>
              <ul
                style={{ display: "flex", gap: "1.5rem", listStyle: "none", margin: 0, padding: 0 }}
              >
                <li>
                  <a href="#section1" style={{ textDecoration: "none", color: "inherit" }}>
                    Section 1
                  </a>
                </li>
                <li>
                  <a href="#section2" style={{ textDecoration: "none", color: "inherit" }}>
                    Section 2
                  </a>
                </li>
              </ul>
            </nav>
          </ReactHeader>
          <div style={{ padding: "2rem" }}>
            <h3 id="section1">Section 1</h3>
            <p style={{ marginBottom: "200px" }}>
              Scroll down to see the sticky behavior. The header stays at the top.
            </p>
            <h3 id="section2">Section 2</h3>
            <p style={{ marginBottom: "200px" }}>
              The header remains visible as you scroll through content.
            </p>
            <p>End of scrollable content.</p>
          </div>
        </div>
      </div>

      <div className="mbe4">
        <h2>CSS Shadow Parts Customization</h2>
        <p className="mbs2 mbe3">
          Use CSS Shadow Parts to customize the header's appearance without affecting its internal
          structure.
        </p>
      </div>
      <div className="mbe4">
        <div className="mbe3">
          <h3 className="mbe2" style={{ fontSize: "1rem", fontWeight: 600 }}>
            Gradient Background
          </h3>
          <ReactHeader className="custom-header-gradient">
            <a
              slot="logo"
              href="#"
              style={{
                textDecoration: "none",
                color: "white",
                fontWeight: 700,
                fontSize: "1.25rem",
              }}
            >
              Gradient Header
            </a>
            <nav>
              <ul
                style={{ display: "flex", gap: "1.5rem", listStyle: "none", margin: 0, padding: 0 }}
              >
                <li>
                  <a href="#home" style={{ textDecoration: "none", color: "white" }}>
                    Home
                  </a>
                </li>
                <li>
                  <a href="#about" style={{ textDecoration: "none", color: "white" }}>
                    About
                  </a>
                </li>
              </ul>
            </nav>
          </ReactHeader>
        </div>

        <div className="mbe3">
          <h3 className="mbe2" style={{ fontSize: "1rem", fontWeight: 600 }}>
            Custom Border
          </h3>
          <ReactHeader className="custom-header-border">
            <a
              slot="logo"
              href="#"
              style={{
                textDecoration: "none",
                color: "var(--vp-c-brand-1)",
                fontWeight: 700,
                fontSize: "1.25rem",
              }}
            >
              Bordered Header
            </a>
            <nav>
              <ul
                style={{ display: "flex", gap: "1.5rem", listStyle: "none", margin: 0, padding: 0 }}
              >
                <li>
                  <a href="#home" style={{ textDecoration: "none", color: "inherit" }}>
                    Home
                  </a>
                </li>
                <li>
                  <a href="#about" style={{ textDecoration: "none", color: "inherit" }}>
                    About
                  </a>
                </li>
              </ul>
            </nav>
          </ReactHeader>
        </div>
      </div>

      <style>{`
        /* CSS Shadow Parts customization examples */
        .custom-header-gradient::part(ag-header) {
          background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
          color: white;
          border-bottom: none;
          box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
        }

        .custom-header-border::part(ag-header) {
          background: var(--ag-background-secondary);
          border-bottom: 3px solid var(--ag-primary);
          box-shadow: none;
        }
      `}</style>
    </section>
  );
};

export default HeaderReactExamples;
Open in StackBlitz

Usage

TIP

The framework examples below import AgnosticUI as an npm package. Alternatively, you can use the CLI for complete control, AI/LLM visibility, and full code ownership:

bash
npx ag init --framework FRAMEWORK # react, vue, lit, svelte, etc.
npx ag add Header

The CLI copies source code directly into your project, giving you full visibility and control. After running npx ag add, you'll receive exact import instructions.

Vue
vue
<template>
  <div>
    <VueHeader>
      <template #logo>
        <a
          href="/"
          style="text-decoration: none; color: inherit; font-weight: 700; font-size: 1.25rem;"
        >
          MyBrand
        </a>
      </template>
      <nav>
        <ul
          style="display: flex; gap: 2rem; list-style: none; margin: 0; padding: 0;"
        >
          <li><a href="#home">Home</a></li>
          <li><a href="#about">About</a></li>
          <li><a href="#contact">Contact</a></li>
        </ul>
      </nav>
    </VueHeader>

    <VueHeader :sticky="true">
      <template #logo>
        <a href="/">Brand</a>
      </template>
      <nav>Navigation</nav>
    </VueHeader>

    <VueHeader contentJustify="start">
      <template #logo>
        <a href="/">Logo</a>
      </template>
      <nav>Menu</nav>
    </VueHeader>
  </div>
</template>

<script lang="ts">
import { defineComponent } from "vue";
import { VueHeader } from "agnosticui-core/header/vue";

export default defineComponent({
  components: { VueHeader },
});
</script>
React
tsx
import { ReactHeader } from "agnosticui-core/header/react";

export default function Example() {
  return (
    <div>
      <ReactHeader>
        <a
          href="/"
          slot="logo"
          style={{
            textDecoration: "none",
            color: "inherit",
            fontWeight: 700,
            fontSize: "1.25rem",
          }}
        >
          MyBrand
        </a>
        <nav>
          <ul
            style={{
              display: "flex",
              gap: "2rem",
              listStyle: "none",
              margin: 0,
              padding: 0,
            }}
          >
            <li>
              <a href="#home">Home</a>
            </li>
            <li>
              <a href="#about">About</a>
            </li>
            <li>
              <a href="#contact">Contact</a>
            </li>
          </ul>
        </nav>
      </ReactHeader>

      <ReactHeader sticky>
        <a href="/" slot="logo">
          Brand
        </a>
        <nav>Navigation</nav>
      </ReactHeader>

      <ReactHeader contentJustify="start">
        <a href="/" slot="logo">
          Logo
        </a>
        <nav>Menu</nav>
      </ReactHeader>
    </div>
  );
}
Lit (Web Components)
html
<script type="module">
  import "agnosticui-core/header";
</script>

<ag-header>
  <a
    href="/"
    slot="logo"
    style="text-decoration: none; color: inherit; font-weight: 700; font-size: 1.25rem;"
  >
    MyBrand
  </a>
  <nav>
    <ul
      style="display: flex; gap: 2rem; list-style: none; margin: 0; padding: 0;"
    >
      <li><a href="#home">Home</a></li>
      <li><a href="#about">About</a></li>
      <li><a href="#contact">Contact</a></li>
    </ul>
  </nav>
</ag-header>

<ag-header sticky>
  <a href="/" slot="logo">Brand</a>
  <nav>Navigation</nav>
</ag-header>

<ag-header contentJustify="start">
  <a href="/" slot="logo">Logo</a>
  <nav>Menu</nav>
</ag-header>

Props

PropTypeDefaultDescription
stickybooleanfalseMakes the header sticky at the viewport top. The header will remain visible when scrolling
contentJustify'start' | 'end' | 'between' | 'around' | 'center''between'Controls flex content alignment. between puts logo and nav at opposite ends, start aligns to the left, end to the right, around distributes space, center centers content

Slots

SlotDescription
logoContent for the logo/brand area, typically a link with logo image or text
(default)Navigation content, typically a <nav> element containing menu items

Events

The Header component does not emit any custom events. It relies on standard DOM events from slotted content.

CSS Shadow Parts

PartDescription
ag-headerThe outer <header> element
ag-header-contentThe inner content wrapper div that controls layout and spacing

Customization Example

css
.gradient-header::part(ag-header) {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
  border-bottom: none;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
}

.custom-border::part(ag-header) {
  background: #f3f4f6;
  border-bottom: 3px solid #12623e;
  box-shadow: none;
}

.wide-header::part(ag-header-content) {
  max-width: 1200px;
  padding: 1.5rem 2rem;
}

Accessibility

The Header component is designed to be accessible by default:

  • Semantic HTML: Uses the <header> element which provides an implicit landmark role
  • Navigation: Consumers should wrap navigation links in a <nav> element for proper semantic structure
  • Keyboard Navigation: All interactive elements in slotted content remain keyboard accessible
  • Screen Readers: The <header> landmark is automatically announced by screen readers
  • ARIA Labels: Consider adding aria-label to <nav> elements for additional context (e.g., <nav aria-label="Main navigation">)

Best Practices

  • Use the <header> component once per page for the main site header
  • Include semantic <nav> elements for navigation menus
  • Ensure logo/brand links have accessible text or aria-label
  • Maintain adequate color contrast in custom styling
  • For sticky headers, consider using scroll-margin-top on jump link targets to prevent content from hiding under the header:
css
h1[id],
h2[id],
h3[id] {
  scroll-margin-top: var(--your-headers-height);
}

Responsive Behavior

The Header component uses a mobile-first responsive approach:

  • Mobile (<960px):

    • Stacked column layout
    • Logo and navigation centered
    • Vertical spacing between logo and navigation
  • Desktop (≥960px):

    • Horizontal row layout
    • Content justification applied (default: space-between)
    • Logo and navigation side-by-side

For mobile navigation menus (hamburger menus), you'll need to implement the toggle logic yourself. The Header component provides the container and layout structure.

Common Patterns

Header with Logo Image

vue
<VueHeader>
  <template #logo>
    <a href="/" style="display: flex; align-items: center; gap: 0.5rem;">
      <img src="/logo.svg" alt="Company Name" width="32" height="32" />
      <span style="font-weight: 700; font-size: 1.25rem;">Company</span>
    </a>
  </template>
  <nav>...</nav>
</VueHeader>

Sticky Header with Shadow

vue
<VueHeader :sticky="true">
  <template #logo>
    <a href="/">Brand</a>
  </template>
  <nav aria-label="Main navigation">
    <ul style="display: flex; gap: 2rem; list-style: none; margin: 0; padding: 0;">
      <li><a href="#home">Home</a></li>
      <li><a href="#about">About</a></li>
      <li><a href="#contact">Contact</a></li>
    </ul>
  </nav>
</VueHeader>

Notes

  • The Header component provides the semantic structure and layout; you're responsible for styling navigation links and implementing any interactive navigation patterns (mobile menus, dropdowns, etc.)
  • When using sticky, the header uses z-index: var(--ag-z-index-dropdown) (100) to stay above page content
  • The default content width is 960px with responsive max-width: 100% to prevent horizontal overflow
  • Dark mode is automatically supported through design tokens when data-theme="dark" is set on the HTML element