Open demo

CSS code

HTML
<header class="sp">
  <a class="sp-mark" href="#">Halden<span>Est. 2014</span></a>
  <button class="sp-toggle" type="button" aria-expanded="false" aria-controls="sp-menu" aria-label="Menu" data-menu-button><i></i><i></i><i></i></button>
  <nav class="sp-menu" id="sp-menu" aria-label="Main">
    <ul class="sp-left">
      <li><a href="#" aria-current="page">Collections</a></li>
      <li><a href="#">Journal</a></li>
    </ul>
    <ul class="sp-right">
      <li><a href="#">Stockists</a></li>
      <li><a href="#">Contact</a></li>
    </ul>
  </nav>
</header>
CSS
/* Split navigation: a three-column grid (1fr auto 1fr) keeps the mark centred however many links sit either
   side. The nav spans all three columns as a subgrid, so its two lists line up with the outer columns while
   every link stays inside one nav landmark. Below 992px the lists fold behind a menu button. */
.sp{display:grid;grid-template-columns:1fr auto 1fr;align-items:center;column-gap:30px;min-height:88px;
  padding:0 40px;background:#fff;border-bottom:1px solid #ecedf2;color:#1a1d26}
.sp,.sp *{box-sizing:border-box}
.sp a{text-decoration:none}
.sp ul{list-style:none;margin:0;padding:0}
.sp a:focus-visible,.sp button:focus-visible{outline:2px solid #1a1d26;outline-offset:2px}
.sp-mark{grid-column:2;grid-row:1;position:relative;z-index:1;font-weight:800;font-size:1.35rem;letter-spacing:-.02em;
  color:#1a1d26;white-space:nowrap;text-align:center}
.sp-mark span{display:block;margin-top:3px;font-size:.62rem;font-weight:600;letter-spacing:.28em;color:#6b7385;text-transform:uppercase}
.sp-menu{grid-column:1/-1;grid-row:1;display:grid;grid-template-columns:subgrid}
.sp-menu ul{display:flex;gap:8px}
.sp-left{grid-column:1;justify-content:flex-end}
.sp-right{grid-column:3}
.sp-menu a{display:block;padding:9px 12px;font-size:.85rem;font-weight:600;letter-spacing:.02em;text-transform:uppercase;color:#4b5468}
.sp-menu a:hover,.sp-menu a[aria-current="page"]{color:#1a1d26}
.sp-menu a[aria-current="page"]{text-decoration:underline;text-decoration-thickness:2px;text-underline-offset:6px}
.sp-toggle{display:none;flex:none;width:44px;height:44px;flex-direction:column;align-items:center;justify-content:center;
  gap:5px;padding:0;background:#fff;border:1px solid #d9dfe8;border-radius:10px;cursor:pointer}
.sp-toggle i{display:block;width:20px;height:2px;border-radius:2px;background:#1a1d26;transition:transform .2s,opacity .2s}
.sp-toggle[aria-expanded="true"] i:nth-child(1){transform:translateY(7px) rotate(45deg)}
.sp-toggle[aria-expanded="true"] i:nth-child(2){opacity:0}
.sp-toggle[aria-expanded="true"] i:nth-child(3){transform:translateY(-7px) rotate(-45deg)}
@media (max-width:991.98px){
  .sp{min-height:0;padding:12px 16px;column-gap:12px}
  .sp-toggle{display:flex;grid-column:3;grid-row:1;justify-self:end}
  .sp-menu{display:none;grid-row:2;margin-top:12px;padding:8px 0 4px;border-top:1px solid #ecedf2}
  .sp-menu[data-open]{display:block}
  .sp-menu ul{flex-direction:column;align-items:center;gap:0}
  .sp-menu a{padding:11px 12px}
}
@media (prefers-reduced-motion:reduce){.sp *{transition:none!important}}
JavaScript
/* Menu button: toggles aria-expanded on itself and data-open on the menu it controls (aria-controls).
   Esc closes an open menu and returns focus to the button; widening past 992px resets it. */
document.querySelectorAll('[data-menu-button]').forEach(btn => {
  const menu = document.getElementById(btn.getAttribute('aria-controls'));
  if (!menu) return;
  const set = open => { btn.setAttribute('aria-expanded', String(open)); menu.toggleAttribute('data-open', open); };
  btn.addEventListener('click', () => set(btn.getAttribute('aria-expanded') !== 'true'));
  document.addEventListener('keydown', e => {
    if (e.key === 'Escape' && btn.getAttribute('aria-expanded') === 'true') { set(false); btn.focus(); }
  });
  matchMedia('(min-width: 992px)').addEventListener('change', e => { if (e.matches) set(false); });
});

Bootstrap 5 code

Requires: Bootstrap 5.3.8 CSS, Bootstrap 5.3.8 JS bundle

HTML
<header class="navbar navbar-expand-lg sp">
  <a class="navbar-brand sp-mark" href="#">Halden<span>Est. 2014</span></a>
  <button class="navbar-toggler sp-toggle" type="button" data-bs-toggle="collapse" data-bs-target="#sp-menu" aria-controls="sp-menu" aria-expanded="false" aria-label="Menu"><i></i><i></i><i></i></button>
  <nav class="collapse navbar-collapse" id="sp-menu" aria-label="Main">
    <ul class="navbar-nav sp-left">
      <li class="nav-item"><a class="nav-link active" href="#" aria-current="page">Collections</a></li>
      <li class="nav-item"><a class="nav-link" href="#">Journal</a></li>
    </ul>
    <ul class="navbar-nav sp-right">
      <li class="nav-item"><a class="nav-link" href="#">Stockists</a></li>
      <li class="nav-item"><a class="nav-link" href="#">Contact</a></li>
    </ul>
  </nav>
</header>
CSS
/* Bootstrap .navbar-expand-lg on the <header>, laid out as a 1fr auto 1fr grid so the brand stays centred.
   From 992px the .navbar-collapse becomes a subgrid across all three columns; below it, a normal collapse. */
.sp{--bs-navbar-padding-x:40px;--bs-navbar-padding-y:0;--bs-navbar-color:#4b5468;--bs-navbar-hover-color:#1a1d26;
  --bs-navbar-active-color:#1a1d26;--bs-navbar-brand-color:#1a1d26;--bs-navbar-brand-hover-color:#1a1d26;
  --bs-navbar-brand-padding-y:0;--bs-navbar-brand-margin-end:0;--bs-navbar-brand-font-size:1.35rem;--bs-navbar-nav-link-padding-x:12px;
  display:grid;grid-template-columns:1fr auto 1fr;align-items:center;column-gap:30px;min-height:88px;
  background:#fff;border-bottom:1px solid #ecedf2}
.sp a{text-decoration:none}
.sp a:focus-visible,.sp button:focus-visible{outline:2px solid #1a1d26;outline-offset:2px;box-shadow:none}
.sp-mark{grid-column:2;grid-row:1;position:relative;z-index:1;font-weight:800;letter-spacing:-.02em;text-align:center;line-height:normal}
.sp-mark span{display:block;margin-top:3px;font-size:.62rem;font-weight:600;letter-spacing:.28em;color:#6b7385;text-transform:uppercase}
.sp .navbar-collapse{grid-column:1/-1}
.sp .navbar-nav{--bs-nav-link-padding-y:9px;--bs-nav-link-font-size:.85rem;--bs-nav-link-font-weight:600;gap:8px}
.sp .nav-link{letter-spacing:.02em;text-transform:uppercase}
.sp .nav-link.active{text-decoration:underline;text-decoration-thickness:2px;text-underline-offset:6px}
.sp .navbar-toggler{width:44px;height:44px;padding:0;display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:5px;background:#fff;border:1px solid #d9dfe8;border-radius:10px}
.sp .navbar-toggler:focus{box-shadow:none}
.sp .navbar-toggler i{display:block;width:20px;height:2px;border-radius:2px;background:#1a1d26;transition:transform .2s,opacity .2s}
.sp .navbar-toggler[aria-expanded="true"] i:nth-child(1){transform:translateY(7px) rotate(45deg)}
.sp .navbar-toggler[aria-expanded="true"] i:nth-child(2){opacity:0}
.sp .navbar-toggler[aria-expanded="true"] i:nth-child(3){transform:translateY(-7px) rotate(-45deg)}
@media (min-width:992px){.sp .navbar-toggler{display:none}}
@media (min-width:992px){
  .sp .navbar-collapse{grid-row:1;display:grid!important;grid-template-columns:subgrid}
  .sp-left{grid-column:1;justify-content:flex-end}
  .sp-right{grid-column:3}
}
@media (max-width:991.98px){
  .sp{--bs-navbar-padding-x:16px;min-height:0;padding-top:12px;padding-bottom:12px;column-gap:12px}
  .sp .navbar-toggler{grid-column:3;grid-row:1;justify-self:end}
  .sp .navbar-collapse{grid-row:2}
  .sp .navbar-nav{--bs-nav-link-padding-y:11px;--bs-nav-link-padding-x:12px;align-items:center;gap:0}
  .sp-left{margin-top:12px;padding-top:8px;border-top:1px solid #ecedf2}
  .sp-right{padding-bottom:4px}
}
@media (prefers-reduced-motion:reduce){.sp *{transition:none!important}}
JavaScript
/* Bootstrap's Collapse has no Esc handling of its own: close an open navbar menu on Esc
   and return focus to its toggler. */
document.addEventListener('keydown', e => {
  if (e.key !== 'Escape') return;
  document.querySelectorAll('.navbar-collapse.show').forEach(menu => {
    bootstrap.Collapse.getOrCreateInstance(menu, { toggle: false }).hide();
    document.querySelector(`[data-bs-target="#${menu.id}"]`)?.focus();
  });
});

Tailwind 4 code

Requires: Tailwind CSS 4

HTML
<header class="grid min-h-[88px] grid-cols-[1fr_auto_1fr] items-center gap-x-[30px] border-b border-[#ecedf2] bg-white px-10 text-[#1a1d26] max-lg:min-h-0 max-lg:gap-x-3 max-lg:px-4 max-lg:py-3">
  <a class="relative z-[1] col-start-2 row-start-1 text-center text-[1.35rem] font-extrabold tracking-[-.02em] whitespace-nowrap text-[#1a1d26] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[#1a1d26]" href="#">Halden<span class="mt-[3px] block text-[.62rem] font-semibold tracking-[.28em] text-[#6b7385] uppercase">Est. 2014</span></a>
  <button class="group flex size-11 flex-none cursor-pointer flex-col items-center justify-center gap-[5px] rounded-[10px] border border-[#d9dfe8] bg-white p-0 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[#1a1d26] lg:hidden col-start-3 row-start-1 justify-self-end" type="button" aria-expanded="false" aria-controls="sp-menu" aria-label="Menu" data-menu-button><i class="block h-0.5 w-5 rounded-sm bg-[#1a1d26] transition-transform duration-200 motion-reduce:transition-none group-aria-expanded:translate-y-[7px] group-aria-expanded:rotate-45"></i><i class="block h-0.5 w-5 rounded-sm bg-[#1a1d26] transition-opacity duration-200 motion-reduce:transition-none group-aria-expanded:opacity-0"></i><i class="block h-0.5 w-5 rounded-sm bg-[#1a1d26] transition-transform duration-200 motion-reduce:transition-none group-aria-expanded:-translate-y-[7px] group-aria-expanded:-rotate-45"></i></button>
  <nav class="col-span-full row-start-1 hidden grid-cols-subgrid data-open:block lg:grid max-lg:row-start-2 max-lg:mt-3 max-lg:border-t max-lg:border-[#ecedf2] max-lg:pt-2 max-lg:pb-1" id="sp-menu" aria-label="Main">
    <ul class="col-start-1 flex justify-end gap-2 max-lg:flex-col max-lg:items-center max-lg:gap-0">
      <li><a class="block px-3 py-[9px] text-[.85rem] font-semibold tracking-[.02em] text-[#4b5468] uppercase hover:text-[#1a1d26] aria-[current=page]:text-[#1a1d26] aria-[current=page]:underline aria-[current=page]:decoration-2 aria-[current=page]:underline-offset-[6px] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[#1a1d26] max-lg:py-[11px]" href="#" aria-current="page">Collections</a></li>
      <li><a class="block px-3 py-[9px] text-[.85rem] font-semibold tracking-[.02em] text-[#4b5468] uppercase hover:text-[#1a1d26] aria-[current=page]:text-[#1a1d26] aria-[current=page]:underline aria-[current=page]:decoration-2 aria-[current=page]:underline-offset-[6px] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[#1a1d26] max-lg:py-[11px]" href="#">Journal</a></li>
    </ul>
    <ul class="col-start-3 flex gap-2 max-lg:flex-col max-lg:items-center max-lg:gap-0">
      <li><a class="block px-3 py-[9px] text-[.85rem] font-semibold tracking-[.02em] text-[#4b5468] uppercase hover:text-[#1a1d26] aria-[current=page]:text-[#1a1d26] aria-[current=page]:underline aria-[current=page]:decoration-2 aria-[current=page]:underline-offset-[6px] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[#1a1d26] max-lg:py-[11px]" href="#">Stockists</a></li>
      <li><a class="block px-3 py-[9px] text-[.85rem] font-semibold tracking-[.02em] text-[#4b5468] uppercase hover:text-[#1a1d26] aria-[current=page]:text-[#1a1d26] aria-[current=page]:underline aria-[current=page]:decoration-2 aria-[current=page]:underline-offset-[6px] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[#1a1d26] max-lg:py-[11px]" href="#">Contact</a></li>
    </ul>
  </nav>
</header>
CSS
@theme {
  --breakpoint-lg: 62rem; /* 992px, the same collapse point as Bootstrap's navbar-expand-lg */
}
JavaScript
/* Menu button: toggles aria-expanded on itself and data-open on the menu it controls (aria-controls).
   Esc closes an open menu and returns focus to the button; widening past 992px resets it. */
document.querySelectorAll('[data-menu-button]').forEach(btn => {
  const menu = document.getElementById(btn.getAttribute('aria-controls'));
  if (!menu) return;
  const set = open => { btn.setAttribute('aria-expanded', String(open)); menu.toggleAttribute('data-open', open); };
  btn.addEventListener('click', () => set(btn.getAttribute('aria-expanded') !== 'true'));
  document.addEventListener('keydown', e => {
    if (e.key === 'Escape' && btn.getAttribute('aria-expanded') === 'true') { set(false); btn.focus(); }
  });
  matchMedia('(min-width: 992px)').addEventListener('change', e => { if (e.matches) set(false); });
});

About this set

A header with the brand mark in the middle and the navigation split either side of it: Collections and Journal on the left, Stockists and Contact on the right, in small uppercase type, with a small “Est. 2014″ line under the name. It suits a fashion label, a studio or a boutique shop, where the mark matters more than the menu. The header is a CSS grid with three columns of 1fr, auto and 1fr, so the mark stays centred however many links sit either side, which a flex row cannot do without fixed widths. The nav spans all three columns as a subgrid, so its two lists line up with the outer columns while every link stays inside one labelled nav landmark. The current link is underlined from aria-current=”page”. Below 992px the mark stays centred with a menu button on the right, and the four links fold into a centred list underneath it. The Bootstrap version turns .navbar-collapse into the subgrid from 992px.

What’s included

  • Centred mark held by a 1fr auto 1fr grid
  • Both link groups in one nav landmark through CSS subgrid
  • Current page underlined from aria-current="page"
  • Centred menu list below 992px, closed with Esc
  • Bootstrap .navbar-collapse turned into a subgrid from 992px

Accessibility

All four links are in one nav labelled Main, which follows the mark in reading order, and the current link has aria-current="page". The menu button is a real button with an accessible name that reports aria-expanded; it opens with Enter or Space, and Esc closes the menu and returns focus to the button. Links and the button show a 2px dark outline on keyboard focus, and the menu icon transition switches off under prefers-reduced-motion.

Customise it

Change the hex values on .sp and .sp-menu for colour, the 1.35rem mark size and the 88px min-height for scale. In Bootstrap the link colours are the --bs-navbar-* variables on .sp; in Tailwind edit the text-[…] and aria-[current=page]: utilities.