From c2f931f06aed3be5f77640355ff69c47d75dd86a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?benjamin=20melan=C3=A7on?= Date: Tue, 15 Jul 2025 08:39:56 -0400 Subject: [PATCH 1/2] Make the burger menu look nice before realizing details/summary cannot be nicely responsive One unmentioned con: The menu has to be repeated in HTML for this to switch responsively from spelled-out menu to hamburger, with the widescreen version outside the details. (Or JavaScript is needed to set the initial open/close state based on viewport size, and that seems to defeat the purpose.) Left as comment at https://lucas-levin.com/code/blog/burger-navigation-menu-with-no-javascript-and-no-checkbox-hack --- web/themes/custom/geofresco/src/global/_layout.scss | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/web/themes/custom/geofresco/src/global/_layout.scss b/web/themes/custom/geofresco/src/global/_layout.scss index f46187d..f90730e 100644 --- a/web/themes/custom/geofresco/src/global/_layout.scss +++ b/web/themes/custom/geofresco/src/global/_layout.scss @@ -65,12 +65,14 @@ // Main navigation, goes to code in page.html.twig details .burger-icon { - transition: transform 0.1s; + cursor: pointer; display: block; + margin-left: auto; + margin-right: 0; + padding: 1.25rem 2.5rem 1rem 1.5rem; width: 1.5rem; height: 1.5rem; - padding: .25rem; - cursor: pointer; + transition: transform 0.1s; } details[open] .burger-icon { From d56ee8dceed3dd845788f8856def40e584713a0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?benjamin=20melan=C3=A7on?= Date: Tue, 15 Jul 2025 12:51:30 -0400 Subject: [PATCH 2/2] Proof of concept for a more appropriate accessible 'hamburger' menu From https://unused-css.com/blog/css-only-hamburger-menu/ Ref #114 #126 --- .../custom/geofresco/src/global/_layout.scss | 116 ++++++++++++++++-- .../src/templates/layout/page.html.twig | 18 ++- 2 files changed, 112 insertions(+), 22 deletions(-) diff --git a/web/themes/custom/geofresco/src/global/_layout.scss b/web/themes/custom/geofresco/src/global/_layout.scss index f90730e..270339b 100644 --- a/web/themes/custom/geofresco/src/global/_layout.scss +++ b/web/themes/custom/geofresco/src/global/_layout.scss @@ -64,21 +64,113 @@ } // Main navigation, goes to code in page.html.twig -details .burger-icon { - cursor: pointer; +.hamburger-container { + width: max-content; + position: absolute; + top: 10px; + right: 10px; + color: white; + transition: transform 0.5s ease; +} + +/* We don't need the checkbox to be visible, but we can't set it to display: none because this will break keyboard navigation. Instead set the opacity to 0 and the position to absolute so it doesn't push the rest of the content down */ +.hamburger-container .checkbox { + opacity: 0; + position: absolute; +} + +/* Show an outline when the hamburger is selected using the keyboard. Older browsers don't support :focus-visible, so we will just use :focus here. */ +.hamburger-container .checkbox:focus ~ .hamburger { + /* Not all browsers support outline: auto, so set a sensible fallback outline. */ + outline: 2px solid white; + outline: auto; + outline-offset: 4px; +} + +/* For newer browsers that do support :focus-visible, hide the outline when the checkbox isn't selected with the keyboard. */ +@supports selector(:focus-visible) { + .hamburger-container .checkbox:not(:focus-visible) ~ .hamburger { + outline: none; + } +} + +/* Hide any focusable elements in the drawer by default to aid keyboard navigation. We use visibility so it makes the elements unfocusable, but doesn't affect the layout. We can also add a "transition" to visibility, which will make it show instantly when we open the drawer, but take half a second to hide it when we close the drawer. */ +.hamburger-container .drawer a { + visibility: hidden; + transition: visibility 0.5s linear; +} + +/* Make the focusable elements in the drawer visible when it is open. */ +.hamburger-container .checkbox:checked ~ .drawer a { + visibility: visible; +} + +.hamburger-container .checkbox:checked ~ .drawer { + transform: translateX(0%); +} + +.hamburger-container .checkbox:checked ~ .hamburger .slice:nth-child(1) { + transform: translateY(12px) rotate(45deg); +} + +.hamburger-container .checkbox:checked ~ .hamburger .slice:nth-child(2) { + opacity: 0; +} + +.hamburger-container .checkbox:checked ~ .hamburger .slice:nth-child(3) { + transform: translateY(-12px) rotate(-45deg); +} + +.hamburger { + width: 32px; + height: 32px; + position: relative; display: block; - margin-left: auto; - margin-right: 0; - padding: 1.25rem 2.5rem 1rem 1.5rem; - width: 1.5rem; - height: 1.5rem; - transition: transform 0.1s; + transition: transform 0.5s ease; + z-index: 1; + cursor: pointer; + padding-top: 5px; } -details[open] .burger-icon { - transform: rotate(90deg); +.hamburger .slice { + display: block; + width: 100%; + height: 2px; + background-color: white; + transition: all 0.5s ease; } -summary { - list-style-type: none; +.hamburger .slice:not(:first-child) { + margin-top: 10px; +} + +.drawer { + position: fixed; + left: 0; + top: 0; + height: 100%; + width: max-content; + max-width: 100%; + padding: 22px; + background: black; + transform: translateX(-100%); + transition: transform 0.5s ease; +} + +.drawer .nav-list { + padding: 0; + list-style: none; + margin-top: 30px; + margin-left: 20px; +} + +.drawer .nav-list .nav-list-item { + padding-bottom: 10px; +} + +/* Make the drawer full-width on mobile */ +@media screen and (max-width: 768px) { + .drawer { + width: 100%; + } } \ No newline at end of file diff --git a/web/themes/custom/geofresco/src/templates/layout/page.html.twig b/web/themes/custom/geofresco/src/templates/layout/page.html.twig index 69b2b70..8633cec 100644 --- a/web/themes/custom/geofresco/src/templates/layout/page.html.twig +++ b/web/themes/custom/geofresco/src/templates/layout/page.html.twig @@ -23,15 +23,14 @@ {% block navbar_branding %} {{ page.navbar_branding }} {% endblock navbar_branding %} - {% if is_front %}