Skip to content

About

Hamburger menu / mobile nav as a web component

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

hamburger two

tests types module install size gzip size semantic versioning Common Changelog license

Another hamburger menu, as a web component. This extends @susbtrate-system/web-component.

See a live demo

Note

In the example page, you must be in mobile view to see the component.

See @substrate-system/hamburger for something similar but with different style.

Contents

Install

npm i -S @substrate-system/hamburger-two

Use

Just import; the library code calls window.customElements.define. hamburger-two.

Note

This module only has client-side code. There is no provision for server-side rendering, because this element is only useful on the client-side.

HTML

Application code should listen for hamburger events, and show/hide the menu. Pass the menu's id as the controls attribute.

    <hamburger-two controls="mobile-nav"></hamburger-two>

    <div id="mobile-nav" class="mobile-nav-menu">
        <ul>
          <li><a href="/hello">hello</a></li>
          <li><a href="/abc">abc</a></li>
          <li><a href="/def">def</a></li>
        </ul>
    </div>

Javascript

import { HamburgerTwo } from '@substrate-system/hamburger-two'
import '@substrate-system/hamburger-two/css'

// tag name is exposed as .TAG
const el = document.querySelector(HamburgerTwo.TAG)

// programmatically open the menu
el?.isOpen = true

// listen for events, then change the class on our navigation element
el?.addEventListener(HamburgerTwo.event('open'), () => {
    debug('menu is open...')
    document.querySelector('.mobile-nav-menu')!.classList.add('open')
})

// or use .on, because this extends @substrate-system/web-component
el.on('open', ev => {
    // ...
})

el?.addEventListener(HamburgerTwo.event('close'), () => {
    debug('menu is closed...')
    document.querySelector('.mobile-nav-menu')!.classList.remove('open')
})

CSS

Only display on small screens. This needs to be part of the application code; it is not in this library.

hamburger-two {
    display: none;
}

/* show/hide our menu */
.mobile-nav-menu {
    display: none;

    &.open {
        display: flex;
    }
}

@media (width < 680px) {
    hamburger-two {
        display: block;
    }
}

Attributes

  • controls -- the id of the menu element. It becomes aria-controls on the button, and the element moves focus into that menu on open.
  • label -- the accessible name of the button. Default is "Menu".
  • open -- present when the menu is open. Add or remove it to open or close the menu; this emits the matching event.

Accessibility

The element renders a single <button> with aria-label, aria-expanded, and aria-controls.

  • Clicking the button emits open first, so the app can show the menu, then moves focus to the first focusable element in the controls menu. Opening by setting isOpen or the open attribute does not move focus.
  • Pressing Escape while open closes the menu and returns focus to the button.
  • Moving focus from the menu to an element outside of the menu and the hamburger closes the menu.

events

Typically you would use the tag in the DOM, then listen for events and show/hide a menu element in response.

open

HamburgerTwo.event('open')
// => 'hamburger-two:open'
document.querySelector('hamburger-two')
    .addEventListener(HamburgerTwo.event('open'), () => {
        document
            .querySelector('.mobile-nav-menu')
            .classList
            .add('open')
    })

close

HamburgerTwo.event('close')
// => 'hamburger-two:close'
document.querySelector('hamburger-two')
    .addEventListener(HamburgerTwo.event('close'), () => {
        document
            .querySelector('.mobile-nav-menu')
            .classList
            .remove('open')
    })

Example

See ./example.

// after registering the component
document.body.innerHTML += `
    <hamburger-two></hamburger-two>
`

const el = document.querySelector('hamburger-two')

el?.addEventListener(HamburgerTwo.event('open'), () => {
    debug('menu is open...')
    document.querySelector('.mobile-nav-menu')!.classList.add('open')
})

el?.addEventListener(HamburgerTwo.event('close'), () => {
    debug('menu is closed...')
    document.querySelector('.mobile-nav-menu')!.classList.remove('open')
})

Modules

This exposes ESM and common JS via package.json exports field.

ESM

import { HamburgerTwo } from '@substrate-system/hamburger-two'

Common JS

require('@substrate-system/hamburger-two')

pre-built

This package exposes minified JS and CSS files too. Copy them to a location that is accessible to your web server, then link to them in HTML.

copy

cp ./node_modules/@substrate-system/hamburger-two/dist/index.min.js ./public/hamburger-two.min.js
cp ./node_modules/@substrate-system/hamburger-two/dist/style.min.css ./public/hamburger-two.css

HTML

<head>
    <link rel="stylesheet" href="./hamburger-two.css">
</head>
<body>
    <!-- ... -->
    <script type="module" src="./hamburger-two.min.js"></script>
</body>

CSS

Import CSS

import '@substrate-system/hamburger-two/css'

Or minified:

import '@substrate-system/hamburger-two/css/min'

Customize CSS via variables

The element uses the shared --substrate-* variables, each with a fallback:

  • --substrate-text -- the color of the lines. Default black when closed and white when open.
  • --substrate-focus -- the focus ring color. Default Highlight.
  • --substrate-focus-width -- the focus ring width. Default 2px.
  • --substrate-radius -- the corner radius of the button, which shapes the focus ring. Default 0.

Two more variables override --substrate-text for this element only. --hamburger-color sets the color of the lines when closed, and --burger-open-color sets the color of the close "x" when open.

:root {
    --substrate-text: #222;
    --substrate-focus: #0055d4;
    --burger-open-color: white;
}

The line animation is off when the user prefers reduced motion.

test

Run some tests locally with tape-run.

npm test

Develop

Start a localhost server of the example page.

npm start

See also

About

Hamburger menu / mobile nav as a web component

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Contributors

Languages