Info Overlay
Clicking the ‘.info-toggle’ element will display (or hide) the ‘.info-overlay’ element.
Keyboard accessible!
- The ‘disable’ function sets all links within the overlay element to ‘tabindex = “-1″‘ on page load. When the overlay is toggled, all links are set to ‘tabindex = “0”‘. This prevents them from being focused while the overlay is hidden when using the user presses the ‘Tab’ key to browse the website.
- Pressing the ‘Escape’ key will hide the overlay.
- Clicking anywhere outside of the overlay will hide the overlay.
- Scrolling will hide the overlay — disabled by default.
JavaScript
// **************************************************
// Info Overlay
// Toggle
// **************************************************
const infoOverlayToggle = document.querySelector('.info-toggle');
const infoOverlay = document.querySelector('.info-overlay');
const infoOverlayLink = document.querySelectorAll('.info-overlay a');
const toggleInfo = () => {
// show
const show = () => {
infoOverlay.classList.toggle('show');
};
// hide
const hide = () => {
infoOverlay.classList.remove('show');
};
// set all link elements to tabindex="0"
const enable = () => {
infoOverlayLink.forEach((element) => {
element.setAttribute('tabindex', '0');
});
};
// set all link elements to tabindex="-1"
const disable = () => {
infoOverlayLink.forEach((element) => {
element.setAttribute('tabindex', '-1');
});
};
disable(); // run this on page load
// focus the overlay
const focusOverlay = () => {
infoOverlay.setAttribute('tabindex', '0');
infoOverlay.focus();
infoOverlayToggle.classList.add('clicked'); // mimics the toggle's hover/focus CSS
};
// focus the toggle
const focusToggle = () => {
infoOverlay.setAttribute('tabindex', '-1');
infoOverlayToggle.focus();
infoOverlayToggle.classList.remove('clicked');
};
// all functions to 'open' the menu
const open = () => {
show();
enable();
focusOverlay();
}
// all functions to 'close' the menu
const close = () => {
hide();
disable();
focusToggle();
}
// toggle is clicked
infoOverlayToggle.addEventListener('click', () => {
if (!infoOverlay.classList.contains('show')) {
open();
} else {
close();
};
});
// hide when 'Escape' key is pressed
document.addEventListener('keydown', (event) => {
if ((infoOverlay.classList.contains('show')) && (event.keyCode == 27)) {
close();
}
});
// hide when user clicks anywhere outside of the overlay
document.addEventListener('click', (event) => {
if (infoOverlay.classList.contains('show')) {
let targetElement = event.target;
do {
if (targetElement == infoOverlay || targetElement == infoOverlayToggle) {
return;
}
targetElement = targetElement.parentNode;
} while (targetElement);
close();
};
});
// hide when a user scrolls up/down
// DISABLED
// document.addEventListener('scroll', () => {
// close();
// });
};
toggleInfo();
HTML
<div class="info">
<a href="#" class="info-toggle" aria-label="Contact Information"><i class="fa-solid fa-comment"></i></a>
<div class="info-overlay">
<p>Email Us:<br><a href="mailto:email@me.com">email@me.com</a></p>
<p>Call Us:<br><a href="tel:15558299982">(555) 829-9982</a></p>
</div>
</div>
CSS
// **************************************************
// Info
// **************************************************
body {
font-family: Arial, sans-serif;
}
.info {
display: flex;
justify-content: center;
position: relative;
overflow: visible;
.info-toggle {
display: block;
color: rebeccapurple;
font-size: 5rem;
text-decoration: none;
&:hover,
&:focus,
&.clicked {
color: blueviolet;
}
}
.info-overlay {
visibility: hidden;
opacity: 0;
z-index: -1;
background: whitesmoke;
box-shadow: 1px 1px 5px rgba(0, 0, 0, 0.3);
position: absolute;
inset: 90px auto auto auto;
display: flex;
flex-direction: column;
justify-content: center;
padding: 1em 2.5em;
min-height: 140px;
z-index: 9999;
&.show {
visibility: visible;
opacity: 1;
z-index: 9999;
transition: opacity 0.3s;
}
p {
color: #000;
font-size: 0.9rem;
line-height: 1rem;
a {
color: steelblue;
font-weight: 600;
text-decoration: none;
}
}
}
}