Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nfreear/7e863682fe314550c669493655271b60 to your computer and use it in GitHub Desktop.
Save nfreear/7e863682fe314550c669493655271b60 to your computer and use it in GitHub Desktop.
Accessibility - "More" button loading behaviour demo - Ajax - WAI-ARIA | https://w3.org/TR/wai-aria-practices/#no_aria_better_bad_aria
<!doctype html><html lang="en"><meta charset="utf-8">
<title> "More" button loading demo (WAI-ARIA) </title>
<style>
body { margin: 1rem auto; max-width: 35rem; padding: .5rem; }
main { font: 1rem/1.5 sans-serif; position: relative; }
/* Accessibility / Usability - visually indicate new content.
@TODO: customise, animate - https://code-boxx.com/glowing-text-pure-css/ .. etc.
*/
.glow {
box-shadow: 0 0 2rem .5rem teal;
text-shadow: 0 0 .5rem #fff700;
transition: all 2s;
}
.loading {
cursor: wait;
}
.loading .morebtn_wrapper,
.loading #more-button {
border: none;
outline: none;
max-height: 1px;
max-width: 1px;
overflow: hidden !important;
transition: all 3s;
}
.loading-complete .morebtn_wrapper {
display: none;
}
#more-status {
position: absolute;
left: 0;
top: 50%;
height: 100px;
width: 100%;
margin-top: -50px; /* account for padding and border if not using box-sizing: border-box; */
}
/* Accessibility / Usability - visual loading indicator.
*/
#more-status > * {
background-color: #f8f8f8;
background-image: url(https://upload.wikimedia.org/wikipedia/commons/7/7a/Ajax_loader_metal_512.gif);
background-position: center bottom;
background-repeat: no-repeat;
background-size: contain;
display: block;
font-size: large;
margin: 0 auto;
max-width: 9rem;
text-align: center;
height: 12rem;
padding: .5rem;
}
#grid-container > * {
border: 1px solid #bbb;
margin: 1rem 0;
padding: .7rem;
}
/* Copy styles.
*/
#grid-container > .morebtn_wrapper {
border: none;
padding: 50px 0 100px;
text-align: center;
}
.morebtn {
border: 2px solid #808080;
display: inline-block;
text-decoration: none;
text-align: center;
font-weight: 700;
font-size: 20px;
line-height: 24px;
color: #808080;
padding: 18px 24px;
min-width: 242px;
position: relative;
text-transform: uppercase;
border-radius: 60px;
-moz-border-radius: 60px;
-webkit-border-radius: 60px;
-ms-border-radius: 60px;
position: relative;
background: white;
cursor: pointer;
}
.morebtn::after {
content: '';
position: absolute;
display: block;
background-image: url(https://iet.double.systems//images/svg/more.svg);
background-repeat: no-repeat;
background-position: center center;
background-size: cover;
display: inline-block;
vertical-align: middle;
width: 18px;
height: 18px;
left: 50%;
margin-left: -9px;
bottom: -27px;
}
</style>
<h1> "More" button loading demo (WAI-ARIA) </h1>
<p> Please VIEW SOURCE to look at the HTML markup and Javascript. </p>
<p> Important — <a href="https://w3.org/TR/wai-aria-practices/#no_aria_better_bad_aria">No ARIA is better than Bad ARIA</a>!</p>
<!-- Accessibility - use a "main" landmark role. -->
<main role="main">
<!-- Screen reader accessibility - WAI-ARIA live region - status. -->
<div id="more-status" role="status" aria-live="polite"></div>
<!-- Screen reader accessibility - WAI-ARIA live region - grid-container. -->
<div id="grid-container" role="region" aria-live="polite" aria-label="Articles">
<article tabindex="-1"> <h2> Grid article 1. </h2> </article>
<article tabindex="-1"> <h2> Grid article 2. </h2> </article>
<article tabindex="-1"> <h2> Grid article 3. </h2> </article>
<article tabindex="-1"> <h2> Grid article 4. </h2> </article>
<!-- <article> <h2> Grid article 5. </h2> </article> -->
<!-- Accessibility - use a "form" role and an "aria-label". -->
<div class="morebtn_wrapper" role="form" aria-label="Load more content">
<!--
Keyboard accessibility.
Make this a <button> so it behaves well with 'SPACE-BAR' as well as 'ENTER' keys!
-->
<button id="more-button" class="morebtn" aria-label="Load more content" type="button">More</button>
</div>
</div>
</main>
<script>
// Mockup an Ajax request.
const DELAY_MS = 4000;
const ITEMS = [ 5, 6, 7, 8 /*, 9, 10 */ ]; // Clunk!
const FIRST_IDX = ITEMS[0];
const BODY = document.body;
const CONTAINER = document.querySelector('#grid-container');
const MORE_STATUS = document.querySelector('#more-status');
const MORE_BUTTON = document.querySelector('#more-button');
// Accessibility - use the "click" event with a "real" <button>!
MORE_BUTTON.addEventListener('click', ev => {
ev.preventDefault();
console.warn('"More" button clicked - Loading content', ev);
// Accessibility - visiual "loading" indicator(s)
BODY.classList.add('loading');
BODY.classList.add('more-button-clicked');
// Accessibility - non-visual "loading" indicator".
MORE_STATUS.innerHTML = '<div>Loading content</div>';
// Mockup an Ajax request.
setTimeout(() => {
BODY.classList.remove('loading');
BODY.classList.add('loading-complete');
ITEMS.forEach(index => {
const ELEM = document.createElement('article');
ELEM.innerHTML = `<h2> Grid article ${index}. </h2>`;
ELEM.id = `grid-item-${index}`;
ELEM.setAttribute('tabindex', '-1');
CONTAINER.appendChild(ELEM);
});
// Tidy up!
MORE_STATUS.textContent = '';
const FIRST_LOADED = document.querySelector(`#grid-item-${FIRST_IDX}`);
// Keyboard accessibility - set focus.
FIRST_LOADED.focus();
FIRST_LOADED.scrollIntoView({ behavior: 'smooth', block: 'start' });
// Accessibility / usability - visually indicate new content.
FIRST_LOADED.classList.add('glow');
setTimeout(() => FIRST_LOADED.classList.remove('glow'), DELAY_MS);
console.warn('Loading content - completed!');
},
DELAY_MS);
});
</script>
<pre>
What this page demonstrates:
1. The "More" button is keyboard accessible with the SPACE-BAR and ENTER keys;
2. Screen reader users are informed as the page starts to load more content;
3. Screen reader users are read the new content when it arrives;
4. Keyboard focus is set on the first new article;
5. The page is scrolled to the first new article;
6. The first new article is visually highlighted;
Nick Freear, 20-April-2021.
</pre>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment