Relative luminance calculator
Measure how much light a color gives under the WCAG formula: mid-gray #808080 scores 0.215860500114, on a scale from 0 for black to 1 for white. The RGB channels and their linear values are shown so the figure can be checked. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
Worked example
- Color
- #808080
- Relative luminance
- 0.2158605001
The relative luminance calculator converts an sRGB hex color into the light measurement used by WCAG contrast calculations. It expands shorthand hex when necessary, validates every digit, normalizes the red, green, and blue channels, removes sRGB gamma through the standard piecewise formula, and combines the linear values with the official coefficients. The result ranges from 0 for black to 1 for white. Alongside that final value, the response includes normalized hex, integer RGB channels, and the three linearized channels so that every stage is visible and reproducible.
Enter a precise sRGB color
Provide one color as three or six hexadecimal digits, either with or without the leading number sign. For example, #09C expands to #0099CC before calculation, while 4A90D9 is accepted and normalized to #4A90D9. The calculator deliberately accepts only these unambiguous sRGB hex forms.
It does not guess named colors, parse CSS functions, discard alpha, or silently clamp malformed channel values. Letter case does not affect the calculation, and surrounding whitespace is removed, but internal whitespace, extra digits, unsupported punctuation, and empty values are rejected. The returned RGB object contains integer channels from 0 through 255, providing a quick confirmation of how the source text was interpreted.
This normalization step is especially helpful when callers mix shorthand and full hex notation but need one canonical representation for logs, snapshots, or downstream calculations.
Understand the WCAG calculation
Relative luminance is not the simple average of red, green, and blue, and it is not the lightness component from HSL. Each 8-bit sRGB channel is first divided by 255. A normalized channel at or below 0.04045 is divided by 12.92; a higher channel is transformed with ((channel + 0.055) / 1.055) raised to 2.4.
This removes the sRGB transfer curve and produces linear-light channel values. The calculator then applies the standard coefficients: 0.2126 for red, 0.7152 for green, and 0.0722 for blue. Green receives the greatest weight because human vision is more sensitive to it, while blue receives the least.
The weighted sum is the reported relative luminance, bounded by black at 0 and white at 1. Because all operations and coefficients are fixed, identical valid input always produces identical output without network access, stored state, or model inference.
Use luminance in accessibility workflows
A single relative-luminance value describes one color; it does not by itself declare text accessible. To evaluate contrast, calculate luminance for both foreground and background, identify the lighter value L1 and darker value L2, then use (L1 + 0.05) / (L2 + 0.05). Compare that ratio with the WCAG threshold appropriate to the content, text size, and conformance target.
Keeping luminance as a separate capability is useful when a pipeline already has its own contrast policy, needs to cache normalized color measurements, or wants to inspect intermediate values during debugging. Remember that this calculation assumes opaque sRGB colors. If a design uses transparency, first composite the color against its actual background; passing an alpha-bearing hex value directly is rejected because luminance would otherwise be undefined without that background.
What you can do with it
Inspect design tokens
Calculate and store relative luminance for every opaque sRGB color token before applying a project-specific contrast policy.
Debug contrast calculations
Review normalized RGB and linear-light channels to locate parsing or gamma-correction mistakes in another implementation.
Build accessibility tests
Generate deterministic luminance values for foreground and background colors used in automated WCAG contrast assertions.
FAQ
What range can relative luminance have?
The result ranges from 0 for sRGB black to 1 for sRGB white, inclusive.
Which color formats are accepted?
Three-digit and six-digit sRGB hex colors are accepted, with or without a leading #. Named colors, RGB functions, and alpha values are rejected.
Is relative luminance the same as HSL lightness?
No. WCAG relative luminance linearizes sRGB channels and applies weighted coefficients; HSL lightness uses a different geometric definition.
Can this value alone prove WCAG conformance?
No. Conformance requires a contrast ratio between two colors and the appropriate threshold for the content and target level.
Why is mid-gray #808080 well below half?
Because the sRGB gamma curve is removed first. Each channel of 128 becomes 0.215860500114 in linear light, and since red, green and blue are equal, that is also the luminance.
Related tools
For developers — API access
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.
API endpoint
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.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/color/relative-luminance \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"color":"#4A90D9"}'const res = await fetch("https://api.kit.forhosting.com/color/relative-luminance", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"color": "#4A90D9"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/color/relative-luminance",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"color": "#4A90D9"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/color/relative-luminance", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"color":"#4A90D9"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"color":"#4A90D9"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/color/relative-luminance", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"color": "#4A90D9"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "color.relative_luminance",
"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.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |
Technical notes
Use luminance in accessibility workflows
The API costs $0.002 per item, while the browser execution uses the same deterministic calculation for immediate checks.
Technical questions
What does the API cost?
Each item costs $0.002. The calculation can also run free in the browser.