feat: Navigationsleiste fertig und bereit zum einbinden

feature/navigationsleiste
Emirhan Sahin 2026-09-27 17:47:43 +00:00
parent 7059b41bfe
commit 33e844423b
3 changed files with 72 additions and 34 deletions

View File

@ -2,11 +2,7 @@
<header class="navbar" id="site-navbar">
<div class="navbar__inner">
<a
href="/src/design/tri-hub-ernaehrungsberatung.html"
class="navbar__brand"
aria-label="TriHub Startseite"
>
<div class="navbar__brand">
<img
src="/src/components/navigationsbar/images/logo.png"
alt=""
@ -15,10 +11,10 @@
<span class="navbar__brand-text">
<span class="navbar__brand-title">TRI-HUB</span>
<span class="navbar__brand-tagline"
>Triathlon als sportliches Zuhause ab 50</span
>Ernährungsberatung für Triathleten ab 50</span
>
</span>
</a>
</div>
<button
class="navbar__toggle"
@ -50,6 +46,28 @@
<li>
<a href="/kontakt.html" class="navbar__link">Kontakt</a>
</li>
<li>
<a
href="https://tri-hub.de/"
class="navbar__link navbar__link--home"
>
<span class="navbar__home-icon" aria-hidden="true">
<svg
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M4 10L12 3L20 10V20a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V10Z M9 21V14H15V21"
stroke="currentColor"
stroke-linejoin="round"
stroke-linecap="round"
/>
</svg>
</span>
Startseite
</a>
</li>
</ul>
</nav>
</div>

View File

