Ajout d'une navigation mobile avec menu burger pour améliorer l'expérience utilisateur sur petits écrans.

This commit is contained in:
mrtoine 2025-12-15 12:27:39 +01:00
parent 82867e14e4
commit 093c6e58a0
3 changed files with 149 additions and 1 deletions

View file

@ -438,6 +438,115 @@ body {
white-space: nowrap; /* Prevents text from wrapping */ white-space: nowrap; /* Prevents text from wrapping */
} }
/* Burger / mobile navigation */
.nav-toggle {
display: none;
align-items: center;
justify-content: center;
gap: 8px;
padding: 8px 12px;
border-radius: var(--r-2);
}
@media (max-width: 900px) {
.site-nav {
position: sticky;
top: 0;
flex-wrap: wrap;
padding: var(--space-2) var(--gutter);
}
.brand { display: flex; align-items: center; gap: 12px; }
/* Put the burger to the right of the brand */
.nav-toggle { display: inline-flex; margin-left: auto; position: relative; z-index: 1301; }
/* Off-canvas menu (hidden to the right by default) */
.navbar {
position: fixed;
top: 0;
right: 0;
height: 100vh;
/* Ensure total box never exceeds the viewport width (padding + border included) */
box-sizing: border-box;
width: min(85vw, 380px);
max-width: 100vw;
margin: 0;
/* Safe-area aware padding on the right (iOS notch) */
padding: var(--space-5) max(var(--gutter), env(safe-area-inset-right)) var(--space-5) var(--gutter);
display: flex;
flex-direction: column;
gap: var(--space-3);
background: var(--surface);
border-left: 1px solid var(--border);
box-shadow: var(--shadow-3);
z-index: 1200;
overflow-y: auto;
-webkit-overflow-scrolling: touch;
transform: translateX(100%);
opacity: 0;
visibility: hidden;
pointer-events: none;
transition: transform var(--transition-2), opacity var(--transition-2), visibility 0s linear 320ms;
}
.navbar.is-open {
transform: translateX(0);
opacity: 1;
visibility: visible;
pointer-events: auto;
transition: transform var(--transition-2), opacity var(--transition-2), visibility 0s;
}
/* Dim background when menu is open (requires :has support) */
body:has(#navToggle[aria-expanded="true"]) { overflow: hidden; }
.site-nav:has(#navToggle[aria-expanded="true"])::after {
content: "";
position: fixed;
inset: 0;
background: rgba(0,0,0,0.45);
backdrop-filter: blur(2px);
z-index: 1100;
}
.navbar ul { flex-direction: column; width: 100%; }
.navbar li { margin: 0; }
.navbar a { display: block; padding: 12px 14px; border-radius: var(--r-1); }
/* Dropdowns behave as inline lists on mobile */
.navbar ul ul {
position: static;
transform: none;
display: block;
background: transparent;
border: 0;
padding-left: 10px;
}
.navbar ul ul li { border: 0; margin: 0; padding: 6px 8px; }
.navend {
width: 100%;
margin-top: auto; /* push to bottom */
display: flex;
flex-direction: column;
align-items: stretch;
gap: 6px;
}
.navend ul { width: 100%; }
}
/* Respect reduced motion preferences */
@media (max-width: 900px) and (prefers-reduced-motion: reduce) {
.navbar,
.navbar.is-open,
.site-nav:has(#navToggle[aria-expanded="true"])::after {
transition: none !important;
}
}
.brand { .brand {
display: flex; display: flex;
flex-direction: column; flex-direction: column;

View file

@ -58,6 +58,42 @@ document.addEventListener('DOMContentLoaded', function() {
}); });
} }
} catch(e) {} } catch(e) {}
// Mobile nav toggle
try {
var navToggle = document.getElementById('navToggle');
var primaryNav = document.getElementById('primaryNav');
if (navToggle && primaryNav) {
function setExpanded(expanded) {
navToggle.setAttribute('aria-expanded', expanded ? 'true' : 'false');
navToggle.setAttribute('aria-label', expanded ? 'Fermer le menu' : 'Ouvrir le menu');
var icon = navToggle.querySelector('i');
if (icon) {
icon.classList.remove('fa-bars','fa-xmark');
icon.classList.add(expanded ? 'fa-xmark' : 'fa-bars');
}
primaryNav.classList.toggle('is-open', expanded);
}
navToggle.addEventListener('click', function() {
var expanded = navToggle.getAttribute('aria-expanded') === 'true';
setExpanded(!expanded);
});
// Close menu when a link is clicked (on small screens)
primaryNav.addEventListener('click', function(e) {
var target = e.target;
if (target.tagName === 'A' || target.closest('a')) {
setExpanded(false);
}
});
// Close on Escape
document.addEventListener('keydown', function(e) {
if (e.key === 'Escape') setExpanded(false);
});
}
} catch(e) {}
}); });
// Fonction pour générer des flocons de neige // Fonction pour générer des flocons de neige

View file

@ -6,7 +6,10 @@
</div> </div>
<span class="subtitle comment">/* Anthony Violet */</span> <span class="subtitle comment">/* Anthony Violet */</span>
</div> </div>
<div class="navbar"> <button id="navToggle" class="nav-toggle button button-ghost" aria-label="Ouvrir le menu" aria-controls="primaryNav" aria-expanded="false">
<i class="fa-solid fa-bars"></i>
</button>
<div id="primaryNav" class="navbar" aria-label="Navigation principale">
<ul id="menu"> <ul id="menu">
<li><a href="/" class="house"><i class="fa-solid fa-house"></i></a></li> <li><a href="/" class="house"><i class="fa-solid fa-house"></i></a></li>
<li> <li>