Egy olyan felugró ablak elkészítése, mely megjelenésekor fókuszba kerül, azaz a TAB gomb is csak a modal-on belül érvényesül, a környezete elhalványul és ha a bezáró gombra vagy a környzetére kattintunk akkor tűnik el. Tipikus példa a hamburger menü megvalósítására.
Csak azért van három indítógomb, hogy gyakoroljuk ugyanazon eseményfigyelő több gombra való felírását,
ugyanazon
modal fog feljönni. A tabindex
negatív értékkel az adott gomb a TAB használatakor nem fog
fókuszba
kerülni, kimarad. A tabindex = 0
azt jelenti, hogy a TAB megnyomásakor a főkusz erre az elemre
kerül. A tabindex
pozitív értékei irányíthatnák a további sorrendet, de ezek használata nem
ajánlott és nekem nem is működött. A példában az Okey és a Cancel gombra való kattintás is bezárja a modalt.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Modal</title>
<link rel="stylesheet" href="./css/style.css">
</head>
<body>
<div class="backdrop fade-in"></div>
<button class="btn-any" tabindex="-1">Első modal</button>
<button class="btn-any" tabindex="-1">Második modal</button>
<button class="btn-any" tabindex="-1">Harmadik modal</button>
<div class="modal fade-in">
<div class="modal__close" tabindex="0">
<div class="modal__close--bar1" tabindex="0">
<div class="modal__close--bar2"></div>
</div>
</div>
<h3 class="modal__title">CSSSript.com</h3>
<p class="modal__content">Lorem ipsum dolor sit amet consectetur adipisicing elit. Eius perspiciatis
deleniti,
blanditiis ullam dolor assumenda commodi rem, beatae modi nam neque possimus odit nobis molestias
excepturi
eum ratione eaque deserunt libero nihil odio? Esse cupiditate sed quaerat, sunt earum perspiciatis quis.
Molestiae expedita maiores voluptate assumenda blanditiis nemo repellendus ipsum iusto quia delectus.
Illum
consequuntur earum excepturi eos voluptas doloribus adipisci possimus quis, facilis ex nulla, sequi
numquam
dolore iusto! Alias cum quia a vero.
</p>
<div class="modal__buttons">
<button class="btn-modal btn-yes">Okey</button>
<button class="btn-modal btn-no">Cancel</button>
</div>
</div>
<script src="./js/main.js"></script>
</body>
</html>
A modal bezáró gombot CSS-el generáljuk és abszolut pozicionálással tesszük a modal jobb felső sarkába.
* {
margin: 0;
padding: 0;
}
*, *::before, *::after {
box-sizing: inherit;
}
html {
box-sizing: border-box;
}
body {
min-height: 100vh;
position: relative;
}
.modal {
padding: 1rem;
border: 2px solid lightgray;
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
position: relative;
display: none;
z-index: 6;
background-color: cornsilk;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 100%;
}
.modal__title {
margin-top: 1rem;
}
.modal__content {
padding: 1rem 0;
}
.modal__buttons {
display: flex;
justify-content: flex-end;
}
.btn-modal {
padding: 0.75rem 1.5rem;
margin: 0.5rem;
border: none;
color: white;
border-radius: 2px;
cursor: pointer;
transition: all 0.3s;
}
.btn-modal:hover {
scale: 1.05;
}
.btn-any {
background-color: blueviolet;
padding: 0.75rem 1.5rem;
margin: 0.5rem;
border: none;
color: white;
border-radius: 2px;
cursor: pointer;
transition: all 0.3s;
}
.btn-yes {
background-color: lightgreen;
}
.btn-yes:hover {
background-color: lime;
}
.btn-no {
background-color: lightsalmon;
}
.btn-no:hover {
background-color: red;
}
.modal__close {
position: absolute;
top: 0;
right: 0;
cursor: pointer;
border: none;
width: 2rem;
height: 2rem;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.modal__close--bar1,
.modal__close--bar2 {
width: 20px;
height: 2px;
background-color: #000;
}
.modal__close--bar1 {
transform: rotate(45deg);
}
.modal__close--bar2 {
transform: rotate(90deg);
}
.modal__close--bar1:hover,
.modal__close--bar2:hover {
scale: 1.1;
}
.backdrop {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100vh;
background: rgba(0, 0, 0, 0.5);
z-index: 5;
}
.fade-in {
animation-name: fadeInOpacity;
animation-iteration-count: 1;
animation-timing-function: ease-in;
animation-duration: .3s;
}
.fade-out {
animation-name: fadeOutOpacity;
animation-iteration-count: 1;
animation-timing-function: ease-in;
animation-duration: .3s;
}
@keyframes fadeInOpacity {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
@keyframes fadeOutOpacity {
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}
@media(min-width: 560px) {
.modal {
width: 50%;
}
}
Felírjuk a DOM elemeket, NodeList-eket.
const buttons = document.querySelectorAll('.btn-any');
const modal = document.querySelector('.modal');
const backdrop = document.querySelector('.backdrop');
const modalButtons = document.querySelectorAll('.btn-modal');
const close = document.querySelector('.modal__close');
Felírjuk az eseményfigyelőket.
for (let i = 0; i < buttons.length; i++) {
modalOpen(i);
}
function modalOpen(i) {
buttons[i].addEventListener('click', () => {
backdrop.classList.remove('fade-out');
modal.classList.remove('fade-out');
modal.style.display = 'block';
backdrop.style.display = 'block';
});
};
A modalhoz hozzáadjuk a TAB eseményfigyelőjét, mely a modal záró gombja az Okey és a Cancel gombok között váltogatja a TAB mozgását. A TAB klaviatúra kódja a 9-es.
modal.addEventListener('keydown', (e) => {
e.preventDefault();
if (e.keyCode === 9 && document.activeElement === close) {
modalButtons[0].focus();
}
else if (e.keyCode === 9 && document.activeElement === modalButtons[0]) {
modalButtons[1].focus();
}
else if (e.keyCode === 9 && document.activeElement === modalButtons[1]) {
close.focus();
}
})
A modal eltűnésére egy külön függvényt írunk.
function fadeOut() {
backdrop.classList.add('fade-out');
modal.classList.add('fade-out');
setTimeout(() => {
backdrop.style.display = 'none';
modal.style.display = 'none';
}, 300)
}
A modal eltűnésére felírjuk az eseményfigyelőket.
for (let i = 0; i < modalButtons.length; i++) {
modalButtons[i].addEventListener('click', () => {
fadeOut();
})
}
close.addEventListener('click', () => {
fadeOut();
})
backdrop.addEventListener('click', () => {
fadeOut();
})