Bold Full Screen Navigation

A full-screen overlay navigation with a clip-path reveal, oversized link typography, and a three-bar hamburger that animates into an X. Links slide up from below as the overlay opens, and hovering dims all other items. Entirely CSS-driven via a single data-navigation-status attribute.

navigationfullscreenoverlaycss animationno gsap

Code

HTML
html
<nav data-navigation-status="not-active" class="bold-nav-full">
  <div class="bold-nav-full__bar">
    <a href="#" class="bold-nav-full__logo w-inline-block">
      <!-- your logo SVG -->
    </a>
    <button data-navigation-toggle="toggle" class="bold-nav-full__hamburger">
      <div class="bold-nav-full__hamburger-bar"></div>
      <div class="bold-nav-full__hamburger-bar"></div>
      <div class="bold-nav-full__hamburger-bar"></div>
    </button>
  </div>
  <div class="bold-nav-full__tile">
    <ul class="bold-nav-full__ul">
      <li class="bold-nav-full__li">
        <a href="#" class="bold-nav-full__link"><span class="bold-nav-full__link-text">Home</span></a>
      </li>
      <li class="bold-nav-full__li">
        <a href="#" class="bold-nav-full__link is--current"><span class="bold-nav-full__link-text">Work</span></a>
      </li>
      <li class="bold-nav-full__li">
        <a href="#" class="bold-nav-full__link"><span class="bold-nav-full__link-text">Company</span></a>
      </li>
      <li class="bold-nav-full__li">
        <a href="#" class="bold-nav-full__link"><span class="bold-nav-full__link-text">Blog</span></a>
      </li>
      <li class="bold-nav-full__li">
        <a href="#" class="bold-nav-full__link"><span class="bold-nav-full__link-text">Contact</span></a>
      </li>
    </ul>
    <div class="bold-nav__bottom">
      <p class="bold-nav__word">Global Community</p>
      <p class="bold-nav__word">hello@osmo.supply</p>
    </div>
  </div>
</nav>
CSS
css
.bold-nav-full {
  z-index: 100;
  pointer-events: none;
  position: fixed;
  inset: 0;
}

.bold-nav-full__bar {
  z-index: 1;
  justify-content: space-between;
  width: 100%;
  padding: 2.5em;
  display: flex;
  position: absolute;
}

.bold-nav-full__logo {
  pointer-events: auto;
  color: #f4f4f4;
  justify-content: center;
  align-items: center;
  width: 8em;
  height: 2em;
  display: flex;
}

/* Hamburger */
.bold-nav-full__hamburger {
  pointer-events: auto;
  color: #f4f4f4;
  cursor: pointer;
  background-color: #0000;
  justify-content: center;
  align-items: center;
  width: 3em;
  height: 3em;
  display: flex;
  position: relative;
  overflow: hidden;
}

.bold-nav-full__hamburger .bold-nav-full__hamburger-bar {
  background-color: currentColor;
  width: 2em;
  height: .125em;
  position: absolute;
  transform: translate(0, 0) rotate(0.001deg);
  transition: transform 0.5s cubic-bezier(.7, 0, .3, 1);
}

.bold-nav-full__hamburger .bold-nav-full__hamburger-bar:nth-child(1) {
  transform: translate(0, -.45em) scale(1, 1) rotate(0.001deg);
}

.bold-nav-full__hamburger .bold-nav-full__hamburger-bar:nth-child(3) {
  transform: translate(0, .45em) scale(1, 1) rotate(0.001deg);
}

/* Hamburger - Hover */
.bold-nav-full__hamburger:hover .bold-nav-full__hamburger-bar:nth-child(1) {
  transform: translate(0, -.45em) scale(.5, 1) rotate(0.001deg);
}

.bold-nav-full__hamburger:hover .bold-nav-full__hamburger-bar:nth-child(3) {
  transform: translate(0, .45em) scale(.5, 1) rotate(0.001deg);
}

/* Hamburger - Open */
[data-navigation-status="active"] .bold-nav-full__hamburger-bar:nth-child(1) {
  transform: translate(0, 0) rotate(45deg) scale(1, 1);
}

[data-navigation-status="active"] .bold-nav-full__hamburger-bar:nth-child(2) {
  transform: translate(-150%, 0) rotate(0.001deg) scale(1, 1);
}

