Insights / Technical notes

Practical Accessibility Improvements for an Astro Site

Prioritize Astro accessibility work around a task users need to complete, such as a contact form.

  • Technology
  • Astro
  • Accessibility
Practical Accessibility Improvements for an Astro Site
Table of contents
  1. Introduction
  2. aria-hidden for Decorative Icons
  3. Solution
  4. Screen Reader Notifications for External Links
  5. Solution
  6. Ensuring Contrast
  7. Common Problem
  8. Solution
  9. focus-visible Styles
  10. Implementation with UnoCSS
  11. Elements Often Overlooked
  12. Underlines on Inline Links
  13. Solution
  14. Form Accessibility
  15. Inline Validation
  16. Required Field Markers
  17. role Attribute on figure Elements
  18. role Attribute on List Elements
  19. Other Improvements
  20. width/height Attributes on Images
  21. aria-live on Hero Slider
  22. aria-labelledby on dialog
  23. aria-current on Pagination
  24. Copy Button aria-label Update
  25. Summary
  26. Part of a Series
  27. Supplement: verify usability when moving to Tailwind CSS v4
  28. October 6, 2026 update: authentication buttons and post-registration guidance

Prioritize Astro accessibility work around a task users need to complete, such as a contact form. Use the keyboard to enter data, correct errors and finish, checking labels and notifications against W3C WAI: Forms Tutorial. Verify task completion separately from the automated scores reported below.

Update, September 26, 2026: The code and PageSpeed Accessibility score of 100 below record the Astro + UnoCSS site in March 2026. The current company site declares Tailwind CSS 4.3.3. These selected checks and an automated score do not establish site-wide WCAG AA conformance. A conformance assessment must define the pages and complete processes in scope and evaluate all Level A and AA success criteria with automated and human testing (W3C conformance requirements).

Introduction

“Accessibility” might seem like something easy to put off. But when you actually work on it, you realize that improving contrast, keyboard navigation, and focus indicators directly enhances usability for every user.

This article introduces the improvements made to achieve a PageSpeed Accessibility score of 100 on an Astro + UnoCSS site, organized by category.


aria-hidden for Decorative Icons

UnoCSS Iconify icons (i-lucide-*) are often used as visual decoration, but when screen readers read them aloud, they announce “image” or “unknown image,” which causes confusion.

Solution

Add aria-hidden="true" to decorative icons.

<span class="i-lucide-mail" aria-hidden="true"></span> Contact

This was applied to over 30 icons across the site. Be careful not to miss icons inside components like StatBar, Callout, ServiceCard, and ProcessFigure.


External links opened with target="_blank" visually indicate they open in a new tab, but this isn’t communicated to screen reader users.

Solution

Add visually hidden supplementary text to external links.

<a href="https://example.com" target="_blank" rel="noopener noreferrer">
  Example
  <span class="sr-only">(opens in a new tab)</span>
</a>

Using the rehype-external-links plugin, target="_blank" and rel can be automatically added to external links in Markdown. The SR notification text is added on the template side.


Ensuring Contrast

Insufficient contrast is the most common issue flagged by PageSpeed Insights.

Common Problem

Using text-slate-400 from UnoCSS’s color palette results in a contrast ratio of about 3:1 against a white background, failing the WCAG AA requirement of 4.5:1.

Solution

Changing text-slate-400 → text-slate-500 (contrast ratio 4.6:1) clears the requirement. This is commonly used for supplementary text like dates and captions, so check across the entire site.


focus-visible Styles

For users who navigate sites with a keyboard, focus indicators are the only way to know “where I am now.” WCAG 2.4.7 requires focus visibility.

Implementation with UnoCSS

Set common focus styles for buttons and links. Using UnoCSS’s shortcut feature, you can define it in one place and apply it everywhere.

shortcuts: {
  'ac-btn': '... focus-visible:ring-2 focus-visible:ring-brand-500 focus-visible:ring-offset-2 focus-visible:outline-none',
}

focus-visible is a pseudo-class that shows the ring only during keyboard navigation, not on mouse clicks. It provides better UX than focus, so use this one.

Elements Often Overlooked

  • Copy buttons
  • Scroll-to-top button
  • Anchor ad close button
  • Modal close buttons

PageSpeed may flag “Links are identifiable only by color.” This is a problem for users with color vision deficiencies who cannot distinguish links.

Solution

Make underlines always visible instead of only on hover. Using UnoCSS shortcuts for consistency is recommended.

shortcuts: {
  'ac-link': 'underline decoration-brand-300 underline-offset-2 hover:decoration-brand-500 transition-colors',
}

Form Accessibility

Accessibility is especially important where users provide input, such as contact forms.

Inline Validation

Display error messages immediately on blur/input events, coordinating with the following aria attributes:

  • aria-invalid="true" — Notifies that the input is invalid
  • aria-describedby — References the error message’s ID
