diff --git a/.changeset/orange-trainers-learn.md b/.changeset/orange-trainers-learn.md
new file mode 100644
index 0000000000..8b6e059bd1
--- /dev/null
+++ b/.changeset/orange-trainers-learn.md
@@ -0,0 +1,5 @@
+---
+"astro": minor
+---
+
+Improves the a11y-missing-content rule and error message for audit feature of dev-overlay. This also fixes an error where this check was falsely reporting accessibility errors.
diff --git a/packages/astro/src/runtime/client/dev-toolbar/apps/audit/a11y.ts b/packages/astro/src/runtime/client/dev-toolbar/apps/audit/a11y.ts
index 5a1fd46938..537b03e00d 100644
--- a/packages/astro/src/runtime/client/dev-toolbar/apps/audit/a11y.ts
+++ b/packages/astro/src/runtime/client/dev-toolbar/apps/audit/a11y.ts
@@ -358,13 +358,72 @@ export const a11y: AuditRuleWithSelector[] = [
},
{
code: 'a11y-missing-content',
- title: 'Missing content on element important for accessibility',
- message: 'Headings and anchors must have content to be accessible.',
+ title: 'Missing content',
+ message:
+ 'Headings and anchors must have an accessible name, which can come from: inner text, aria-label, aria-labelledby, an img with alt property, or an svg with a tag
.',
selector: a11y_required_content.join(','),
match(element: HTMLElement) {
// innerText is used to ignore hidden text
const innerText = element.innerText.trim();
- if (innerText === '') return true;
+ if (innerText !== '') return false;
+
+ // Check for aria-label
+ const ariaLabel = element.getAttribute('aria-label')?.trim();
+ if (ariaLabel && ariaLabel !== '') return false;
+
+ // Check for valid aria-labelledby
+ const ariaLabelledby = element.getAttribute('aria-labelledby')?.trim();
+ if (ariaLabelledby) {
+ const ids = ariaLabelledby.split(' ');
+ for (const id of ids) {
+ const referencedElement = document.getElementById(id);
+ if (referencedElement && referencedElement.innerText.trim() !== '') return false;
+ }
+ }
+
+ // Check for with valid alt attribute
+ const imgElements = element.querySelectorAll('img');
+ for (const img of imgElements) {
+ const altAttribute = img.getAttribute('alt');
+ if (altAttribute && altAttribute.trim() !== '') return false;
+ }
+
+ // Check for