{"id":31077679,"url":"https://github.com/chrisnajman/details-dropdown-menu","last_synced_at":"2025-10-16T10:12:52.296Z","repository":{"id":314475974,"uuid":"1055385660","full_name":"chrisnajman/details-dropdown-menu","owner":"chrisnajman","description":"Dropdown menu using the HTML details element and anchor positioning.","archived":false,"fork":false,"pushed_at":"2025-09-12T16:24:30.000Z","size":60,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-09-12T18:48:25.664Z","etag":null,"topics":["accessibility","anchor-positioning","aria-attributes","chatgpt-free","css-flexbox","css-grid","css-imports","css-nesting","cssnano","details","dropdown-menu","es6-modules","esbuild","html-css-javascript","html-minifier-terser","loading-spinner","postcss","theme-switcher"],"latest_commit_sha":null,"homepage":"https://chrisnajman.github.io/details-dropdown-menu/","language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/chrisnajman.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-09-12T07:33:34.000Z","updated_at":"2025-09-12T16:24:34.000Z","dependencies_parsed_at":"2025-09-12T18:58:38.431Z","dependency_job_id":null,"html_url":"https://github.com/chrisnajman/details-dropdown-menu","commit_stats":null,"previous_names":["chrisnajman/details-dropdown-menu"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/chrisnajman/details-dropdown-menu","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chrisnajman%2Fdetails-dropdown-menu","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chrisnajman%2Fdetails-dropdown-menu/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chrisnajman%2Fdetails-dropdown-menu/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chrisnajman%2Fdetails-dropdown-menu/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/chrisnajman","download_url":"https://codeload.github.com/chrisnajman/details-dropdown-menu/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chrisnajman%2Fdetails-dropdown-menu/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":275384104,"owners_count":25454910,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-16T02:00:10.229Z","response_time":65,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["accessibility","anchor-positioning","aria-attributes","chatgpt-free","css-flexbox","css-grid","css-imports","css-nesting","cssnano","details","dropdown-menu","es6-modules","esbuild","html-css-javascript","html-minifier-terser","loading-spinner","postcss","theme-switcher"],"created_at":"2025-09-16T07:56:43.131Z","updated_at":"2025-10-16T10:12:52.277Z","avatar_url":"https://github.com/chrisnajman.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"# `\u003cdetails\u003e` Dropdown Menu\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003cstrong id=\"menu\"\u003eMenu\u003c/strong\u003e\u003c/summary\u003e\n\n- [Description](#description)\n- [Features](#features)\n- [JavaScript](#javascript)\n- [CSS](#css)\n- [Accessibility](#accessibility)\n- [CANIUSE Anchor Positioning?](#caniuse-anchor-positioning)\n- [Code Source](#code-source)\n- [Theme Toggling](#theme-toggling)\n- [Testing and Compatibility](#testing-and-compatibility)\n- [How to Run](#how-to-run)\n- [Build \u0026 Deployment Setup for `/docs` Folder](#build--deployment-setup-for-docs-folder)\n\n\u003c/details\u003e\n\n## Description\n\nA lightweight, accessible navigation and content system built using the native HTML `\u003cdetails\u003e` and `\u003csummary\u003e` elements.  \nEnhances the default behavior with JavaScript for better usability, keyboard support, and ARIA state management — without relying on external libraries.\n\n[Back to menu](#menu)\n\n---\n\n## Features\n\n- Native `\u003cdetails\u003e` used for dropdown menus in navigation and content.\n- Automatic closing of `\u003cdetails\u003e` when clicking outside a navigation area.\n- Keyboard support: pressing `Escape` closes the currently focused `\u003cdetails\u003e`.\n- ARIA attributes (`aria-expanded`) synchronized with open/close state.\n- `\u003cdetails\u003e` elements can be grouped with a shared `data-group` attribute for mutually exclusive behavior (opening one closes the others), supported in all major browsers.\n- Responsive hamburger menu with accessible ARIA controls.\n- Modern **CSS Anchor Positioning** used for aligning dropdown menus.\n\n[View on GitHub Pages](https://chrisnajman.github.io/details-dropdown-menu)\n\n[Back to menu](#menu)\n\n---\n\n## JavaScript\n\nBuilt with **vanilla ES6 JavaScript**, focusing on modern syntax and browser APIs.\n\nThe JavaScript has been split into separate modules, improving code modularity:\n\n- `details.js`: Handles `\u003cdetails\u003e` accessibility and behavior.\n  - Syncs `aria-expanded` between `\u003csummary\u003e` and `\u003cdetails\u003e`.\n  - Closes dropdowns when clicking outside navigation.\n  - Supports closing via the `Escape` key and restores focus.\n  - Implements grouped accordion behavior using the `data-group` attribute: when one `\u003cdetails\u003e` in a group opens, any others in the same group automatically close.\n- `hamburger-button.js`: Toggles the mobile navigation menu.\n  - Updates `aria-expanded` on the button.\n  - Switches between hidden/visible menu states.\n  - Updates the visually hidden text for screen readers.\n\n### Other\n\n- `loader.js`: See [Loader Git repository](https://github.com/chrisnajman/loader)\n- `theme.js`: Handles theme toggling (light/dark mode) and local storage management.\n\n[Back to menu](#menu)\n\n---\n\n## CSS\n\n- **Anchor Positioning** (`position-anchor`) is used to align dropdown menus relative to their `\u003csummary\u003e`.\n  - In browsers without Anchor Positioning support (e.g., Firefox), the layout gracefully falls back to a standard flow layout, preserving an unbroken user experience.\n- Uses **media query range syntax** for responsive breakpoints.\n- Mobile-first design, with progressive enhancements for larger viewports.\n- Dropdown menus adapt to available space without JavaScript intervention.\n\n[Back to menu](#menu)\n\n---\n\n## Accessibility\n\n- ARIA attributes (`aria-expanded`) dynamically updated on all `\u003csummary\u003e` elements.\n- Escape key support: closes the open `\u003cdetails\u003e` and returns focus to its `\u003csummary\u003e`.\n- Clicking outside a `\u003cnav\u003e` closes only its dropdown menus.\n- Mobile hamburger menu includes `aria-controls` and `aria-expanded` for screen reader support.\n- Semantic HTML structure (`\u003cheader\u003e`, `\u003cnav\u003e`, `\u003cmain\u003e`, `\u003cdetails\u003e`, `\u003csummary\u003e`) aids navigation for assistive technologies.\n\n### No JS\n\nIf JavaScript is disabled, the loader animation, theme-toggler and mobile menu cease to function. However, all content remains accessible.\n\n[Back to menu](#menu)\n\n---\n\n## CANIUSE Anchor Positioning?\n\nAs of September 2025, **Caniuse** reports that the following browsers/platforms support anchor positioning:\n\n- Chrome v.140\n- Edge v.140\n- Opera v.122\n- Chrome for Android v.139\n- Safari on IOS v.26\n- Android Browser v.139\n\n**Caniuse** reports that \"All major browser engines are working on implementing this spec\".\n\n[Caniuse: anchor positioning](https://caniuse.com/css-anchor-positioning)\n\n**Note**: unsupported browsers/platforms will display the default `details` behaviour.\n\n[Back to menu](#menu)\n\n---\n\n## Code Source\n\nThe anchor positioning code for the main navigation comes from a **Codepen** by [Ryan Trimble](https://codepen.io/mrtrimble). My only changes were:\n\n- Changing IDs to classes\n- Adding `position-try-fallbacks: flip-block, flip-inline` to the target's `::details-content`\n- Making both targets `position-area: block-end center`\n\n[View CodePen](https://codepen.io/mrtrimble/pen/ZYzzqOJ/676e5968b2726fb2c3383819ffb8d15b)\n\n[Back to menu](#menu)\n\n---\n\n## Theme Toggling\n\nThe application includes a dark mode and light mode toggle:\n\n- The current theme state is stored in **local storage** and applied automatically on page reload.\n- Accessible buttons with appropriate ARIA attributes are used to improve usability.\n\n\u003e [!IMPORTANT]\n\u003e Remember to change `const LOCAL_STORAGE_PREFIX` in `js-modules/theme.js` to a unique identifier.\n\n[Back to menu](#menu)\n\n---\n\n## Testing and Compatibility\n\nThe application has been tested on the following platforms and browsers:\n\n- **Operating System**: Windows 10/11\n- **Browsers**:\n  - Google Chrome (full support, including Anchor Positioning)\n  - Mozilla Firefox (no Anchor Positioning support yet, but layout gracefully falls back to default `\u003cdetails\u003e` behavior)\n  - Microsoft Edge (full support, including Anchor Positioning)\n\n### Device View Testing\n\nThe layout and functionality have been verified in both browser and device simulation views to ensure responsiveness and usability.\n\n[Back to menu](#menu)\n\n---\n\n## How to Run\n\n1. Clone or download the repository to your local machine.\n2. Open the project folder and start a simple HTTP server (e.g., using `Live Server` in VS Code or Python's `http.server` module).\n3. Open the project in a modern browser (e.g., Chrome, Firefox, or Edge).\n\n[Back to menu](#menu)\n\n---\n\n## Build \u0026 Deployment Setup for `/docs` Folder\n\nIf you want to deploy a minified version of this project to **GitHub Pages**, read on.\n\n### 1. Install Required Packages\n\nRun this once in your project root to install dev dependencies:\n\n```bash\nnpm install\n```\n\n### 2. Run the full build process\n\n\u003e [!IMPORTANT]\n\u003e Any assets not described in `package.json` must be added. In the current project we don't have an `img` folder. If you create one and add images to it, you have to add this to `copy:assets`, e.g.\n\n#### Current `package.json`\n\n```\n\"copy:assets\": \"shx cp -r  site.webmanifest favicon.ico favicon-16x16.png favicon-32x32.png apple-touch-icon.png android-chrome-192x192.png android-chrome-512x512.png docs/\",\n```\n\n#### Updated `package.json` with \"img\"\n\n```\n\"copy:assets\": \"shx cp -r  img site.webmanifest favicon.ico favicon-16x16.png favicon-32x32.png apple-touch-icon.png android-chrome-192x192.png android-chrome-512x512.png docs/\",\n```\n\netc, etc.\n\nThen in the terminal, run:\n\n```bash\nnpm run build\n```\n\n### 3. Deploy to GitHub Pages\n\nOnce you've created a repository and pushed the files,\n\n- go to `https://github.com/[your-name]/[your-project-name]/settings/pages`.\n- Under \"Build and deployment \u003e Branch\" make sure you set the branch to `main` and folder to `/docs`.\n- Click \"Save\".\n\n\u003e [!NOTE]\n\u003e For a detailed description of the build process, configuration files and npm packages see my [GitHub Pages Optimised Build](https://github.com/chrisnajman/github-pages-optimised-build).\n\n[Back to menu](#menu)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchrisnajman%2Fdetails-dropdown-menu","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchrisnajman%2Fdetails-dropdown-menu","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchrisnajman%2Fdetails-dropdown-menu/lists"}