Skip to content

Instantly share code, notes, and snippets.

@ryangittings
Last active October 16, 2025 12:32
Show Gist options
  • Select an option

  • Save ryangittings/a1d4a8df1e795151b78a17edb64ade74 to your computer and use it in GitHub Desktop.

Select an option

Save ryangittings/a1d4a8df1e795151b78a17edb64ade74 to your computer and use it in GitHub Desktop.
menu-toggle
menu-toggle button {
background: none;
padding: 0;
border: none;
cursor: pointer;
color: currentColor;
}
menu-toggle button svg {
width: 2em;
}
menu-toggle button svg path {
transform-box: fill-box;
transform-origin: center;
transition: 0.2s var(--ease-default);
transition-property: transform, opacity;
}
menu-toggle button[aria-expanded="true"] svg path:first-child {
transform: translateY(5px) rotate(45deg);
}
menu-toggle button[aria-expanded="true"] svg path:nth-child(2) {
opacity: 0;
}
menu-toggle button[aria-expanded="true"] svg path:last-child {
transform: translateY(-5px) rotate(-45deg);
}
class MenuToggle extends HTMLElement {
constructor() {
super();
this.toggleMenu = this.toggleMenu.bind(this);
this.button = this.querySelector("button");
}
connectedCallback() {
this.button.addEventListener("click", this.toggleMenu);
}
toggleMenu() {
const open = this.button.getAttribute("aria-expanded") == "true";
if (open) {
this.button.setAttribute("aria-expanded", false);
this.removeAttribute("open");
} else {
this.button.setAttribute("aria-expanded", true);
this.setAttribute("open", true);
}
}
}
window.customElements.define("menu-toggle", MenuToggle);
<menu-toggle class="flex flex-wrap items-center justify-between gap-s">
<button type="button" class="lg:hidden" aria-label="Toggle main menu" aria-controls="menu">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" aria-hidden="true">
<!-- Top line -->
<path d="M3.75 6.75h16.5" stroke-linecap="round" stroke-linejoin="round"></path>
<!-- Middle line -->
<path d="M3.75 12h16.5" stroke-linecap="round" stroke-linejoin="round"></path>
<!-- Bottom line -->
<path d="M3.75 17.25h16.5" stroke-linecap="round" stroke-linejoin="round"></path>
</svg>
</button>
<nav id="menu" class="hidden basis-full lg:block lg:basis-auto [menu-toggle:has([aria-expanded=true])_&]:block" aria-label="Main menu">
<ul role="list">
{% for item in collections.all | eleventyNavigation %}
<li>
<a href="{{ item.url }}" class="block no-underline">{{ item.title }}</a>
</li>
{% endfor %}
</ul>
</nav>
</menu-toggle>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment