Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Very Simple Responsive Menu

A small, accessible and dependency-free navigation menu written in plain JavaScript and CSS.

  • Responsive desktop and mobile layouts
  • Nested submenus
  • Mouse, touch and keyboard support
  • Automatic edge collision handling
  • Configurable with CSS custom properties
  • No framework and no build step

Demo

Open demo/index.html in a browser. The demo works directly from the filesystem.

Quick start

Copy the two files in src/ into your project, then include them:

<link rel="stylesheet" href="very-simple-responsive-menu.css">
<script src="very-simple-responsive-menu.js" defer></script>

Add the following structure. IDs and labels should be unique and meaningful in your page.

<nav class="vsrm" data-vsrm aria-label="Main navigation">
  <div class="vsrm__bar">
    <div class="vsrm__container">
      <a class="vsrm__brand" href="/">My website</a>

      <button class="vsrm__mobile-toggle" type="button"
        aria-expanded="false" aria-controls="main-menu-panel"
        aria-label="Open main menu">
        <span></span><span></span><span></span>
      </button>

      <div class="vsrm__panel" id="main-menu-panel">
        <ul class="vsrm__list">
          <li class="vsrm__item"><a class="vsrm__link" href="/">Home</a></li>

          <li class="vsrm__item vsrm__item--parent"
            data-vsrm-parent data-level="0">
            <div class="vsrm__entry">
              <a class="vsrm__link" href="/products">Products</a>
              <button class="vsrm__submenu-toggle" type="button"
                aria-expanded="false" aria-controls="products-submenu"
                data-open-label="Open Products submenu"
                data-close-label="Close Products submenu">
                <span aria-hidden="true"></span>
              </button>
            </div>
            <ul class="vsrm__submenu" id="products-submenu" hidden>
              <li class="vsrm__item">
                <a class="vsrm__link" href="/products/one">Product one</a>
              </li>
            </ul>
          </li>
        </ul>
      </div>
    </div>
  </div>
</nav>

Menus carrying data-vsrm are initialized automatically, whether the script is loaded before or after the markup.

Options

Add vsrm--sticky to the <nav> element to keep the navigation at the top of the viewport.

The mobile button labels can be translated with data attributes:

<nav class="vsrm" data-vsrm
  data-open-label="Ouvrir le menu principal"
  data-close-label="Fermer le menu principal">

Each submenu button accepts data-open-label and data-close-label in the same way.

Customize the appearance by overriding CSS properties:

.vsrm {
  --vsrm-height: 64px;
  --vsrm-max-width: 1440px;
  --vsrm-background: #111827;
  --vsrm-color: #f9fafb;
  --vsrm-hover: #1f2937;
  --vsrm-accent: #f59e0b;
  --vsrm-border: #374151;
}

The responsive threshold is 992px. Because CSS media-query breakpoints cannot use custom properties, change both media queries in the CSS and the matchMedia value in the JavaScript if you need a different threshold.

JavaScript API

Automatic initialization stores the instance on the menu element:

const menu = document.querySelector('[data-vsrm]').vsrm;
menu.closeAll();
menu.reset();
menu.destroy();

You can also initialize inserted markup manually:

const menu = new VerySimpleResponsiveMenu(document.querySelector('#my-menu'));
VerySimpleResponsiveMenu.initAll(document.querySelector('#fragment'));

Keyboard behavior

  • Enter or Space activates submenu buttons.
  • Arrow down opens a submenu and focuses its first item.
  • Arrow right opens a submenu on desktop.
  • Arrow left closes the current submenu on desktop.
  • Escape closes the current submenu or the whole mobile menu.

Browser support

The component targets current evergreen browsers. It uses Element.closest, :scope, optional chaining, matchMedia and CSS color-mix() for the focus-ring enhancement.

License

MIT

AI-assisted development

Very Simple Responsive Menu is a project initiated, directed and validated by François Milhiet.

Its design and development were carried out in collaboration with OpenAI's ChatGPT, through a series of prompts, analyses, iterations and validations.

Functional direction, architectural decisions, trade-offs, real-world testing and final validation remain under the responsibility of the project's initiator. ChatGPT acts as an assistant for design, programming, documentation and review.

This AI-assisted development approach is an integral part of Very Simple Responsive Menu's history and is disclosed here in the interest of transparency.

Une construction assistée par intelligence artificielle

Very Simple Responsive Menu est un projet initié, dirigé et validé par François Milhiet.

Sa conception et son développement ont été réalisés en collaboration avec ChatGPT d’OpenAI, au fil d’une série de prompts, d’analyses, d’itérations et de validations.

Les orientations fonctionnelles, les choix d’architecture, les arbitrages, les essais en conditions réelles et la validation finale restent conduits par l’initiateur du projet. ChatGPT intervient comme assistant de conception, de programmation, de documentation et de contrôle.

Cette méthode de développement assisté par intelligence artificielle fait partie intégrante de l’histoire de Very Simple Responsive Menu et est indiquée ici dans un souci de transparence.