feat: pure-CSS hamburger menu for public nav (≤640px)

This commit is contained in:
Pontoporeia
2026-04-29 22:12:19 +02:00
parent c27ffafa7e
commit 11f429eb72
2 changed files with 167 additions and 6 deletions

View File

@@ -125,6 +125,147 @@ header {
border-bottom: 1px solid var(--header-nav-active-border); border-bottom: 1px solid var(--header-nav-active-border);
padding-bottom: 1px; padding-bottom: 1px;
} }
/* nav-top-row: transparent wrapper at desktop — children become
direct flex items of nav, preserving the existing layout */
.nav-top-row {
display: contents;
}
/* nav-mobile-links: mobile-only dropdown, hidden at desktop */
.nav-mobile-links {
display: none;
}
}
/* ============================================================
HAMBURGER MENU — public nav (pure CSS, checkbox trick)
DOM order inside <header> (public only):
input.menu-btn ← off-screen checkbox
nav
div.nav-top-row ← always-visible row (logo + burger)
div.nav-left ← logo + desktop link list
ul.nav-right-links ← desktop right links
label.menu-icon ← burger icon trigger
ul.nav-mobile-links ← full dropdown (hidden by default)
At desktop: .menu-icon and .nav-mobile-links are display:none.
.nav-top-row is display:contents so its children
participate directly in navs flex row.
At mobile: nav becomes a flex column. .nav-top-row is a real
flex row (logo | burger). .nav-mobile-links expands
via max-height on checkbox:checked.
============================================================ */
/* Off-screen checkbox — triggered by its label */
.menu-btn {
position: absolute;
top: -9999px;
left: -9999px;
}
/* Burger label — takes no space at desktop */
.menu-icon {
display: none;
cursor: pointer;
padding: var(--space-2xs) var(--space-s);
align-items: center;
justify-content: center;
}
/* Middle bar of the burger icon */
.navicon {
background: var(--accent-foreground);
display: block;
height: 2px;
width: 24px;
position: relative;
transition: all 0.3s ease-out;
}
/* Top and bottom bars */
.navicon::before,
.navicon::after {
content: '';
background: var(--accent-foreground);
display: block;
height: 2px;
width: 100%;
position: absolute;
transition: all 0.3s ease-out;
}
.navicon::before { top: -7px; }
.navicon::after { bottom: -7px; }
/* ---- Mobile ---- */
@media screen and (max-width: 640px) {
/* Nav becomes a flex column: top-row on row 1, dropdown on row 2 */
header nav[aria-label="Navigation principale"] {
display: flex;
flex-direction: column;
padding: 0;
}
/* Top row: logo left, hamburger right */
header nav[aria-label="Navigation principale"] .nav-top-row {
display: flex;
align-items: center;
justify-content: space-between;
padding: var(--space-s);
}
/* Hide desktop link lists inside the top row */
header nav[aria-label="Navigation principale"] .nav-left-links,
header nav[aria-label="Navigation principale"] .nav-right-links {
display: none;
}
/* Reveal the hamburger icon */
.menu-icon {
display: flex;
}
/* Dropdown: clipped by default */
header nav[aria-label="Navigation principale"] .nav-mobile-links {
list-style: none;
margin: 0;
padding: 0;
max-height: 0;
overflow: hidden;
transition: max-height 0.2s ease-out;
}
/* ---- Open state ---- */
.menu-btn:checked ~ nav[aria-label="Navigation principale"] .nav-mobile-links {
max-height: 300px;
}
/* Dropdown link rows */
header nav[aria-label="Navigation principale"] .nav-mobile-links li {
border-top: 1px solid var(--header-nav-active-border);
}
header nav[aria-label="Navigation principale"] .nav-mobile-links li a {
display: block;
padding: var(--space-xs) var(--space-s);
}
/* ---- Animate burger → X ---- */
.menu-btn:checked ~ nav[aria-label="Navigation principale"] .menu-icon .navicon {
background: transparent;
}
.menu-btn:checked ~ nav[aria-label="Navigation principale"] .menu-icon .navicon::before {
transform: rotate(-45deg);
top: 0;
}
.menu-btn:checked ~ nav[aria-label="Navigation principale"] .menu-icon .navicon::after {
transform: rotate(45deg);
bottom: 0;
}
} }
main { main {

View File

@@ -37,7 +37,9 @@ $_thesisId = $_GET['id'] ?? null;
<?php else: ?> <?php else: ?>
<input class="menu-btn" type="checkbox" id="menu-btn" name="menu-btn" />
<nav aria-label="Navigation principale"> <nav aria-label="Navigation principale">
<div class="nav-top-row">
<div class="nav-left"> <div class="nav-left">
<a href="/" class="nav-logo">Xamxam</a> <a href="/" class="nav-logo">Xamxam</a>
<ul class="nav-left-links"> <ul class="nav-left-links">
@@ -57,6 +59,24 @@ $_thesisId = $_GET['id'] ?? null;
<?= ($_navCurrent === 'apropos') ? 'aria-current="page"' : '' ?>>À Propos</a> <?= ($_navCurrent === 'apropos') ? 'aria-current="page"' : '' ?>>À Propos</a>
</li> </li>
</ul> </ul>
<label class="menu-icon" for="menu-btn">
<span class="navicon" aria-label="Menu de navigation"></span>
</label>
</div>
<ul class="nav-mobile-links">
<li>
<a href="/repertoire"
<?= ($_navCurrent === 'repertoire') ? 'aria-current="page"' : '' ?>>Répertoire</a>
</li>
<li>
<a href="/licence"
<?= ($_navCurrent === 'licence') ? 'aria-current="page"' : '' ?>>Licences</a>
</li>
<li>
<a href="/apropos"
<?= ($_navCurrent === 'apropos') ? 'aria-current="page"' : '' ?>>À Propos</a>
</li>
</ul>
</nav> </nav>
<?php endif; ?> <?php endif; ?>