[data-navigation-status="active"] .bold-nav-full__hamburger-bar:nth-child(3) {
  transform: translate(0, 0) rotate(-45deg) scale(1, 1);
}

/* Hamburger - Hover (Open) */
[data-navigation-status="active"] .bold-nav-full__hamburger:hover .bold-nav-full__hamburger-bar:nth-child(1) {
  transform: translate(0, 0) rotate(45deg) scale(.7, 1);
}

[data-navigation-status="active"] .bold-nav-full__hamburger:hover .bold-nav-full__hamburger-bar:nth-child(3) {
  transform: translate(0, 0) rotate(-45deg) scale(.7, 1);
}

/* Tile */
.bold-nav-full__tile {
  pointer-events: auto;
  background-color: #1b372e;
  flex-flow: column;
  justify-content: center;
  align-items: center;
  width: 100%;
  height: 100%;
  display: flex;
  position: absolute;
  top: 0;
  left: 0;
  transition: clip-path 1s cubic-bezier(.9, 0, .1, 1);
  clip-path: polygon(0% 0%, 100% 0%, 100% 0%, 0% 0%);
}

[data-navigation-status="active"] .bold-nav-full__tile {
  clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%);
}

.bold-nav-full__ul {
  flex-flow: column;
  align-items: center;
  margin: 0;
  padding: 0;
  display: flex;
}

.bold-nav-full__li {
  justify-content: center;
  align-items: center;
  margin: 0;
  padding: 0;
  text-decoration: none;
  display: flex;
  position: relative;
  overflow: hidden;
}

.bold-nav-full__link {
  color: #f4f4f4;
  letter-spacing: -.04em;
  padding-left: .075em;
  padding-right: .075em;
  font-family: Haffer XH, Arial, sans-serif;
  font-size: calc(4vw + 4vh);
  font-weight: 400;
  line-height: 1.1;
  text-decoration: none;
  transform: translateY(100%) rotate(5deg);
  transition: transform 0.75s cubic-bezier(.7, 0, .3, 1);
}

.bold-nav-full__link.is--current {
  color: #d0ff00;
}

.bold-nav-full__li:nth-child(1) .bold-nav-full__link { transition-delay: 0.2s; }
.bold-nav-full__li:nth-child(2) .bold-nav-full__link { transition-delay: 0.15s; }
.bold-nav-full__li:nth-child(3) .bold-nav-full__link { transition-delay: 0.1s; }
.bold-nav-full__li:nth-child(4) .bold-nav-full__link { transition-delay: 0.05s; }
.bold-nav-full__li:nth-child(5) .bold-nav-full__link { transition-delay: 0s; }

/* Links - Open */
[data-navigation-status="active"] .bold-nav-full__link {
  transform: translateY(0%) rotate(0.001deg);
}

[data-navigation-status="active"] .bold-nav-full__li:nth-child(1) .bold-nav-full__link { transition-delay: 0.3s; }
[data-navigation-status="active"] .bold-nav-full__li:nth-child(2) .bold-nav-full__link { transition-delay: 0.35s; }
[data-navigation-status="active"] .bold-nav-full__li:nth-child(3) .bold-nav-full__link { transition-delay: 0.4s; }
[data-navigation-status="active"] .bold-nav-full__li:nth-child(4) .bold-nav-full__link { transition-delay: 0.45s; }
[data-navigation-status="active"] .bold-nav-full__li:nth-child(5) .bold-nav-full__link { transition-delay: 0.5s; }

.bold-nav-full__link-text {
  text-shadow: 0 1.1em 0;
  display: block;
  position: relative;
}

/* Links - Hover dim */
.bold-nav-full__li {
  transition: opacity 0.5s cubic-bezier(.7, 0, .3, 1);
}

.bold-nav-full__ul:has(.bold-nav-full__li:hover) .bold-nav-full__li {
  opacity: 0.15;
}

.bold-nav-full__ul:has(.bold-nav-full__li:hover) .bold-nav-full__li:hover {
  opacity: 1;
}

/* Links - Hover slide */
.bold-nav-full__link .bold-nav-full__link-text {
  transition: transform 0.5s cubic-bezier(.7, 0, .3, 1);
  transform: translateY(0%) rotate(0.001deg);
}

