What test 1321 checks (WCAG 2.5.3 — Label in Name): Test 1321 verifies that an <a> element's visible link text is contained within its accessible name. It is a one-directional substring check: accessibleName.includes(visibleText). It does not check whether a link has a meaningful name at all — a link that is completely nameless is a different problem (WCAG 2.4.4 "Link Purpose", covered by a different test).
Bug (ENG-1722): The engine captured the visible-text side from node.innerText, which omits CSS generated content (a::before { content: "…" } / a::after { content: "…" }). The W3C accessible name computation, however, folds a link's own ::before / ::after content into the accessible name (via cssOP in AccName.js). The two sides therefore diverged, and links decorated with an icon-font glyph, a chevron / arrow, or a "Read more" suffix could be falsely flagged.
Important nuance: the accname calc folds in the link's own pseudo content only when the link has no aria-label / aria-labelledby — an ARIA label short-circuits the computation before the CSS-content step (AccName.js, the if (!hasLabel) gate). So the visible-text side must surface the link's pseudo content under the same condition, otherwise a perfectly accessible icon-only link such as <a aria-label="Home"> (glyph via ::before) would have "★" on the visible side but "Home" as its accname — a false positive.
::before / ::after content around node.innerText, so the substring check sees the same string the accname calc produces.aria-label / aria-labelledby, mirroring the accname calc's !hasLabel gate. A labelled icon-only link (no real text) then exposes no visible text and is correctly treated as not-applicable to 1321.AccName.js drops descendant pseudo content during its top-down walk; surfacing it would add a glyph the accname lacks and flip the check to a false fail.Pre-fix: decorated links falsely flagged (visible text ≠ accname) → Post-fix: both sides see the same pseudo content; only real label-in-name mismatches are flagged.
display:none that uses pseudo content — id="na-hidden-link"Element is not rendered (display:none), so it is excluded from the accessible tree and from test 1321 evaluation. Should not be flagged.
<span class="deco-label">Test 1321 only targets links (<a href>). A plain <span> with a decorative ::before star is not a link and is never evaluated. Should not be flagged.
href, not a link) — id="na-anchor-name"An <a> with no href is not exposed as a link, so 1321 does not apply even though it carries pseudo content. Should not be flagged.
::before) WITH aria-label — id="na-icononly-arialabel"The aria-label="Home" supplies the accessible name and short-circuits the accname calc before the CSS-content step, so the ::before glyph is not in the accname. The fix mirrors that gate, so the visible-text side is empty too — there is no visible link text to compare. The link is not evaluated by 1321 (and not flagged). CORRECT post-fix. (This is the false positive the !hasLabel gate fixes: without it the visible side would be "★" against accname "Home".)
aria-labelledby — id="na-icononly-labelledby"Visible glyph is from ::before only, but aria-labelledby resolves to "Settings" and suppresses the pseudo from the accname. Mirrored on the visible side → no visible link text to compare → not evaluated, not flagged. CORRECT post-fix.
::before icon — id="pass-text-plus-before"No ARIA label, so the accname folds in the ::before star: accName = "★Dashboard". The fix surfaces the same glyph on the visible side: visibleText = "★Dashboard". Substring check holds → not flagged. CORRECT post-fix.
::after chevron — id="pass-text-chevron"accName = "Next page›" (real text + folded chevron); visibleText = "Next page›". The trailing ::after chevron (\203A) appears on both sides → not flagged. CORRECT post-fix.
<img alt> + pseudo decoration — id="pass-img-alt"The name comes from the contained img[alt] ("View profile"), not from an ARIA label, so the ::after chevron is folded into the accname too: accName = "View profile›". The visible text is just the chevron ("›", since img contributes no .innerText), which is contained in the accname → not flagged. CORRECT post-fix.
::after arrow + matching title — id="pass-text-arrow-title"title does not short-circuit the accname calc the way aria-label does, so the name is the real text plus the folded arrow: accName = "Pricing→", visibleText = "Pricing→" → not flagged. CORRECT post-fix.
id="pass-icononly-nolabel"The only "content" is the decorative ::before star and there is no ARIA label, so the glyph is folded into the accname: accName = "★", visibleText = "★". The substring check holds → not flagged by 1321. Note: this link has no meaningful name, which is a real accessibility problem — but that is WCAG 2.4.4 (Link Purpose), a different test. Test 1321 (label-in-name) is not the rule that catches nameless icon links.
::after, no label — id="pass-afteronly-nolabel"The visible "Read more" comes entirely from ::after; with no ARIA label it is folded into the accname: accName = "Read more", visibleText = "Read more" → not flagged by 1321. Whether CSS-generated CTA text is good practice is a separate concern; 1321 only checks that the visible text is in the accname, and here it is.
aria-label="Send message" — id="fail-label-mismatch"visibleText = "Submit"; the aria-label overrides the accname to "Send message". "send message" does not contain "submit" → correctly flagged. Classic WCAG 2.5.3 failure (speech-recognition users say the visible word but it is absent from the name).
::after — id="fail-labelled-pseudo"visibleText = "open menu" (real body text; the ::after chevron is suppressed because an aria-label is present). accName = "close window". "close window" does not contain "open menu" → correctly flagged. Demonstrates that decorative pseudo content does not rescue a genuine label-in-name mismatch.
id="fail-richer-visible"visibleText = "Download annual report"; accName = "Report". The accessible name omits visible words ("download annual") → "report" does not contain "download annual report" → correctly flagged.
::after { content:" Read more" } — id="bug-readmore-suffix"Pre-fix: visible side came from .innerText ("Continue reading the full story") while the accname folded in the ::after suffix, so the two strings diverged and the link could be flagged ❌. Post-fix: the suffix is surfaced on both sides — accName = visibleText = "Continue reading the full storyRead more" → handled ✓ (not flagged).
content glyph + aria-label — id="bug-iconfont-parse"Pre-fix: surfacing the glyph on the visible side while the aria-label-driven accname did not contain it produced a false positive ❌. Post-fix: because the link is labelled, the pseudo is suppressed on the visible side (matching the accname), so there is no visible text to mis-compare → handled ✓ (not flagged). This is the exact case the !hasLabel gate addresses.
::after chevron — id="bug-text-chevron"Pre-fix: visible side "Browse all products" diverged from the accname "Browse all products›" (folded chevron) → false positive ❌. Post-fix: the chevron is surfaced on both sides → handled ✓ (not flagged).
id="rw-social-row"All three glyphs come from ::before. Twitter and Facebook are labelled, so their pseudo is suppressed on both sides → no visible text to compare → not evaluated / not flagged. The GitHub link has no label, so its glyph is folded into both sides equally (accName = visibleText = "⊛") → not flagged by 1321. None are flagged by 1321. Note: the unlabelled GitHub link still lacks a meaningful name — flag that under WCAG 2.4.4, not 1321.
id="rw-article-card"How we made test 1321 robust against CSS generated content.
Read the full articleNo ARIA label, so accName = visibleText = "Read the full article→" (real text + folded arrow). The visible text is contained in the accname → not flagged. CORRECT post-fix.
id="rw-cta-mismatch"A card whose call-to-action has a label that omits the visible words.
View detailsvisibleText = "View details" (the aria-label suppresses the decorative arrow); accName = "More". "more" does not contain "view details" → correctly flagged. A real label-in-name failure that the hardening must still catch.
This page exercises test 1321 (WCAG 2.5.3 — Label in Name) against CSS ::before / ::after generated content on links. After the ENG-1722 hardening:
::before / ::after on the visible side, matching the accname calc (cssOP). Decorated links with real text (icon, chevron, arrow, "Read more") are no longer falsely flagged.aria-label / aria-labelledby supplies the name, the pseudo is suppressed on both sides (the accname's !hasLabel gate), so such a link exposes no visible text and is simply not evaluated by 1321.