Launchy! πŸš€

Agenda βœ…

  1. Some history
  2. What makes a modal window "accessible?"
  3. Why accessibility?
  4. What is Launchy! πŸš€ ?
  5. Code highlights
  6. Demo!

Some history πŸ•ΉπŸ‘Ύ

The blog post that started it all…

Screenshot of the NCZOnline blog post, Making an accessible dialog box.

What worked πŸ‘

  • Captured keyboard focus
  • Wrapped on Tab
  • Returned focus

What didn't πŸ‘Ž

  • Wrapping on Shift+Tab

What makes a modal window "accessible?" πŸ€”

The ARIA guidelines site is your best friend

Screenshot of the WAI-ARIA Authoring Practices 1.1 website.

Keyboard/focus interaction

πŸš€ On launch
Move focus inside the dialog
⌨️ Esc
Close dialog and move focus to launcher

Keyboard/focus interaction (cont…)

⌨️ Tab
Move forward, wrapping on last focusable element
⌨️ Shift+Tab
Move backward, wrapping on first focusable element

Roles, states, properties

(Semantic meaning/context)
πŸ“¦ role="dialog"
Applied to container; helps to give context
πŸ“¦ aria-modal="true" (⭐️ ARIA 1.1)
Applied to container; "modal is open"

Roles, states, properties (cont…)

πŸ“¦ aria-label or aria-labelledby
Applied to container; provides a description
πŸš€ aria-haspopup="dialog" (⭐️ ARIA 1.1)
Applied to launcher; provides context for click event

Why accessibility? πŸ€”

To not get sued?

Yeah, pretty good reason.

It's the right thing to do?

Absolutely.

It's everyone's responsibility to ensure what is shipped out into the world is usable by as many people as possible!

So, what is Launchy! πŸš€ ? πŸ€”

Highlights 🚨

  • Single, minified JavaScript file @ 3kb gzip
  • Open source on GitHub
  • Available via npm

Features ✨

  • Fully accessible! (obvs πŸ™Š)
  • Easy to use and implement!
  • No dependent HTML structure!
  • Everything is dynamically created for you!
  • Add your own custom close controls!
  • Plenty of CSS classes to add your own styles!

Project setup πŸ“¦

  • ES6, Babel, webpack
  • Sass, Autoprefixer
  • Browsersync
  • inert polyfill
  • Mocha, Chai, headless Chrome
  • npm scripts

code highlights πŸ–₯

Check for the Shift key

							
								document.addEventListener('keydown', checkShift);

								function checkShift(e) {
								    if (modalIsVisible) {
								        shiftKeyIsPressed = e.shiftKey;
								    }
								};
							
						

Trapping keyboard focus

							
								document.addEventListener('focus', trapFocus);

								function trapFocus(e) {
								    if (modalIsVisible && !modalWindow.contains(e.target)) {
								      shiftKeyIsPressed ? lastFocusable.focus() : firstFocusable.focus();
								    }
								};
							
						

Custom close controls

							
								const closeControls = modalContent.querySelectorAll('[data-launchy-close]');

								for (const closeControl of closeControls) {
								    closeControl.addEventListener('click', hideModal);
								}
							
						

Demo! 🐢

Thanks! πŸ™‚