.bold-nav-full__link:hover .bold-nav-full__link-text {
  transform: translateY(-100%) rotate(0.001deg);
}

/* Bottom */
.bold-nav__bottom {
  justify-content: space-between;
  align-items: center;
  width: 100%;
  padding: 2.25em 2.5em;
  display: flex;
  position: absolute;
  bottom: 0;
  left: 0;
}

.bold-nav__word {
  opacity: .5;
  margin-bottom: 0;
  font-size: 1.125em;
  position: relative;
}
JavaScript
javascript
function initBoldFullScreenNavigation() {
  // Toggle Navigation
  document.querySelectorAll('[data-navigation-toggle="toggle"]').forEach(toggleBtn => {
    toggleBtn.addEventListener('click', () => {
      const navStatusEl = document.querySelector('[data-navigation-status]');
      if (!navStatusEl) return;
      if (navStatusEl.getAttribute('data-navigation-status') === 'not-active') {
        navStatusEl.setAttribute('data-navigation-status', 'active');
        // If you use Lenis you can 'stop' Lenis here: Example Lenis.stop();
      } else {
        navStatusEl.setAttribute('data-navigation-status', 'not-active');
        // If you use Lenis you can 'start' Lenis here: Example Lenis.start();
      }
    });
  });

  // Close Navigation
  document.querySelectorAll('[data-navigation-toggle="close"]').forEach(closeBtn => {
    closeBtn.addEventListener('click', () => {
      const navStatusEl = document.querySelector('[data-navigation-status]');
      if (!navStatusEl) return;
      navStatusEl.setAttribute('data-navigation-status', 'not-active');
      // If you use Lenis you can 'start' Lenis here: Example Lenis.start();
    });
  });

  // ESC closes
  document.addEventListener('keydown', e => {
    if (e.keyCode === 27) {
      const navStatusEl = document.querySelector('[data-navigation-status]');
      if (!navStatusEl) return;
      if (navStatusEl.getAttribute('data-navigation-status') === 'active') {
        navStatusEl.setAttribute('data-navigation-status', 'not-active');
        // If you use Lenis you can 'start' Lenis here: Example Lenis.start();
      }
    }
  });
}

document.addEventListener('DOMContentLoaded', function() {
  initBoldFullScreenNavigation();
});

Attributes

NameTypeDefaultDescription
data-navigation-status"active" | "not-active""not-active"Controls the open/closed state. Can be placed on the <nav> element or on <body> if you want all page children to react. Flipping to "active" triggers the clip-path reveal and link slide-up.
data-navigation-toggle="toggle"attributeAttach to any element that should toggle the nav between active and not-active. Typically placed on the hamburger button.
data-navigation-toggle="close"attributeAttach to any element that should force the nav closed, such as a close icon or a nav link.

Notes

  • No GSAP required — all animation is CSS-driven.
  • The data-navigation-status attribute can be placed on the <nav> or on <body> to scope CSS selectors more broadly.
  • Add data-navigation-toggle="close" to individual nav links to auto-close the menu on click.
  • Pressing Escape closes the nav via the keydown listener.
  • To integrate Lenis, call Lenis.stop() on open and Lenis.start() on close inside the toggle handler.

Guide

Overlay reveal

The full-screen tile opens and closes via clip-path. The closed state clips the tile to zero height (polygon top edge = bottom edge), and the active state expands it to cover the full viewport. The transition is 1s with a strong ease-in/out curve for a snappy feel.

Link reveal choreography

Each link starts at translateY(100%) rotate(5deg) so it sits below and slightly tilted, hidden by the parent overflow:hidden. On open, a staggered transition-delay (0.3s → 0.5s) slides each link into place. On close, the delays reverse (0.2s → 0s) so links exit faster than the overlay.

Hover dimming

Uses :has() to dim all sibling list items to 0.15 opacity when any item is hovered, while the hovered item stays at full opacity. The hover text slide uses text-shadow: 0 1.1em 0 on .bold-nav-full__link-text to create a ghost copy of the text one line below, which slides into view on hover.

Active link

Add the .is--current class to a .bold-nav-full__link to highlight it in the accent color (#d0ff00 in the default theme).