@ -1,6 +1,7 @@
/**
* Lädt das Navbar-Fragment (navigation.html) per fetch() und ersetzt
* damit den Platzhalter im Header der jeweiligen Seite.
* Aufruf z. B. in main.js: initNavbar('#navbar-placeholder')
*/
export function initNavbar(placeholderSelector = "#navbar-placeholder") {
const placeholder = document.querySelector(placeholderSelector);
@ -38,15 +39,12 @@ export function setupBehavior() {
let openedViaKeyboard = false;
// Merken, ob der Toggle-Button per Tastatur (statt Maus) ausgelöst wurde
toggle.addEventListener("keydown", (e) => {
if (e.key === "Enter" || e.key === " ") {
openedViaKeyboard = true;
}
});
// Menü auf-/zuklappen; funktioniert nativ per Klick UND per Enter/Space,
// da .navbar__toggle ein echtes <button>-Element ist
toggle.addEventListener("click", () => {
const isOpen = nav.classList.toggle("is-open");
toggle.setAttribute("aria-expanded", String(isOpen));
@ -56,14 +54,12 @@ export function setupBehavior() {
);
if (isOpen && openedViaKeyboard) {
// Bei Tastatur-Öffnung direkt in den ersten Menüpunkt springen
const firstLink = menu.querySelector(".navbar__link");
if (firstLink) firstLink.focus();
}
openedViaKeyboard = false;
});
// Escape schließt das Menü, Fokus geht zurück auf den Toggle-Button
document.addEventListener("keydown", (e) => {
if (e.key === "Escape" && nav.classList.contains("is-open")) {
nav.classList.remove("is-open");
@ -73,7 +69,6 @@ export function setupBehavior() {
}
});
// Schließt das Menü automatisch, sobald der Fokus die Navbar per Tab verlässt
navbar.addEventListener("focusout", (e) => {
const leavingNavbar = !navbar.contains(e.relatedTarget);
if (leavingNavbar && nav.classList.contains("is-open")) {
@ -83,7 +78,6 @@ export function setupBehavior() {
}
});
// Klick außerhalb der Navbar schließt das mobile Menü (Maus/Touch-Nutzer)
document.addEventListener("click", (e) => {
if (!navbar.contains(e.target) && nav.classList.contains("is-open")) {
nav.classList.remove("is-open");
@ -107,5 +101,4 @@ export function markCurrentPage() {
});
}
// Startet die Navbar automatisch, sobald die Seite geladen ist
document.addEventListener("DOMContentLoaded", () => initNavbar());

View File

@ -11,8 +11,7 @@
--nav-muted: #94a3b8;
}
/* Verhindert, dass Padding die Breite von Elementen zusätzlich vergrößert
(ohne das würde die Navbar breiter als der Bildschirm werden) */
/* Verhindert, dass Padding die Breite von Elementen zusätzlich vergrößert */
.navbar,
.navbar *,
.navbar *::before,
@ -26,13 +25,12 @@
top: 0;
left: 0;
width: 100%;
z-index: 1000; /* bleibt über allen anderen Inhalten */
z-index: 1000;
border-bottom: 1px solid var(--nav-border);
background: var(--nav-bg);
font-family: "Inter", system-ui, sans-serif;
}
/* Innerer Container: Logo links, Menü rechts, mit etwas Innenabstand */
.navbar__inner {
width: 100%;
min-height: 76px;
@ -43,13 +41,12 @@
gap: 16px;
}
/* ---------- Logo + Markenname (klickbarer Link, ganz links) ---------- */
/* ---------- Logo + Markenname (kein Link mehr, nur Anzeige) ---------- */
.navbar__brand {
display: inline-flex;
align-items: center;
gap: 12px;
text-decoration: none;
flex-shrink: 0; /* schrumpft nie, auch wenn das Menü eng wird */
flex-shrink: 0;
}
.navbar__logo-img {
@ -78,7 +75,7 @@
color: var(--nav-muted);
}
/* ---------- Menüpunkte (ganz rechts) ---------- */
/* ---------- Menüpunkte (rechts) ---------- */
.navbar__menu {
display: flex;
align-items: center;
@ -97,7 +94,7 @@
text-decoration: none;
transition: color 0.2s ease;
padding: 0.35rem 0.1rem;
white-space: nowrap; /* verhindert Zeilenumbruch mitten im Linktext */
white-space: nowrap;
}
.navbar__link:hover,
@ -105,9 +102,43 @@
color: var(--nav-white);
}
/* ---------- Kriterium 2: barrierefreie Tastatursteuerung ---------- */
/* ---------- "Startseite"-Button mit Haus-Icon, ganz rechts ---------- */
.navbar__link--home {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 6px 18px 6px 10px;
border: 1px solid rgba(148, 163, 184, 0.3);
border-radius: 999px;
color: var(--nav-light);
transition:
border-color 0.2s ease,
color 0.2s ease;
}
/* Skip-Link: unsichtbar, bis er per Tab fokussiert wird */
.navbar__link--home:hover {
border-color: rgba(16, 185, 129, 0.55);
color: var(--nav-white);
}
.navbar__home-icon {
display: inline-flex;
align-items: center;
justify-content: center;
color: #22d3ee;
}
.navbar__home-icon svg {
width: 18px;
height: 18px;
}
/* Linienstärke des Haus-Icons zentral hier steuern statt im SVG-Markup */
.navbar__home-icon svg path {
stroke-width: 1.5;
}
/* ---------- Kriterium 2: barrierefreie Tastatursteuerung ---------- */
.skip-link {
position: absolute;
top: -40px;
@ -124,7 +155,6 @@
top: 0;
}
/* Sichtbarer, einheitlicher Fokus-Ring für alle interaktiven Elemente */
.navbar a:focus-visible,
.navbar button:focus-visible {
outline: 3px solid var(--nav-green);
@ -132,7 +162,7 @@
border-radius: 4px;
}
/* ---------- Mobiler Hamburger-Button (nur auf schmalen Bildschirmen sichtbar) ---------- */
/* ---------- Mobiler Hamburger-Button ---------- */
.navbar__toggle {
display: none;
background: none;
@ -162,8 +192,6 @@
top: 7px;
}
/* Ab dieser Breite wechselt die Navbar auf den Hamburger,
damit die Menüpunkte nie über den Bildschirmrand hinausragen */
@media (max-width: 1300px) {
.navbar__toggle {
display: block;
@ -176,11 +204,11 @@
right: 0;
background: var(--nav-bg);
border-bottom: 1px solid var(--nav-border);
display: none; /* standardmäßig eingeklappt */
display: none;
}
.navbar__nav.is-open {
display: block; /* wird per JS umgeschaltet */
display: block;
}
.navbar__menu {
@ -192,7 +220,6 @@
}
}
/* Auf sehr schmalen Bildschirmen den Untertitel ausblenden, spart Platz */
@media (max-width: 600px) {
.navbar__inner {
padding: 0 16px;
@ -203,7 +230,7 @@
}
}
/* Platz für die fixierte Navbar, damit sie keinen Inhalt verdeckt */
/* Platz für die fixierte Navbar */
body {
padding-top: 76px;
}