Batch 4 — FAIL fixture

Every check here reads the DOM, the CSSOM, or computed styles. Nothing is clicked, focused, hovered, or modified.

1.3.4 Orientation — Level AA (page-level)

EXPECT: 1 finding

@media (orientation: landscape) { body { display: none } } in the stylesheet above. The page is unusable in one orientation.

The second orientation query on this page only changes flex-direction. It must not be reported — that is the normal, correct use of the feature, and the case exists to catch a check that flags every orientation query it finds.

A layout that reflows by orientation. Legitimate.

2.3.3 Animation from Interactions — Level AAA (page-level)

EXPECT: 1 finding
Hover me — I slide sideways and scale up.

A transform transition on hover and an infinite rotate animation, and no @media (prefers-reduced-motion: reduce) rule anywhere on the page.

This link only changes colour on hover — a transition, but not motion.

The href is real on purpose. The first version used href="#" and the existing link-href-hash check reported it — correctly, but it is noise in a fixture testing four other criteria.

That colour transition must stay silent. 2.3.3 is about movement. A check that treats every transition as motion would report every site on the web, which is the same as reporting nothing.

1.4.8 Visual Presentation — Level AAA (element-level)

Case A — justified text

EXPECT: reported

Justified text stretches the spaces between words to force both edges straight. The uneven gaps form vertical rivers of white space running down the paragraph, which readers with dyslexia lose their place in. WCAG asks for text that is not justified for exactly this reason.

Case B — line-height below 1.5

EXPECT: reported

This paragraph sets line-height to 1.15. Lines sitting this close together make it easy to skip a line or read the same one twice, which matters most to readers with low vision or a reading disability. The criterion asks for at least 1.5 within a paragraph.

Case C — line longer than 80 characters

EXPECT: NOT reported — sub-check dropped

This case was going to be the third of three measurements. It is being dropped, and the reason is worth recording.

Line length can only be measured from rendered width, and device.js picks the scan viewport at random from eight resolutions between 1280 and 2560. The same paragraph is 90 characters wide on one scan and 60 on the next, with nothing about the page having changed.

A customer would see the issue count move on its own between scans. That costs more trust than the sub-criterion is worth, so 1.4.8 will check only the two properties that are viewport-independent: text-align and line-height.

This paragraph is fourteen hundred pixels wide, so a line of it runs well past eighty characters before it wraps. Long measures are hard to track: the eye has to travel a long way back to find the start of the next line, and losing that return sweep means re-reading. The criterion caps a line at eighty characters.

Case D — correct prose

EXPECT: not reported

Left aligned, line-height 1.7, and a measure of about sixty-two characters. This paragraph satisfies all three of the sub-requirements the check reads, and must produce nothing at all.

Case E — short text

EXPECT: not reported

OK

Two characters, in a container that would fail on both measures. Line length and line-height are properties of prose; measuring a label or a button caption produces noise. The check needs a minimum text length, and this case is here to prove it has one.

3.3.1 Error Identification — Level A (element-level)

Case F — aria-invalid with nothing attached

EXPECT: reported

The field is announced as invalid and never says why. A screen-reader user hears "invalid" and nothing else.

Case G — aria-describedby pointing at nothing

EXPECT: NOT reported by our 3.3.1 check

axe already reports this, as aria-valid-attr-value under 4.1.2: "ARIA attribute element ID does not exist on the page". Adding a 3.3.1 finding on the same element would put one input in two sections of the report saying the same thing.

So 3.3.1 covers only case F — aria-invalid="true" with no error mechanism at all, which axe does not report. Same scoping rule that keeps 1.4.11 out of 1.4.3's lane.


An id that does not exist on the page. Present in the markup, absent in the accessibility tree — a check that only looks for the attribute would pass this, and that is what this case is for.

Case H — invalid, with a real message

EXPECT: not reported
Enter a postcode in the format SW1A 1AA.

This is the correct pattern.

Case I — aria-invalid="false"

EXPECT: not reported

Not in an error state. Nothing to identify.


Expected totals

SC Level Findings Must stay silent
1.3.4AA 1 the flex-direction orientation query
1.4.8AAA 2 (A, B) cases C, D, E
2.3.3AAA 1 the colour-only transition
3.3.1A 1 (F) cases G, H, I

Five findings, eight things that must stay silent. It started as seven and six; two cases moved to the silent column after the first scan of this file. Case C because line length depends on a viewport the scanner randomises, and case G because axe already reports it under a different criterion.

Both of those were found by running the fixture rather than by reasoning about it. The silent list is the part worth checking first — a false positive teaches people to close the report.