<input type="email" aria-invalid="true" aria-describedby="email-error" />
<p id="email-error" role="alert">Please enter a valid email address</p>

Required Field Markers

A visual * mark alone is insufficient. Add supplementary text for screen readers.

<span aria-hidden="true">*</span> <span class="sr-only">(required)</span>
Connect form labels, operation, and announcements A conceptual reading of the March 2026 examples; automated checks do not establish overall WCAG conformance.
  1. Field and label Give each field a visible label; communicate required status beyond the asterisk.
  2. Keyboard focus Use focus-visible to show the active field and verify keyboard access and editing.
  3. Associated error and announcement aria-invalid and aria-describedby connect field and message; role=alert announces changes. Add manual review.

role Attribute on figure Elements

Setting role="img" on <figure> elements hides child elements from screen readers. For components containing icons and descriptive text (InsightGrid, ProcessFigure, Timeline), change to role="group" to keep internal content accessible.


role Attribute on List Elements

When CSS list-style: none is applied, Safari’s screen reader (VoiceOver) has a known bug where it no longer recognizes the element as a list.

Add role="list" to <ol> / <ul> elements in breadcrumbs, sidebars, and footers. Check all lists with customized appearance.


Other Improvements

width/height Attributes on Images

Images without explicit width and height cause layout shifts (CLS — Cumulative Layout Shift) when loading completes. Specify sizes for all images, including avatars (32×32, 48×48, 64×64px) and YouTube thumbnails (480×360px).

aria-live on Hero Slider

Auto-rotating sliders don’t communicate changes to screen reader users. Prepare an aria-live="polite" region and notify with text like “Slide 1 / 4: [title].”

aria-labelledby on dialog

Reference the title element’s ID with aria-labelledby on <dialog> elements so screen readers can announce the modal’s purpose.

aria-current on Pagination

Set aria-current="page" on the current page number to notify screen readers that it is “the current page.”

Copy Button aria-label Update

When clipboard copy succeeds, dynamically update aria-label to “Copied” to notify screen readers of the state change.


Summary

Accessibility improvements are small individual changes, but together they significantly improve overall site quality. The three most impactful changes were:

  1. Applying focus-visible globally: Dramatically improved keyboard navigation
  2. Fixing contrast ratios: Simply changing text-slate-400 → text-slate-500 cleared WCAG AA
  3. SR notifications for external links: Combined with rehype-external-links for automated coverage of all links

Start by scanning your site with axe DevTools and tackling the automatically detectable issues first.


Part of a Series

This article is part of the “Astro Site Quality Improvement Guide” series. Separate articles cover performance, SEO, and UX improvements as well.

Supplement: verify usability when moving to Tailwind CSS v4

Added September 30, 2026. When moving to Tailwind CSS v4, recheck existing CSS resets versus Preflight, CMS icons, visible focus and reduced-motion behavior in production. Decide whether to disable Preflight according to existing styles, rather than recommending that choice for every site.

Tailwind v4 / Preflight

October 6, 2026 update: authentication buttons and post-registration guidance

The anonymized changes replaced authentication-provider icons with official assets and checked their production display. An accessible name conveying the button’s purpose is a separate verification item. Do not rely on the icon alone; check the button name, keyboard focus, and where to proceed after registration.

Implementation checks of guidance and focus differ from a user actually completing registration. End-to-end registration and screen-reader testing remain unverified in these records; they do not establish conformance across every provider and assistive technology.

Accessibility Improvement Workflow

  1. Automated Testing

    Use axe DevTools and Lighthouse to identify machine-detectable issues.

  2. Manual Testing

    Try navigating with keyboard and screen reader yourself.

  3. Fix

    Add aria attributes, fix contrast, and add focus styles.

  4. Re-test

    Confirm a score of 100 on PageSpeed Accessibility.

Accessibility improvements recorded at the time

  • Text contrast ratio is 4.5:1 or higher (3:1 for large text)
  • All interactive elements have focus-visible styles
  • Decorative icons have aria-hidden="true"
  • External links have screen reader notifications
  • Forms have inline validation with aria-invalid integration
  • Images have width/height attributes (CLS prevention)
  • List elements have role="list" (list-style:none workaround)

Frequently Asked Questions

What's the difference between axe DevTools and Lighthouse?

Lighthouse is a comprehensive audit tool covering performance and SEO as well, checking only a subset of accessibility items. axe DevTools specializes in accessibility and performs more detailed checks with a larger rule set. Using both together is recommended.

Should aria attributes be added to every element?

No. If HTML semantics are correct, aria is unnecessary. Aria attributes are meant to supplement "information that HTML alone cannot convey." Overusing them can make screen reader output overly verbose.

Does a PageSpeed Accessibility score of 100 mean WCAG compliance?

Even a score of 100 doesn't guarantee full WCAG compliance. Lighthouse has limited check items, and some criteria can only be verified manually (logical reading order, appropriate alt text, etc.). Both automated and manual testing are necessary.