aria-label, aria-labelledby, and aria-live in practice
Why these three come up
If you're interviewing at a company that takes accessibility seriously, expect questions on ARIA. These three attributes are the ones that come up most often — and once you see the specific problem each one is designed to solve, they click quickly.
aria-label
aria-label gives a screen reader a name for an element when there's no visible text to use. The textbook case is an icon-only button — think the little X on a modal dialog.
1<!-- Without aria-label, screen reader just says "button" -->2<button>3 <svg><!-- X icon --></svg>4</button>56<!-- With aria-label, screen reader says "Close dialog button" -->7<button aria-label="Close dialog">8 <svg><!-- X icon --></svg>9</button>
Real-world shapes you've seen a hundred times:
1<button aria-label="Search">2 <svg><!-- Magnifying glass icon --></svg>3</button>45<button aria-label="Add to cart">6 <svg><!-- Shopping cart icon --></svg>7</button>
One gotcha that trips candidates up: if an element has both visible text and aria-label, the screen reader reads only the aria-label. So don't double up without thinking.
aria-labelledby
Instead of duplicating a label, aria-labelledby points to existing text on the page via its id. That way you keep the sighted and screen-reader experiences in sync by design.
A dialog labelled by its heading:
1<div role="dialog" aria-labelledby="dialog-title">2 <h2 id="dialog-title">Delete Account</h2>3 <p>This action cannot be undone.</p>4 <button>Delete</button>5 <button>Cancel</button>6</div>
No duplicate string to keep in sync. You can also reference multiple ids:
1<span id="first-name">First Name</span>2<span id="required">(required)</span>3<input aria-labelledby="first-name required" />
The screen reader reads them concatenated: "First Name (required)".
Interview framing: when asked for the difference between aria-label and aria-labelledby, the one-line answer is: aria-labelledby ties the accessible name to existing visible text, so updating the UI automatically updates the announcement.
aria-live
Now the interesting one. Imagine a client-side form that shows a validation error when the user types an invalid email. A sighted user sees the red message appear — but a screen reader user gets nothing unless you tell it to announce the change.
That's what aria-live does: it marks a region as "live" so screen readers notice updates.
Two values to know:
aria-live="polite" — announces when the user is idle. This is the default choice.
aria-live="assertive" — interrupts the user. Reserve it for genuinely urgent information like "Your session is about to expire."
A form-validation example:
1<form>2 <label for="email">Email</label>3 <input type="email" id="email" />45 <!-- This div will announce changes to screen readers -->6 <div aria-live="polite" role="status"></div>7</form>89<script>10 const input = document.getElementById('email');11 const status = document.querySelector('[aria-live]');1213 input.addEventListener('blur', () => {14 if (!input.value.includes('@')) {15 status.textContent = 'Please enter a valid email';16 }17 });18</script>
When the text updates, the screen reader announces the error without the user having to hunt for it.
A loading-state example (this one is very common in interviews):
1<button id="submit">Submit</button>2<div aria-live="polite">3 <span id="status">Ready</span>4</div>56<script>7 document8 .getElementById('submit')9 .addEventListener('click', async () => {10 const status = document.getElementById('status');1112 status.textContent = 'Submitting...';13 await submitForm();14 status.textContent = 'Success! Form submitted.';15 });16</script>
Two companion attributes
aria-atomic — announce the whole region or just what changed?
1<!-- Announces "Items in cart: 4" (the whole thing) -->2<div aria-live="polite" aria-atomic="true">3 Items in cart: <span id="count">3</span>4</div>56<!-- Announces just "4" (only what changed) -->7<div aria-live="polite" aria-atomic="false">8 Items in cart: <span id="count">3</span>9</div>
aria-relevant — which kinds of changes trigger an announcement?
1<!-- Only announce when text changes or nodes are added -->2<div aria-live="polite" aria-relevant="additions text">3 <!-- Updates here get announced -->4</div>
A clean interview answer
aria-label: "Supplies an accessible name for elements without visible text — typical case is an icon-only button."
aria-labelledby: "References existing visible text by id. Better than aria-label because the visual and assistive experiences stay in sync automatically — e.g., using a dialog's heading as its accessible name."
aria-live: "Declares a live region so dynamic content gets announced. polite for most things; assertive only for urgent interruptions. Crucially, the container must exist in the DOM before you update it — otherwise nothing is announced."