My use case is a customer coming to a landing page from an email. The page itself is doing some processing and then displays success or error messaging to the customer.

Web design isn't my day job - so what I'm looking for is a best practice or maybe pro's and con's to the approach that I'm following.

When the customer hits the page all available content is loaded to the DOM but only the Loading content is displayed:

<div class="loading" style="display:block">Loading content Here</div>
<div class="success" style="display:none">Success content Here</div>
<div class="error" style="display:none">Error content Here</div>

Based on the outcome of the AJAX call, Loading is flipped to display:none while either Success or Error is flipped to display:block. Once either Success or Error is displayed, I am removing the remaining hidden elements from the DOM.

Conversely, I suppose I could have the AJAX call return the messaging that should be displayed instead of pre-loading it to the page.

It's this change in methodology that has me wondering what the standard of practice is for people that do this sort of thing every day...? Are there accessibility concerns with this methodology - would screen readers struggle to parse the page?

Thank you!

1 Answer 1


TL;DR: You can implement what you want without disturbing UX, just not the way your HTML is setup right now.

So I did some testing with the code you shared above, this is a definitely a fun task.

(I was using the narrator that comes with Windows 11 btw)

The best solution I came up with was by adding an empty element with the aria-live="assertive" attribute. I tried using the display: block idea and that didn't work. So I found that using the aria-live attribute and then changing the target element's innerHTML did the trick.

Here's the code I used:

<h1>This is a page</h1>
<h2>Oh look, subtext</h2>

<div id="status" style="display:block" aria-live="assertive"></div>

    const statusDiv = document.getElementById('status');

    setTimeout(() => {
        // show success
        statusDiv.innerHTML = "Success content Here"
    }, 3000)

    setTimeout(() => {
        // show error
        statusDiv.innerHTML = "Error content Here"
    }, 7000)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.