How the booking colour contrast check works
A plain-language guide to what this check does inside the booking widgets, what it takes into account, and where it stops. No technical background needed.
What it is and why it exists
Most of a hotel booking page can be checked for color contrast just by looking at the page as it loads. The booking widgets can't — the interesting content only appears after you interact with them:
- The Destination list only appears once you click the destination field.
- The Calendar only appears once you click the check-in or check-out date.
- The Guests & Rooms panel only appears once you click the guests field.
Because those panels are hidden until opened, a normal page scan never sees them, and the text inside them (city names, weekday initials, day numbers, "Adults", "+", "−", "Confirm") was never being measured. This logic exists to close that gap: it opens each booking widget like a real user would, and then measures the colors of what's inside it.
The purpose is simple: make sure a person with low vision can actually read the booking form — not just the marketing text around it.
How it behaves, step by step
For each booking widget it finds on the page, it does the following:
- Finds the widget. It looks for the fields and buttons that open booking panels — destination, dates, guests, room counts — including fields that only show a number ("2") or a date range ("04 Jul – 05 Jul") instead of a word.
- Clears the way. If a cookie banner is covering the form, it dismisses it first.
- Opens the panel. It clicks (or presses Enter on) the field, then waits for the panel to finish appearing. This wait matters: many sites fade their panels in, and measuring too early would read a half-transparent, "still loading" color instead of the real one.
- Measures everything readable inside the panel. It reads each piece of text, works out its color and the color behind it, and compares the two.
- Measures the non-text parts too. Icons, arrows, borders and dividers inside the panel are measured against their background.
- Repeats for hover and keyboard focus. It moves the mouse over the panel's buttons and links, and separately moves keyboard focus through them, and re-measures — but only where the site actually changes colors in those situations, so it doesn't waste time on plain text that never reacts.
- Groups the results and reports. Items that look identical (same color, same background, same text size) are grouped together so you get one finding with examples, not fifty copies of the same problem.
Then it closes the panel and moves on to the next widget.
What it takes into account
The color in front and the color behind
- It reads the text's own color, then works out what is actually behind it. If the text sits on something see-through, it looks further back until it finds a real color.
- If the background is a gradient or an image (for example a red-to-pink button, or a destination row with a photo behind it), it takes a picture of that spot and samples the color actually painted on screen, rather than guessing white.
- If something is painted on top of or behind the text without being its container — a highlight bar behind a selected date, a floating label sitting over an input box — it checks what is really painted at that spot, so the comparison matches what a person sees.
How big and how bold the text is
- Larger text is legally allowed a lower contrast, so size and boldness change the pass mark. Text counts as "large" when it's roughly 24 pixels or bigger, or roughly 19 pixels or bigger and bold.
Whether the element is text or a control
- Words and numbers are judged as text. Icons, arrows, borders and dividers are judged as graphics, which have a lower pass mark.
Whether the item is actually active and visible
- Disabled things are skipped. A greyed-out past date, an exhausted "+" button, a "Delete room" button that can't be used — these are deliberately dimmed to say "not available", and accessibility rules exempt them. It recognises this in several forms: sites that mark them properly, and sites that only signal it through styling.
- Deliberately faded sections are skipped. If a whole area has been dimmed (for example a collapsed row shown at 60% strength), it treats that as an inactive part of the interface rather than a contrast failure.
- But text a site chose to make pale is still reported. If the text itself is styled light grey on white for visual hierarchy, that's a real readability problem and gets reported.
- Invisible text is skipped. Text that exists in the page but isn't shown to sighted people — hidden off-screen, sized to nothing, or provided only for screen readers — is ignored, because reporting it would be a false alarm.
Calendars specifically
- It understands that a selected or in-range date is active even when the calendar's own internal labelling is confusing about it, so a white-on-blue selected check-in date does get measured.
- It includes the parts around the day grid — weekday initials, month arrows, the year, footer notes and legends, and "Close"/"Apply" buttons — because those live just outside the grid and were previously being missed.
- It handles calendars that show two months side by side, and calendars where the day number is glued to a price ("3 From US$101").
Avoiding repetition
- Items that look identical are grouped. It keeps up to about fifteen examples of each identical look, which is enough to catch cases where two items look the same but sit on different backgrounds, without flooding the report.
- If the same item was already reported by another part of the run, it isn't reported twice.
What it actually checks
| What's being looked at | The pass mark | Everyday example |
|---|---|---|
| Normal-size text | 4.5 to 1 | Grey "Adults", "Children", "1 night chosen" on white |
| Large or bold text | 3 to 1 | A pale heading like "Where would you like to go?" |
| Placeholder text in a field | 4.5 to 1 | A faint "City, hotel, area…" hint inside the destination box |
| Icons, arrows, borders, dividers | 3 to 1 | A calendar's next-month arrow, or a "−" button whose shape blends into its background |
| Text while hovered with the mouse | Same as above | A destination row that fades when you hover over it |
| Text while keyboard-focused | Same as above | A calendar day that changes color when you tab to it |
Each finding tells you the widget it came from, the two colors involved, the measured ratio, and where on the page to find it.
Where it stops — restrictions and limitations
It only looks inside the opened panels. This is the single most important limit. If you give the test a specific area of the page to work in, that area is used to decide which widgets to open — it is not the region that gets scanned. Text sitting inside that area but outside an opened panel (the "Search" button, a promo-code box, the page header) is deliberately left to the general page-wide contrast check, so the two tests don't overlap or double-report.
Things it will not report:
- Dropdowns drawn by the operating system. When a site uses a plain system dropdown, Windows, macOS and Android each paint it with their own theme. The colors written in the page are ignored by the device, so measuring them would produce fiction, and a developer couldn't fix it anyway.
- Disabled and unavailable controls, as described above — this is intentional, not an oversight.
- Sections the site has deliberately dimmed as a whole. Whether these should be reported is an open judgement call, not a technical gap.
- Glyphs drawn purely by styling rules rather than being real text — for example a "+" that is generated decoratively. The visible mark and the underlying element can have completely different colors, so measuring it would report the wrong one.
- Icons made of images. These are measured by sampling the picture on screen, so the color given is a close approximation rather than an exact value, and "change this color" isn't a fix that can be applied to an image.
Things it can miss or get approximately right:
- Animated or moving backgrounds. If the color behind the text keeps changing, there is no single correct answer. The reading is taken at one moment in time and is an approximation.
- Semi-transparent text. Where text is partly see-through, the reported color is the blended result as it appears on screen, not the value written in the page.
- Anything that depends on a specific choice. The destination field is filled with one fixed search term, so suggestions that only appear for other searches aren't seen. Similarly, calendars are checked in the state they're in — if a site's failing color only shows up after picking a particular date, that state may not be reached.
- Icons made of characters. A "+" or "−" button built from the actual characters is currently judged as text rather than as a control, so it's reported under the text rule. This is a known classification limitation and will be revisited when the graphics check is extended.
Situations where it won't run at all:
- Sites that block automated browsers. Some sites refuse the test browser at the network level and never serve the real page. Nothing in the checking logic can work around that.
- Widgets built in unusual ways. A few sites construct their panels so that the tool can't reliably tell when they've opened or where their boundary is. On those the widget is reported as "did not open" and its contents aren't measured.
- Panels that vanish or reshape mid-check. Some sites close their panel as soon as focus moves, or rebuild the whole form when a field is touched. There are safeguards that re-open a collapsed panel, but where the page transforms itself entirely the widget can't be audited.
- Very heavy pages. There are time limits per item and per run so one unresponsive panel can't stall the whole test. When a limit is hit that item is skipped rather than measured.
