Need help with your JSON?
Try our JSON Formatter tool to automatically identify and fix syntax errors in your JSON. JSON Formatter tool
Designing Accessible JSON Formatters for Screen Readers
Developers often work with JSON data, displaying it for debugging, documentation, or even directly to end-users in specific contexts. However, simply dumping raw JSON text onto a page, even with syntax highlighting, poses significant challenges for users relying on screen readers and other assistive technologies. This article explores why raw JSON is inaccessible and provides strategies for formatting JSON data in a way that is structured, understandable, and navigable for everyone.
Why is Raw JSON Inaccessible?
JSON's structure is designed for machines, not humans (or screen readers). When a screen reader encounters a block of raw JSON text, it typically reads characters, symbols, and words sequentially without understanding the data's hierarchical relationships.
- Lack of Semantic Structure: JSON uses punctuation like
{
,}
,[
,]
,:
, and,
to define structure. Screen readers read these symbols literally or ignore them, losing the meaning of "object start", "array element", "key-value separator", etc. - Indentation Issues: While indentation helps sighted users visualize nested structures, it's often ignored by screen readers reading linear text.
- Verbosity: Reading every character and punctuation mark in a complex JSON structure is overwhelming and disorienting.
- Navigation Difficulties: Users cannot easily jump between keys, values, or nested objects/arrays.
Consider a simple JSON object:
{ "name": "Alice", "age": 30, "city": "New York", "isStudent": false, "courses": ["History", "Physics"] }
A screen reader might read this as: "open brace quote name quote colon quote Alice quote comma quote age quote colon thirty comma quote city quote colon quote New York quote comma quote isStudent quote colon false comma quote courses quote colon open bracket quote History quote comma quote Physics quote close bracket close brace". This is incredibly difficult to parse mentally.
Semantic HTML to the Rescue
The most effective way to make JSON data accessible is to transform it into standard, semantic HTML structures that screen readers understand naturally. Instead of representing the JSON structure literally, represent the *information* contained within the JSON using elements like lists, tables, and headings.
Basic Objects as Definition Lists or Unordered Lists
A simple JSON object with key-value pairs maps well to HTML definition lists (<dl>
, <dt>
, <dd>
) or even just key-value pairs within an unordered list (<ul>
, <li>
).
Using a Definition List:
HTML Structure:
<dl> <dt>name</dt> <dd>Alice</dd> <dt>age</dt> <dd>30</dd> <dt>city</dt> <dd>New York</dd> <dt>isStudent</dt> <dd>false</dd> </dl>
Screen Reader Output (Example):
"name, term. Alice, definition. age, term. 30, definition. city, term. New York, definition. isStudent, term. false, definition."
This is much clearer, explicitly stating the "term" (key) and "definition" (value).
Arrays as Unordered Lists
JSON arrays translate directly to HTML unordered lists (<ul>
). Each item in the array becomes a list item (<li>
).
For the "courses" array from the example:
HTML Structure:
<ul> <li>History</li> <li>Physics</li> </ul>
Screen Reader Output (Example):
"List with 2 items. History. Physics."
The list structure clearly indicates multiple items.
Handling Nested Structures
Nested JSON objects or arrays should become nested HTML lists or definition lists. This mirrors the hierarchy accessibly.
Example JSON:
{ "user": { "id": 101, "address": { "street": "123 Main St", "zip": "90210" }, "roles": ["admin", "editor"] } }
Accessible HTML Structure:
HTML Structure:
<dl> <dt>user</dt> <dd> <dl> {/* Nested DL for the user object */} <dt>id</dt> <dd>101</dd> <dt>address</dt> <dd> <dl> {/* Nested DL for the address object */} <dt>street</dt> <dd>123 Main St</dd> <dt>zip</dt> <dd>90210</dd> </dl> </dd> <dt>roles</dt> <dd> <ul> {/* Nested UL for the roles array */} <li>admin</li> <li>editor</li> </ul> </dd> </dl> </dd> </dl>
Screen readers announce the nesting level of lists, allowing users to understand the hierarchy and navigate through it using list item shortcuts.
Collapsible Sections with <details> and <summary>
For large or deeply nested JSON, presenting everything at once can be overwhelming. The native HTML <details>
and <summary>
elements are excellent for creating collapsible sections that are inherently accessible. The <summary>
acts as a toggle, and screen readers announce its expanded/collapsed state.
You can wrap objects or arrays in <details>
tags:
HTML Structure:
<details> <summary>User Information (Click to toggle)</summary> <dl> {/* Content inside the collapsible section */} <dt>id</dt> <dd>101</dd> {/* ... other user details ... */} </dl> </details>
This allows users to focus only on the sections they are interested in, reducing cognitive load.
Using Tables for Arrays of Objects
If you have a JSON array where each element is an object with the same structure (e.g., an array of users), a simple HTML <table>
can be an appropriate and accessible format. Use table headers (<th>
) for the JSON keys and table data cells (<td>
) for the values.
Example JSON:
[ { "name": "Alice", "age": 30 }, { "name": "Bob", "age": 25 } ]
Accessible HTML Structure:
HTML Structure:
<table> <caption>List of Users</caption> {/* Important for table accessibility */} <thead> <tr> <th scope="col">Name</th> <th scope="col">Age</th> </tr> </thead> <tbody> <tr> <td>Alice</td> <td>30</td> </tr> <tr> <td>Bob</td> <td>25</td> </tr> </tbody> </table>
Ensure you use <caption>
and <th scope="col">
or scope="row">
for proper table accessibility, allowing screen readers to understand the relationship between headers and data cells.
Additional Considerations for Screen Readers
ARIA Attributes (Use Sparingly)
While semantic HTML should be your primary tool, ARIA attributes can sometimes enhance clarity where native HTML isn't quite sufficient.
aria-label
oraria-describedby
: Could be used on container elements if extra context is needed, but often good HTML structure is enough. For instance, you might label a<dl>
for a specific object property if the<dt>
alone isn't clear in context.role="group"
: Can sometimes be used around logical groupings of data if standard list/DL structures don't apply neatly, but prefer native elements first.
**Caution:** Do not try to recreate the raw JSON syntax visually and then add ARIA to describe punctuation. This is usually less effective than transforming the structure into semantic HTML. Prioritize readability and navigability of the *content*, not the original format's syntax.
Handling Data Types
Consider how different JSON data types are presented:
- Booleans (
true
,false
): Display them as text. Avoid using icons or colors as the *only* indicator without providing equivalent text. - Null: Display as "null" or an equivalent accessible term like "Not Set" or "Empty".
- Numbers: Display as text. Ensure large numbers are formatted readably if necessary (though less common in pure JSON display).
- Strings: Display as text. Be mindful of potentially long strings or strings containing line breaks.
Code Blocks and Syntax Highlighting
If the goal is specifically to *show* the raw JSON structure (e.g., for developers), presenting it within <pre>
and <code>
tags is appropriate. Ensure that:
- The code block is clearly labeled, perhaps with a heading or a preceding paragraph explaining that this is the *raw data format*.
- The content within
<code>
uses appropriate HTML entities for characters like<
,>
,{
,}
etc., if you are embedding code *within* the code tag itself (e.g., explaining syntax). For simply displaying JSON text, the raw characters are usually fine within<pre>
, but ensure line breaks are preserved. - If using client-side syntax highlighting, ensure it doesn't create accessibility barriers (e.g., relying solely on color, creating complex nested structures that confuse screen readers). Server-rendered or static highlighting is often safer.
However, if the purpose is for a user to *understand the data*, transforming it into semantic HTML lists/tables is preferred over just showing the raw syntax.
Practical Implementation Tips
- Build a Recursive Transformer: Write a function that takes a JSON object or array and recursively generates the corresponding HTML structure (
<dl>
/<dt>
/<dd>
,<ul>
/<li>
, or<table>
). - Handle Different Types: The transformer should check the type of each value (object, array, string, number, boolean, null) and output the appropriate HTML.
- Consider Large Data Sets: Implement features like pagination, filtering, or the
<details>
/<summary>
pattern for large JSON payloads. - Provide Context: Add introductory text or headings to explain what the displayed JSON data represents.
- Test with Screen Readers: Always test your formatted output with actual screen reader software (like NVDA, JAWS, VoiceOver) to ensure it is interpreted correctly.
Conclusion
Making JSON data accessible is not about preserving the original syntax, but about translating the underlying information structure into a format that assistive technologies can understand and convey meaningfully. By leveraging semantic HTML elements like definition lists, unordered lists, tables, and the <details>
/<summary>
pattern, developers can create JSON formatters that are not only visually organized but also fully navigable and comprehensible for screen reader users. Prioritizing semantic structure over visual mimicry is key to inclusive data presentation.
Need help with your JSON?
Try our JSON Formatter tool to automatically identify and fix syntax errors in your JSON. JSON Formatter tool