menu : toggle open/close, scroll lock, transitions CSS, touche échap, clic extérieur

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
isUnknown 2026-05-27 19:08:05 +02:00
parent 39ce735ca6
commit 8df354bfcb
4 changed files with 97 additions and 9 deletions

View file

@ -46,4 +46,29 @@
z-index: -1;
transform: translateY(var(--logo-offset));
}
&.menu-transitioning {
.logo {
transition: transform 0.5s ease-in-out;
}
.characters {
transition: margin-top 0.5s ease-in-out;
svg {
transition: width 0.5s ease-in-out, height 0.5s ease-in-out;
}
}
}
&.big {
.logo {
transform: translateY(0);
}
.characters {
margin-top: 9.5rem;
svg {
width: 304px;
height: 304px;
}
}
}
}

View file

@ -8,22 +8,31 @@
color: #fff;
border-radius: var(--radius);
border: var(--border);
overflow: hidden;
margin-top: -1rem;
height: 7.3rem;
transition: height 0.5s ease-in-out;
* {
font-size: 2rem;
font-weight: 600;
text-align: center;
}
h1 {
font-size: 4rem;
}
nav {
ul {
position: absolute;
width: 100%;
padding: 0 var(--space-body);
display: flex;
justify-content: center;
gap: 1rem;
margin-top: 2rem;
font-size: 2rem;
}
}
&.open {
height: 90vh;
}
}

View file

@ -1,4 +1,5 @@
document.addEventListener("DOMContentLoaded", () => {
const header = document.querySelector(".main-header");
const charactersWrapper = document.querySelector(".characters");
const logo = document.querySelector(".logo");
const svg = charactersWrapper.querySelector("svg");
@ -14,7 +15,11 @@ document.addEventListener("DOMContentLoaded", () => {
);
const logoMax = logo.offsetHeight + 100;
let menuOpen = false;
let menuTransitioning = false;
function onScroll() {
if (menuOpen || menuTransitioning) return;
const scrollY = window.scrollY;
moveCharacters(scrollY);
scaleCharacters(scrollY);
@ -29,7 +34,8 @@ document.addEventListener("DOMContentLoaded", () => {
function scaleCharacters(scrollY) {
const charOffset = Math.max(0, charMax - (scrollY / 16) * CHAR_SPEED);
const charWidth =
CHAR_WIDTH_MIN + (charOffset / charMax) * (CHAR_WIDTH_MAX - CHAR_WIDTH_MIN);
CHAR_WIDTH_MIN +
(charOffset / charMax) * (CHAR_WIDTH_MAX - CHAR_WIDTH_MIN);
svg.setAttribute("width", charWidth + "px");
svg.setAttribute("height", charWidth + "px");
}
@ -40,4 +46,51 @@ document.addEventListener("DOMContentLoaded", () => {
}
window.addEventListener("scroll", onScroll);
{
const nav = {
toggleBtn: document.querySelector(".toggle-nav"),
strip: document.querySelector(".strip"),
};
function openMenu() {
menuOpen = true;
header.classList.add("menu-transitioning", "big");
nav.strip.classList.add("open");
nav.toggleBtn.textContent = "fermer";
document.body.style.overflow = "hidden";
}
function closeMenu() {
menuOpen = false;
menuTransitioning = true;
header.classList.remove("big");
nav.strip.classList.remove("open");
nav.toggleBtn.textContent = "menu";
document.body.style.overflow = "";
setTimeout(() => {
header.classList.remove("menu-transitioning");
menuTransitioning = false;
}, 500);
}
nav.toggleBtn.addEventListener("click", () => {
nav.strip.classList.contains("open") ? closeMenu() : openMenu();
});
document.addEventListener("keydown", (e) => {
if (e.key === "Escape" && nav.strip.classList.contains("open"))
closeMenu();
});
document.addEventListener("click", (e) => {
if (
nav.strip.classList.contains("open") &&
!nav.strip.contains(e.target) &&
e.target !== nav.toggleBtn
) {
closeMenu();
}
});
}
});

View file

@ -6,7 +6,7 @@
/
<button>EN</button>
</div>
<!-- <button>menu</button> -->
<button class="toggle-nav">menu</button>
</div>
<h1 class="logo" style="--logo-offset: 0px">
Lesort<br>
@ -17,11 +17,12 @@
</div>
<div class="strip">
<h1><?= $page->title() ?></h1>
<nav>
<ul>
<li><a href="">La Compagnie</a></li>
<li><a href="">Les Spectacles</a></li>
<li><a href="">Agenda</a></li>
<li><a href="">Contact</a></li>
</ul>
</nav>
</div>