Sometimes, designers use CSS content: to add text or icons before or after elements. If that content is meant to be seen, it might also need an accessible version for people who can’t see it.
The spec allows you to add alternative text by putting it after a slash in the content property. For example:
.icon::before {
content: "🔍" / "Search";
}
The part before the slash is what’s shown visually - in this case, a magnifying glass icon.
As per the CSS Generated Content Module Level 3 specification, the slash alternative text is intended as a replacement for speech output - in this case the speech output should be “Search”.
If such alternative text is provided, it must be used for speech output instead.
In supporting browsers, this alternative text may be exposed to the accessibility tree and could be used by assistive technologies in place of the visible CSS content.
Let’s look at four variations:
Test criteria:
For these tests, “announced” means that the exact string (for example, “Visible generated content” or “Hello world”) is spoken when the block receives focus. Partial or generic announcements like “and one other item” are treated as failures.
These tests distinguish between:
- Keyboard focus navigation (e.g. using the TAB key)
- Screen reader reading navigation (e.g. line-by-line or virtual cursor navigation)
Test cases
Test 1: Generated content only
.test-old::after {
content: "Visible generated content";
}
Pass criteria:
- 1.1: "Visible generated content" should be announced.
| OS | Browser | Screen reader | 1.1 |
|---|---|---|---|
| macOS | Chrome | VoiceOver | PASS |
| macOS | Firefox | VoiceOver | PASS |
| macOS | Safari | VoiceOver | PASS |
| Windows | Chrome | NVDA | PASS |
| Windows | Firefox | NVDA | PASS |
| Windows | Chrome | JAWS | PASS |
| Windows | Firefox | JAWS | PASS |
Test 2: Alternative text only
.test-alt-only::after {
content: "" / "Hello world";
}
Pass criteria:
- 2.1: Generated content should not be announced (left blank).
- 2.2: "Hello world" alternative text should be announced when navigating via keyboard focus (TAB).
- 2.3: "Hello world" alternative text should be announced when navigating line-by-line using a screen reader.
| OS | Browser | Screen reader | 2.1 | 2.2 | 2.3 |
|---|---|---|---|---|---|
| macOS | Chrome | VoiceOver | PASS | PASS | PASS |
| macOS | Firefox | VoiceOver | PASS | PASS | PASS |
| macOS | Safari | VoiceOver | PASS | FAIL | FAIL |
| Windows | Chrome | NVDA | PASS | FAIL | FAIL |
| Windows | Firefox | NVDA | PASS | PASS | PASS |
| Windows | Chrome | JAWS | PASS | PASS | PASS |
| Windows | Firefox | JAWS | PASS | FAIL | PASS |
Test 3: Blank alternative text
.test-visible-only::after {
content: "Visible generated content" / "";
}
Pass criteria:
- 3.1: "Visible generated content" should not be announced. Even though the value is blank, it is still considered alternative text as the slash and quotes are present.
- 3.2: No generated or alternative text should be announced when navigating via keyboard focus (TAB).
- 3.3: No generated or alternative text should be announced when navigating line-by-line using a screen reader.
| OS | Browser | Screen reader | 3.1 | 3.2 | 3.3 |
|---|---|---|---|---|---|
| macOS | Chrome | VoiceOver | PASS | PASS | PASS |
| macOS | Firefox | VoiceOver | PASS | PASS | PASS |
| macOS | Safari | VoiceOver | PASS | PASS | PASS |
| Windows | Chrome | NVDA | PASS | PASS | PASS |
| Windows | Firefox | NVDA | PASS | PASS | PASS |
| Windows | Chrome | JAWS | PASS | PASS | PASS |
| Windows | Firefox | JAWS | PASS | PASS | PASS |
Test 4: Generated content and alternative text
.test-both::after {
content: "Visible generated content" / "Hello world";
}
Pass criteria:
- 4.1: "Visible generated content" should not be announced because the alternative text replaces this content.
- 4.2: "Hello world" alternative text should be announced when navigating via keyboard focus (TAB).
- 4.3: "Hello world" alternative text should be announced when navigating line-by-line using a screen reader.
| OS | Browser | Screen reader | 4.1 | 4.2 | 4.3 |
|---|---|---|---|---|---|
| macOS | Chrome | VoiceOver | PASS | PASS | PASS |
| macOS | Firefox | VoiceOver | PASS | PASS | PASS |
| macOS | Safari | VoiceOver | FAIL | FAIL | FAIL |
| Windows | Chrome | NVDA | PASS | FAIL | FAIL |
| Windows | Firefox | NVDA | PASS | PASS | PASS |
| Windows | Chrome | JAWS | PASS | PASS | PASS |
| Windows | Firefox | JAWS | PASS | PASS | PASS |
Summary of findings
As support is still slightly inconsistent across browser and screen reader combinations, this syntax should probably be treated as experimental. For important information, continue to use semantic HTML and ARIA, and do not rely on CSS-generated content as the sole mechanism for accessibility.
Footnotes
- 08/02/2026: Tests 3.1 and 4.1 were updated to align with the CSS specification’s replacement model for alternative text. The results were adjusted accordingly.
- 08/02/2026: Additional tests added to determine different navigation methods.
Disclaimer
Test results involving operating systems, browsers, and assistive technologies should be interpreted with care. Behaviour can vary across versions, browser engines, and assistive technology settings, even when default configurations are used.
Related articles
Understanding screen reader speech queues
This article explores the concept of utterances and how the screen reader speech queue works.
More about screen reader speech queues
This article explores a single example to show why they don’t always behave the way you might expect. In fact, we are going to look at one specific vehicle type - motor scooters.