Skip to content
Dashboard

Improving the accessibility of our Next.js site

Fitts' Law, what it really takes to make a complete form error, how to make web-based games playable for all, and more.

Link to headingIncrease element target size for better usability

A demonstration of the footer on the Next.js Conf registration page. A mouse hovers over the footer revealing an automatically expanding element that reveals several useful links.
A mouse hovers and moves over the footer struggling to stay within the red, 36px tall rectangle of the footer's container.
A mouse hover the footer, expanding it to the left and revealing more useful links. The mouse travels over the 60px tall background, easily staying within the bounds of the red container.

Link to headingBuild with semantic HTML

A screenshot of the ticket theme picker from the Next.js Conf website. It shows 3 buttons with each button having a different color theme.
A screenshot of the ticket theme picker from the Next.js Conf website. It shows 3 buttons with each button having a different color theme.
const THEMES = ["a", "b", "c"];
const TicketThemePicker = () => {
const [activeTheme, setActiveTheme] = useState(THEMES[0]);
return THEMES.map((theme) => (
<button
key={theme}
onClick={() => {
setActiveTheme(theme);
}}
>
<Image src={getImage(theme)} />
{activeTheme === theme && <CheckmarkIcon />}
</button>
));
};

Mapping over array elements to create button images. This code is missing HTML attributes that would improve accessibility.

Link to headingA more robust control

const THEMES = ["a", "b", "c"];
const TicketThemePicker = () => {
const [activeTheme, setActiveTheme] = useState(THEMES[0]);
return THEMES.map((theme) => (
<React.Fragment key={theme}>
<input
checked={activeTheme === theme}
id={`ticket-theme-${theme}`}
onChange={() => {
setActiveTheme(theme);
}}
type="radio"
value={theme}
/>
<label htmlFor={`ticket-theme-${theme}`}>
<Image alt={getDescription(theme)} src={getImage(theme)} />
{activeTheme === theme && <CheckmarkIcon aria-hidden="true" />}
</label>
</>
));
};

An array of controls using inputs with accessibility improvements including type, alt, and aria attributes.

Link to headingBe delightful with alternative text

The 3 Next.js Conf ticket themes side-by-side.
The 3 Next.js Conf ticket themes side-by-side.

Link to headingBetter descriptions

Link to headingInform with input error messages

A screenshot of the email input on the Next.js Conf website with an error message saying “Please enter a valid email address”.
A screenshot of the email input on the Next.js Conf website with an error message saying “Please enter a valid email address”.
const EmailForm = () => {
const [errorMessage, setErrorMessage] = useState(null);
const onChangeHandler = () => { /* Code to handle change */ }
const onSubmitHandler = () => { /* Code to handle success or error */ }
return (
<form onSubmit={onSubmitHandler}>
<label htmlFor="email">Email</label>
<input id="email" name="email" onChange={onChangeHandler} />
{
errorMessage && <p>{errorMessage}</p>
}
</form>
)
}

const EmailForm = () => {
const [errorMessage, setErrorMessage] = useState(null);
const onChangeHandler = () => { /* Code to handle change */ }
const onSubmitHandler = () => { /* Code to handle success or error */ }
return (
<form onSubmit={onSubmitHandler}>
<input onChange={onChangeHandler} />
<p role="alert" aria-atomic="true">{errorMessage}</p>
</form>
)
}

Link to headingReduce motion according to user preferences

Link to headingMaking Vordle accessible

A screenshot of the Vordle board, showing six rows containing the following five letter words, one per row: SMOKE, REACT, TRIED, EXITS, EPOCH, SCARE. Letters have orange, green, or gray borders around them.
A screenshot of the Vordle board, showing six rows containing the following five letter words, one per row: SMOKE, REACT, TRIED, EXITS, EPOCH, SCARE. Letters have orange, green, or gray borders around them.
A screenshot of a Tweet by Guillermo Rauch (@rauchg) with the text ‘Vordle 2 5/6 😅 Dynamic without limits. #nextjsconf’ and an opengraph image below it.

Link to headingListening to our users

A screenshot of a Vordle gameboard emulating red-green color-blindness. The green colors to indicate exactly correct letters are now impossible to see.
A screenshot of a Vordle gameboard emulating red-green color-blindness. The green colors to indicate exactly correct letters are now impossible to see.
A Vordle board showing how we added icons to indicate correct guesses. Previously, only colors were being used so users with red-green colorblindness could not play the game.
A Vordle board showing how we added icons to indicate correct guesses. Previously, only colors were being used so users with red-green colorblindness could not play the game.

Link to headingAccessibility tooling for developers

Link to headingHeaded to Next.js Conf?