Open demo

CSS code

HTML
<header class="mn">
  <a class="mn-logo" href="#">Ada Lovelace</a>
  <button class="mn-toggle" type="button" aria-expanded="false" aria-controls="mn-menu" data-menu-button>Menu</button>
  <nav class="mn-menu" id="mn-menu" aria-label="Main">
    <ul>
      <li><a href="#" aria-current="page">Writing</a></li>
      <li><a href="#">Projects</a></li>
      <li><a href="#">About</a></li>
    </ul>
  </nav>
</header>
CSS
/* Minimal header: no bar, border or background. It shares the page's max-width and side padding, so it lines up
   with the content below. Below 992px the links fold behind a text "Menu" button. */
.mn{max-width:1080px;margin:0 auto;padding:38px 36px 0;display:flex;flex-wrap:wrap;align-items:baseline;
  justify-content:space-between;column-gap:24px;color:#1a1d26}
.mn,.mn *{box-sizing:border-box}
.mn a{text-decoration:none}
.mn ul{list-style:none;margin:0;padding:0}
.mn a:focus-visible,.mn button:focus-visible{outline:2px solid #1a1d26;outline-offset:3px}
.mn-logo{font-weight:700;font-size:1.02rem;color:#1a1d26;letter-spacing:-.01em}
.mn-menu ul{display:flex;gap:22px}
.mn-menu a{position:relative;font-size:.92rem;color:#6b7385}
.mn-menu a::after{content:"";position:absolute;left:0;right:0;bottom:-3px;height:1px;background:#1a1d26;
  transform:scaleX(0);transform-origin:right;transition:transform .25s}
.mn-menu a:hover,.mn-menu a[aria-current="page"]{color:#1a1d26}
.mn-menu a:hover::after{transform:scaleX(1);transform-origin:left}
.mn-menu a[aria-current="page"]::after{transform:scaleX(1)}
.mn-toggle{display:none;padding:2px 0;font:inherit;font-size:.92rem;color:#1a1d26;background:none;border:0;
  border-bottom:1px solid #1a1d26;border-radius:0;cursor:pointer}
@media (max-width:991.98px){
  .mn{padding:28px 20px 0}
  .mn-toggle{display:block}
  .mn-menu{display:none;flex-basis:100%;padding-top:18px}
  .mn-menu[data-open]{display:block}
  .mn-menu ul{flex-direction:column;align-items:flex-start;gap:14px}
}
@media (prefers-reduced-motion:reduce){.mn a::after{transition:none}}
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 mn">
  <a class="navbar-brand" href="#">Ada Lovelace</a>
  <button class="navbar-toggler mn-toggle" type="button" data-bs-toggle="collapse" data-bs-target="#mn-menu" aria-controls="mn-menu" aria-expanded="false">Menu</button>
  <nav class="collapse navbar-collapse" id="mn-menu" aria-label="Main">
    <ul class="navbar-nav ms-lg-auto">
      <li class="nav-item"><a class="nav-link active" href="#" aria-current="page">Writing</a></li>
      <li class="nav-item"><a class="nav-link" href="#">Projects</a></li>
      <li class="nav-item"><a class="nav-link" href="#">About</a></li>
    </ul>
  </nav>
</header>
CSS
/* Bootstrap .navbar-expand-lg with the bar stripped away: no padding-y, no background, the page's max-width.
   The toggler is a text "Menu" button; the underline on the current link comes from aria-current. */
.mn{--bs-navbar-padding-x:36px;--bs-navbar-padding-y:0;--bs-navbar-color:#6b7385;--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.02rem;--bs-navbar-nav-link-padding-x:0;
  max-width:1080px;margin:0 auto;padding-top:38px;align-items:baseline;column-gap:24px}
.mn a{text-decoration:none}
.mn a:focus-visible,.mn button:focus-visible{outline:2px solid #1a1d26;outline-offset:3px;box-shadow:none}
.mn .navbar-brand{font-weight:700;letter-spacing:-.01em}
.mn .navbar-nav{--bs-nav-link-padding-y:0;--bs-nav-link-font-size:.92rem;--bs-nav-link-font-weight:400;gap:22px}
.mn .nav-link{position:relative}
.mn .nav-link::after{content:"";position:absolute;left:0;right:0;bottom:-3px;height:1px;background:#1a1d26;
  transform:scaleX(0);transform-origin:right;transition:transform .25s}
.mn .nav-link:hover::after{transform:scaleX(1);transform-origin:left}
.mn .nav-link.active::after{transform:scaleX(1)}
.mn .navbar-toggler{padding:2px 0;font-size:.92rem;line-height:normal;color:#1a1d26;border:0;border-bottom:1px solid #1a1d26;border-radius:0}
.mn .navbar-toggler:focus{box-shadow:none}
@media (max-width:991.98px){
  .mn{--bs-navbar-padding-x:20px;padding-top:28px}
  .mn .navbar-nav{align-items:flex-start;gap:14px;padding-top:18px}
}
@media (prefers-reduced-motion:reduce){.mn .nav-link::after{transition:none}}
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="mx-auto flex max-w-[1080px] flex-wrap items-baseline justify-between gap-x-6 px-9 pt-[38px] text-[#1a1d26] max-lg:px-5 max-lg:pt-7">
  <a class="text-[1.02rem] font-bold tracking-[-.01em] text-[#1a1d26] focus-visible:outline-2 focus-visible:outline-offset-[3px] focus-visible:outline-[#1a1d26]" href="#">Ada Lovelace</a>
  <button class="cursor-pointer border-b border-[#1a1d26] py-0.5 text-[.92rem] text-[#1a1d26] focus-visible:outline-2 focus-visible:outline-offset-[3px] focus-visible:outline-[#1a1d26] lg:hidden" type="button" aria-expanded="false" aria-controls="mn-menu" data-menu-button>Menu</button>
  <nav class="hidden data-open:block lg:block max-lg:basis-full max-lg:pt-[18px]" id="mn-menu" aria-label="Main">
    <ul class="flex gap-[22px] max-lg:flex-col max-lg:items-start max-lg:gap-3.5">
      <li><a class="relative text-[.92rem] text-[#6b7385] after:absolute after:inset-x-0 after:-bottom-[3px] after:h-px after:origin-right after:scale-x-0 after:bg-[#1a1d26] after:transition-transform after:duration-[250ms] after:content-[''] hover:text-[#1a1d26] hover:after:origin-left hover:after:scale-x-100 aria-[current=page]:text-[#1a1d26] aria-[current=page]:after:scale-x-100 motion-reduce:after:transition-none focus-visible:outline-2 focus-visible:outline-offset-[3px] focus-visible:outline-[#1a1d26]" href="#" aria-current="page">Writing</a></li>
      <li><a class="relative text-[.92rem] text-[#6b7385] after:absolute after:inset-x-0 after:-bottom-[3px] after:h-px after:origin-right after:scale-x-0 after:bg-[#1a1d26] after:transition-transform after:duration-[250ms] after:content-[''] hover:text-[#1a1d26] hover:after:origin-left hover:after:scale-x-100 aria-[current=page]:text-[#1a1d26] aria-[current=page]:after:scale-x-100 motion-reduce:after:transition-none focus-visible:outline-2 focus-visible:outline-offset-[3px] focus-visible:outline-[#1a1d26]" href="#">Projects</a></li>
      <li><a class="relative text-[.92rem] text-[#6b7385] after:absolute after:inset-x-0 after:-bottom-[3px] after:h-px after:origin-right after:scale-x-0 after:bg-[#1a1d26] after:transition-transform after:duration-[250ms] after:content-[''] hover:text-[#1a1d26] hover:after:origin-left hover:after:scale-x-100 aria-[current=page]:text-[#1a1d26] aria-[current=page]:after:scale-x-100 motion-reduce:after:transition-none focus-visible:outline-2 focus-visible:outline-offset-[3px] focus-visible:outline-[#1a1d26]" href="#">About</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

The lightest header in the pack: a name on the left and three text links on the right, with no bar, border or background. It shares the page’s 1080px max-width and side padding, so it lines up with the content below and the page starts where the eye already is. It suits a personal site, a writer’s portfolio or a small blog. The links are grey until hovered; a 1px underline then draws in from the left, and the current page keeps its underline because the CSS styles aria-current=”page” rather than a separate class. Below 992px the links fold behind a plain “Menu” text button instead of a hamburger icon, in keeping with the rest of the header, and open as a short stacked list. The underline is a scaled pseudo-element, so it animates with transform only, and the animation switches off under reduced motion. The Bootstrap version is a stripped .navbar-expand-lg whose toggler is the text button.

What’s included

  • No bar, border or background: aligned to the page margin
  • Underline draws in on hover and stays on the current page
  • Text "Menu" button instead of an icon below 992px
  • Underline animates with transform and stops under reduced motion
  • Bootstrap .navbar-expand-lg stripped back through its variables

Accessibility

The links sit in a nav labelled Main and the current page carries aria-current="page", which is also what draws its underline. The menu button's visible word "Menu" is its accessible name; it reports aria-expanded, and Esc closes the menu and returns focus to it. Links and the button show a 2px outline on keyboard focus, and the underline transition switches off under prefers-reduced-motion.

Customise it

Change the max-width and padding on .mn to match your page, and the #6b7385 and #1a1d26 values for link and underline colour. In Bootstrap use --bs-navbar-color and --bs-navbar-hover-color on .mn; in Tailwind edit the text-[…] and after:bg-[…] utilities.