van11y-accessible-modal-window-aria
Version:
ES2015 accessible modal window system, using ARIA (compatible IE9+ when transpiled)
312 lines (263 loc) • 8.32 kB
Markdown
# Van11y accessible modal window system, using ARIA
<img src="https://van11y.net/layout/images/logo-van11y.svg" alt="Van11y" width="300" />
This script will provide you an accessible modal window using ARIA.
The demo is here: https://van11y.net/downloads/modal/demo/index.html
Website is here: https://van11y.net/accessible-modal/
La page existe aussi en français : https://van11y.net/fr/modale-accessible/
## How it works
Basically, when you activate one:
- the script wraps all the page into a <code>div id="js-modal-page"</code>;
- adds the <code>noscroll</code> class on the <code>body</code> element (to remove scroll with CSS if needed);
- then inserts a <code>dialog</code> element at the end of your page;
- puts the focus into it and __traps focus in the modal window__;
- When you exit it, the focus is given back to the element that opened it.
You can close it using <kbd>Esc</kbd>, or by using <kbd>Enter</kbd> or <kbd>Space</kbd> if you’re on the close button.
Mouse users can click outside the modal window to close it (this option can be disabled if needed).
If you never activate a modal window, it won’t be anywhere in the code.
## How to use it
__Download the script__
You may use npm command: <code>npm i van11y-accessible-modal-window-aria</code>.
You may also use bower: <code>bower install van11y-accessible-modal-window-aria</code>.
__Option and attributes__
First, put <code>class="js-modal"</code> on a button or a link to activate the script. Then, here are all attributes:
- Attribute <code>data-modal-prefix-class</code>: will namespace all the modal CSS element classnames.
- Attribute <code>data-modal-text</code>: the text of your modal window (will be put into a <code>p</code> tag).
- Attribute <code>data-modal-content-id</code>: the <code>id</code> of (hidden) content in your page that will be put into your modal window (if <code>data-modal-text</code> is not present).
- Attribute <code>data-modal-title</code>: the main title of the modal window.
- Attribute <code>data-modal-close-text</code>: the text of the close button in your modal window.
- Attribute <code>data-modal-close-title</code>: the title attribute of the close button in your modal window.
- Attribute <code>data-modal-background-click="disabled"</code>: disable the possibility to click outside the modal window to close it.
- Attribute <code>data-modal-close-img</code>: a path to a valid image for the close button.
- Attribute <code>data-modal-focus-toid</code>: the <code>id</code> of the element in the modal you want to give the focus to, when loading the modal (closing button if not specified).
- Attribute <code>data-modal-describedby-id</code>: adds `aria-describedby=<the value of this attribute>` to the `dialog` tag.
If you need to close it, add `class="js-modal-close"` on an element in the modal content, it will trigger a click on close button.
Remember there are some demos, it will be easier to understand: <a href="https://van11y.net/downloads/modal/demo/index.html">Demo of accessible modal window</a>
The script is launched when the page is loaded. If you need to execute it on AJAX-inserted content, you may use for example on `<div id="newContent">your modal launcher source</div>`:
```van11yAccessibleModalWindowAria(document.getElementById('newContent')[, addListeners]);```
<code>addListeners</code> is a facultative boolean (by default set to <code>true</code>) to add modal listeners (should be set up only the first time in most of the cases).
## Minimal styling classes
Here is the minimal set of styles needed to make it work (without data-modal-prefix-class attribute):
```css
/* needed for old browsers */
dialog {
display: block;
border: 0;
}
/* removes scroll when modal is opened */
.no-scroll {
overflow: hidden;
}
/* overlay covers everything */
.modal-overlay {
position: fixed;
top: 0;
bottom: 0;
right: 0;
left: 0;
z-index: 666;
}
/* modal */
.modal {
position: fixed;
left: 25%;
right: auto;
top: 15%;
width: 50%;
background: #fff;
z-index: 667;
}
```
## Styling classes example
Here are the styles (unprefixed) used for the demo, I’ve used <code>data-modal-prefix-class="simple"</code> and <code>data-modal-prefix-class="simple-animated"</code> to namespace elements, so each one will start with <code>.simple-</code>/<code>.simple-animated-</code>:
```css
dialog {
display: block;
border: 0;
}
/* removes scroll when modal is opened */
.no-scroll {
overflow: hidden;
}
/* overlay covers everything */
.simple-modal-overlay,
.simple-animated-modal-overlay {
position: fixed;
top: 0;
bottom: 0;
right: 0;
left: 0;
background: #fff;
opacity: .8;
z-index: 666;
cursor: pointer;
}
.simple-modal-overlay[data-background-click="disabled"],
.simple-animated-modal-overlay[data-background-click="disabled"] {
cursor: auto;
}
.simple-animated-modal-overlay {
animation: fadewhite ease .5s 1 normal ;
}
@keyframes fadewhite {
0% {
opacity: 0;
}
100% {
opacity: .8;
}
}
/* modal */
.simple-modal,
.simple-animated-modal {
position: fixed;
left: 15%;
top: 5%;
width: 70%;
max-height: 98vh;
border: 2px solid #000;
background: #fff;
z-index: 667;
padding: 2em;
right: auto;
overflow: auto;
}
.simple-modal-close,
.simple-animated-modal-close {
float: right;
background: #128197;
border-radius: 1em;
color: #fff;
border: 0;
font: inherit;
padding: .25em .5em;
cursor: pointer;
}
.simple-modal-close:focus,
.simple-modal-close:hover,
.simple-modal-close:active {
outline: 1px dotted #fff;
}
.simple-modal-close:hover,
.simple-modal-close:active {
background: #4d287f;
}
.simple-animated-modal {
animation: apparition ease .5s 1 normal ;
}
@keyframes apparition {
0% {
opacity: 0;
max-height: 0;
width: 0;
left: 50%;
}
100% {
opacity: 1;
max-height: 100%;
width: 70%;
left: 15%;
}
}
/* it can be easily adapted in media-queries for tablets/mobile */
/* for this example: tablets */
@media (max-width: 55.625em) {
.simple-modal,
.simple-animated-modal {
left: 5%;
top: 5%;
height: 90%;
width: 90%;
}
}
/* for this example: mobile */
@media (max-width: 44.375em) {
.simple-modal,
.simple-animated-modal {
left: 1%;
top: 1%;
width: 98%;
height: 98%;
}
}
```
## Other style example
Here are the styles (unprefixed) used for the third example of the demo, I’ve used <code>data-modal-prefix-class="simple-left"</code> to namespace elements, so each one will start with <code>.simple-left-</code>:
```css
/* needed for old browsers */
dialog {
display: block;
border: 0;
}
/* removes scroll when modal is opened */
.no-scroll {
overflow: hidden;
}
/* another modal styling example */
/* tooltip modal for it’s easy button */
.simple-left-modal-overlay {
position: fixed;
top: 0;
bottom: 0;
right: 0;
left: 0;
background: #fff;
opacity: .8;
z-index: 666;
cursor: pointer;
}
.simple-left-modal-overlay[data-background-click="disabled"] {
cursor: auto;
}
.simple-left-modal-overlay {
position: fixed;
top: 0;
bottom: 0;
right: 0;
left: 0;
background: rgba(0, 0, 0, .8);
opacity: .8;
z-index: 666;
cursor: pointer;
}
.simple-left-modal {
left: auto;
right: 0;
top: 0;
bottom: 0;
height: 100%;
z-index: 667;
position: fixed;
width: 40em;
max-width: 100%;
padding: 0 1em 1em 1em;
font-size: 1em;
border: 0;
overflow: auto;
background-color: #aaa ; /* fallback CSS IE9 */
background-image:
-webkit-linear-gradient(
top,
#128197 3em,
#f7f7f7 3em
); background-image:
linear-gradient(
to bottom,
#128197 3em,
#f7f7f7 3em
);
background-attachment: local;
}
.simple-left-modal-close {
position: absolute;
top: .5em;
right: 0;
background: transparent;
color: #fff;
border: 0;
cursor: pointer;
}
.simple-left-modal-title {
color: #fff;
font-size: 1.5em;
}
```