Skip to content
easeweb
Search topics

Character counters that stay silent or speak on every key

A gift message counter changes on screen only, or in an assertive live region on every key, so a screen reader says nothing, or a number after each letter.

WCAG 2.2
SC 4.1.3AA· new in 2.1
Required by
EN 301 549 (EU)
Broken count.textContent = countText(100 - gift.value.length);
The accessibility problem illustrated: No vision:How much room is left?
01

The problem

Screen reader users can't tell how much room is left in a field with a limit, or hear a number after every letter they type.

02

Try it

Finish the gift message, then stop typing and listen.

  • Broken 1: type a few words, and keep going until the box is full. The count under the box drops, and the panel shows what a screen reader says.

  • Broken 2: type a few words. How many times is the count read?

  • Apply the fix. Type a word, stop for a second, then type on to the limit and stop again.

Broken Can you fix this?

15 characters left

Screen reader says:

(Click in the box and type)

A recreated demo. The broken version is intentionally inaccessible.

03

The fix

Say the count once typing pauses near the limit.

Before

A counter that changes on screen only

<label for="gift">Gift message</label><textarea id="gift" name="gift" maxlength="100"></textarea><p id="gift-count" class="count">100 characters left</p>
What is wrong1 point

The count is right, and it sits right under the box. One thing is wrong.

  • The p is not a live region, so the count changes on screen and is never announced, and when the box is full, nothing says why it stopped taking letters.
After
FixThe count said once, when typing pauses near the limit
<label for="gift">Gift message</label><p id="gift-hint" class="hint">You can enter up to 100 characters.</p><textarea id="gift" name="gift" maxlength="100" aria-describedby="gift-hint"></textarea><p id="gift-count" class="count" aria-hidden="true">100 characters left</p><p id="gift-status" class="visually-hidden" role="status"></p>
How it is fixed4 steps
  1. Put the limit in a hint above the box and tie it to the field with aria-describedby. The screen reader reads "You can enter up to 100 characters" when the person reaches the field, before they type a word.
  2. Take aria-live off the visible counter and give it aria-hidden="true". It still changes on every key for people who see it, but it is no longer read on each key, or a second time when someone reads the page.
  3. Add one empty p with role="status", visually hidden, that is on the page from the start, so writing into it is a change the screen reader announces, once it has finished what it is saying.
  4. Write the count into it once typing has paused for a second, and only from 20 characters left. A person typing hears nothing about the count until they stop near the limit, then hears "12 characters left" once. Further from the limit, the region is emptied, so the next count near it is a change again.

This fixes both Befores and passes 4.1.3. The count is a status message given to the screen reader through its role, politely, once per pause, instead of never or after every key.

Easily confused
04

Design ideas

A counter can take any shape, as long as it has words to say.

Four more ways to draw the gift message counter, each live: type in them. Three say the count in words once you stop near the limit; one draws it only as a bar, and nothing is ever said.

In the design file

  • Write the words a screen reader says for the count, such as “15 characters left”, beside a counter drawn as a fraction, a ring or a bar.
  • Note that those words are said once typing stops, and only near the limit, such as from 20 characters left.
  • Put the limit in the hint under the label, so it is read when people reach the box.
  • If people may go over the limit, draw the box over it too, with the words for how many characters too many.

Passes

  • You can enter up to 100 characters.

    Count near the limit, and how far over Nothing under the box until 20 characters are left, then “15 characters left”; past the limit, “3 characters too many” in red, with the box outlined, so people can paste their whole message and cut it down. The words are said once typing stops.
  • You can enter up to 100 characters.

    Fraction in the corner “85 / 100” in small grey type under the box, the count and the limit as Material and Ant Design draw them. Read on every key it would be noise, so it stays silent: the limit is in the hint, and “15 characters left” is said once typing stops near the limit.
  • You can enter up to 100 characters.

    Ring that fills, with the number near the limit A small ring fills as the message grows and shows the number inside once the limit is near, as X’s post box does. It moves only while letters go in and stops with them. The ring itself says nothing; “15 characters left” is said in words once typing stops.

Fails

  • Bar with no numberWCAG 4.1.3 A thin bar fills under the box and turns amber near the limit. It looks calm, but there is no number and no words anywhere, so nothing can be read: a screen reader user learns the box is full only when it stops taking letters.
05

Verify the fix

4 checks, no mouse.

Test with: Screen reader, Keyboard

0 of 4 checked

Record the OS, browser and assistive-technology versions, the build, the date, and the actual result of each step. Repeat after the field component, its counter or the limit changes.

How screen readers handle aria-live="assertive", role="status" and aria-describedby · tested by hand, October 2026

Limits

Live regions behave differently across screen readers and browsers, and some drop a polite message when people start typing again before it is read. This pattern covers one field with a fixed limit in characters; a limit in words works the same way, with words counted instead. Other status messages, such as a saved draft, are covered in status messages that are shown but never announced. Test your real field, with its real limit, hint and error messages, with the screen readers your users use.

This is a recreated teaching example, not a finding about a named client. The code is a starting pattern: test it in your own product. No completed assistive-technology test is claimed here.

EaseWeb service

Fixed it? Keep it from coming back.

I turn guides like this one into rules your coding agents follow and checks your CI runs. Then I retest by hand with a keyboard and screen readers, periodically.

See the service