Skip to main content

Overview

The Navigation component provides a fixed header with desktop menu, language switcher, and mobile overlay menu. It features smart hide/show behavior on scroll and smooth animations.

Location

src/components/Navigation.astro

Usage

---
import Navigation from '../components/Navigation.astro';
---

<Navigation />
The component automatically detects the current language from the URL and manages translations.

Features

Desktop Navigation

  • Fixed header with blur backdrop
  • Auto-hide on scroll down, show on scroll up
  • Show on mouse hover near top of page
  • Underline animation on link hover
  • Logo with invert filter for dark background

Language Switcher

Built-in bilingual support (Spanish/English):
src/components/Navigation.astro
const getSwitchPath = (targetLang: string) => {
  const parts = currentPath.split("/").filter(Boolean);
  if (parts[0] === "en" || parts[0] === "es") {
    parts.shift();
  }
  return targetLang === "es" ? `/${parts.join("/")}` : `/en/${parts.join("/")}`;
};
The language switcher:
  • Preserves current page path when switching languages
  • Shows active language with bold styling
  • Available in both desktop and mobile menus

Mobile Menu

  • Hamburger icon transforms to X when open
  • Full-screen overlay with staggered animation
  • Menu items fade in sequentially
  • Prevents scroll when open
  • Closes when navigation link is clicked

Structure

<nav class="navigation" id="main-nav">
  <div class="container nav-container">
    <a href={translatePath("/")} class="logo">
      <img src="/Logo_adosa.svg" alt="Logo Adosa" />
    </a>

    <ul class="nav-menu desktop-only">
      <li><a href={translatePath("/")}>{t("nav.home")}</a></li>
      <li><a href={translatePath("/propiedades")}>{t("nav.properties")}</a></li>
      <li><a href={translatePath("/mision")}>{t("nav.mission")}</a></li>
      <li><a href={translatePath("/contacto")}>{t("nav.contact")}</a></li>
      <li class="lang-switcher">
        <a href={getSwitchPath("es")}>ES</a>
        <span>|</span>
        <a href={getSwitchPath("en")}>EN</a>
      </li>
    </ul>

    <button class="hamburger" id="hamburger">
      <div class="line line-1"></div>
      <div class="line line-2"></div>
    </button>
  </div>
</nav>

Styling

background-color
color
default:"rgba(26, 26, 26, 0.35)"
Semi-transparent dark background with blur effect
height
string
default:"var(--height-nav, 90px)"
Fixed navigation height
z-index
number
default:"3000"
High z-index to stay above content and mobile overlay

Key Animations

Hide/Show on Scroll
.navigation {
  transition: transform 0.6s cubic-bezier(0.25, 1, 0.5, 1);
}

.navigation.nav-hidden {
  transform: translateY(-100%);
}
Link Underline Effect
.nav-menu a::after {
  content: "";
  position: absolute;
  bottom: 0;
  left: 0;
  width: 0;
  height: 1px;
  background-color: var(--color-1);
  transition: width 0.3s ease;
}

.nav-menu a:hover::after {
  width: 100%;
}

JavaScript Behavior

The component uses GSAP and vanilla JavaScript for interactions:
let lastScrollTop = 0;
const threshold = 50;

window.addEventListener('scroll', () => {
  const st = window.scrollY;
  
  if (st < 10) {
    nav?.classList.remove('nav-hidden');
    return;
  }
  
  if (Math.abs(lastScrollTop - st) <= threshold) return;
  
  if (st > lastScrollTop) {
    // Scroll Down -> Hide
    nav?.classList.add('nav-hidden');
  } else {
    // Scroll Up -> Show
    nav?.classList.remove('nav-hidden');
  }
  lastScrollTop = st;
});

Responsive Breakpoints

@media (max-width: 1023px) {
  /* Hide desktop menu */
  .desktop-only {
    display: none !important;
  }
  
  /* Show hamburger */
  .hamburger {
    display: flex;
  }
}

@media (max-width: 1023px) and (orientation: landscape) {
  /* Adjust overlay for landscape mobile */
  .mobile-overlay {
    align-items: flex-start;
    overflow-y: auto;
  }
  
  .overlay-link {
    font-size: 1.8rem;
  }
}

Customization

Edit both desktop and mobile menu sections:
<ul class="nav-menu desktop-only">
  <li><a href={translatePath("/new-page")}>{t("nav.newPage")}</a></li>
  <!-- Add more links -->
</ul>

<ul class="overlay-menu">
  <li><a href={translatePath("/new-page")} class="overlay-link">{t("nav.newPage")}</a></li>
  <!-- Add more links -->
</ul>

Adjusting Colors

.navigation {
  background-color: rgba(26, 26, 26, 0.35); /* Change opacity */
}

.nav-menu a {
  color: var(--color-1); /* Link color */
}

.mobile-overlay {
  background-color: var(--color-1); /* Overlay background */
}

Footer

Site footer component

Internationalization

Learn about i18n utilities

Build docs developers (and LLMs) love