ForHosting KIT · Images

Is text legible on a background?

Text in #111827 on a white background at 16 px has a contrast ratio of 17.74 and passes AA and AAA, and this check gives that verdict for any pair. Font size and weight decide whether the large-text minimum applies. Free in your browser.

  • Free
  • Runs in your browser
  • No sign-up
  • Your data stays on your device
Use it from WebAPIEmailTelegramApp soon
If you enter
Color
#111827
Background
#ffffff
Size
16
You get
Size unit
Px
Size pt
12
Size px
16
Text scale
normal

Designers and engineers often need a yes-or-no answer to a deceptively simple question: is this text color, at this size, actually legible on that background? A contrast ratio by itself does not decide the case, because Web Content Accessibility Guidelines treat large type more leniently than body copy. This checker takes a text hex color, a background hex color, and a font size, classifies the sample as normal or large using the published eighteen-point or fourteen-point-bold rule, then compares the official relative-luminance contrast ratio against the minimum for the level you asked for.

How size-aware WCAG legibility is decided

Web Content Accessibility Guidelines do not treat every glyph the same. Body copy at sixteen pixels has a stricter contrast duty than a twenty-four-pixel headline, because larger letterforms remain readable at a lower luminance gap. The contrast ratio is the lighter luminance plus 0.05 divided by the darker luminance plus 0.05.

In parallel it converts the supplied size into CSS points, where one point equals four thirds of a pixel, and classifies the sample as large when it is at least eighteen point, or at least fourteen point and marked bold. Large type needs a minimum of three to one for AA and four point five to one for AAA; normal type needs four point five and seven. The requested level selects one of those four floors.

The unrounded ratio is compared to the floor so a displayed 4.50 cannot sneak a 4.499 past AA. Nothing is inferred from CSS, screenshots, or a live page: you name the pair and the size, and you get a reproducible verdict suitable for tickets, design tokens, and automated gates.

Where a size-aware yes-or-no check earns its keep

Product teams meet this question when a brand grey looks elegant in a slide deck but fails as sixteen-pixel body copy on a white card, or when a headline at twenty-four pixels would pass AA while the same pair would fail in a form label. Designers paste a token hex, the surface behind it, and the type size from the scale, then read a single legible flag before locking the pair.

Engineers wire the contract into pull-request checks that block a body-text token when sixteen-pixel regular type drops below 4.5 to 1, while still allowing a hero headline at eighteen point to use the large-text floor of 3 to 1. Marketing teams verify campaign hex codes against the site background at the actual caption size, not at an assumed heading size. On this page the work runs entirely in your browser.

Pair this verdict with a full-page accessibility scanner when you must crawl live markup, and with a standalone contrast-ratio matrix when you want every AA and AAA flag for both scales at once. Use this page when the search intent is specifically whether that text, at that size, is safe on that background.

Body copy versus headline at the same hex pair

Check whether a grey-on-white token that fails at 16px body size still passes as 24px large text before you reuse it on a hero.

CI gates that know the type scale

Fail a pull request when a primary body color at 16px regular drops below AA 4.5:1, while headlines use the large-text floor.

How do I know if text is legible on a background?

Send the text hex, the background hex, and the font size.

What counts as large text?

WCAG large-scale text is at least 18 point, or at least 14 point and bold. This tool converts CSS pixels with 1pt = 4/3 px, so 24px regular and 18.67px bold are large.

What contrast minimum is used?

The requested level (default aa) picks one floor; flags use the unrounded ratio.

What does the text-on-background check cost?

It is free in your browser on this page.

Why can a headline pass while the same colors fail as body text?

Large text has a lower minimum: 3 to 1 for AA instead of 4.5 to 1. A 24-pixel headline counts as large at 18 points, while 16-pixel body copy is normal text and must meet the stricter floor.

Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.

POSThttps://api.kit.forhosting.com/color/safe-on-background

Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, by email and from Telegram — and soon from our app too.

curl -X POST https://api.kit.forhosting.com/color/safe-on-background \
  -H "Authorization: Bearer $KIT_KEY" \
  -H "Content-Type: application/json" \
  -d '{"color":"#111827","background":"#ffffff","size":16}'
{
  "color": "#111827",
  "background": "#ffffff",
  "size": 16
}
{
  "task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
  "type": "color.safe_on_background",
  "status": "queued",
  "_links": {
    "result": "/tasks/tsk_…/result"
  }
}

The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.

Per request$0.002

Published price — no tokens, no invented credits. A failed task is never charged.

max_color_chars32
max_size500
HTTPCodeMeaning
401unauthorizedMissing or invalid API key.
402insufficient_balanceYour balance doesn't cover the task price.
404unknown_typeThat task type doesn't exist.
429rate_limitedToo many requests. Use the webhook instead of polling.

The verdict is a boolean named legible, plus the ratio, the threshold, and the scale class so you can show the arithmetic next to the answer. The same pure function runs free in the browser and on the API at $0.002 per successful call. Invalid hex, a missing size, or a non-positive size fail with invalid_input and are not billed.

How size-aware WCAG legibility is decided

This checker turns that rule into a single boolean. It parses the text color and the background as opaque sRGB hex, linearizes each eight-bit channel with the official piecewise curve, and builds relative luminance with the 0.2126, 0.7152, and 0.0722 weights. The payload then reports legible, the ratio rounded to two decimals, the minimum that was applied, whether the classified scale would pass AA and AAA, and a method tag of wcag_relative_luminance.

Input contract, units, and validation

Both must be #RGB or #RRGGBB, with or without the leading hash, case-insensitive, and no longer than thirty-two characters. Failed validation is not billed. Send a JSON object with three required fields. color is the text hex, also accepted as text_color, foreground, fg, or text. background is the surface hex, also accepted as background_color or bg. Alpha suffixes, rgb() functions, hsl() functions, and named CSS colors are rejected with invalid_input that names the field. size is a positive finite number no greater than five hundred; font_size is an alias. size_unit defaults to px (CSS pixels) and may be set to pt (CSS points). The conversion is exact: eighteen point is twenty-four pixels, and fourteen point is eighteen and two thirds pixels. bold defaults to false and accepts a boolean or the strings true and false; at fourteen point or larger, bold flips the sample into the large-text class. level defaults to aa and must be aa or aaa. On success the response echoes the normalized lowercase hex colors, the size you sent, both size_pt and size_px, bold, text_scale as normal or large, the requested level, minimum_ratio, contrast_ratio, passes_aa, passes_aaa, and the boolean legible. There is no network call, no clock, and no random sample: the same trio of color, background, and size always produces the same verdict in the free browser tool and on the API.

Where a size-aware yes-or-no check earns its keep

QA and accessibility specialists attach the numeric ratio, the classified scale, and the boolean to tickets so developers fix the exact pair and size instead of guessing from a screenshot. Through the API each successful lookup costs $0.002; invalid input is not charged; nothing is stored after the response returns.

Ticket evidence with a yes-or-no verdict

Attach the boolean, the ratio, and the classified scale to an accessibility bug so the fix targets the real size, not a screenshot guess.

Which color formats are accepted?

Hex only: #RGB or #RRGGBB, with or without the leading hash. rgb(), hsl(), named colors, and alpha hex are rejected with invalid_input.

Read the full KIT documentation →