)
+ // haben kein src. Fallback: umgebender Link, aria-label, oder als letzte
+ // Möglichkeit die class (z.B. bei reinen Icon-Fonts/CSS-Icons ohne jeden
+ // Text). Der instanceIdentifier()-Zähler unterscheidet danach weiterhin
+ // gleich aussehende Duplikate voneinander.
const link = img.closest ? img.closest('a[href]') : null;
if (link && link.href) return `role-img:${link.href}`;
const label = img.getAttribute('aria-label');
if (label) return `role-img:${label}`;
+ if (img.className) return `role-img:class:${img.className}`;
return null;
}
@@ -359,6 +363,7 @@
const labelledBy = resolveIdRefs('aria-labelledby', img);
const hasTitle = img.hasAttribute('title');
const hasLongdesc = img.hasAttribute('longdesc');
+ const isAriaHidden = img.getAttribute('aria-hidden') === 'true';
const hasAccessibleName = hasAriaLabel || describedBy !== null || labelledBy !== null;
const linkPrefix = isInsideLink(img) ? 'Bild in Link: ' : '';
@@ -373,6 +378,14 @@
const isDecorative = altValue.trim().length === 0;
segments = [linkPrefix, { code: `alt="${altValue}"` }, ...extras];
kind = isDecorative ? 'warning' : 'success';
+ } else if (isAriaHidden && !hasAccessibleName) {
+ // aria-hidden="true" entfernt das Element bereits vollständig aus dem
+ // Accessibility-Tree – für Screenreader ist es so, als gäbe es kein
+ // Bild. Das ist eine gültige Alternative zu alt="" bei dekorativen
+ // Elementen (v.a. bei role="img" auf Nicht-
![]()
-Elementen), daher
+ // hier keine Fehlermeldung, sondern dieselbe Einstufung wie alt="".
+ segments = [linkPrefix, { code: 'aria-hidden="true"' }, ...extras];
+ kind = 'warning';
} else if (hasAccessibleName) {
const resolvedName = hasAriaLabel ? img.getAttribute('aria-label') : (labelledBy || describedBy);
segments = [