Get contrast ratio from hexadecimal
Available since: @sardine/colour@2.2.0
Description
Calculates the contrast ratio between two colours in hexadecimal format using WCAG 2.1 or WCAG 3.0 standards.
The contrast ratio is a value that measures the perceptual difference in brightness between two colours. It’s crucial for accessibility as it determines the readability of text on backgrounds. A higher contrast ratio indicates greater visual distinction between colours.
Signature
function getContrastRatioFromHex(
colour1: string,
colour2: string,
standard: "WCAG2.1" | "WCAG3.0"
): number;
Parameters
- colour1
string
- The first colour in hexadecimal format (e.g.,#ff0000
,#abc
,#ffffffff
) - colour2
string
- The second colour in hexadecimal format (e.g.,#00ff00
,#def
,#ffffff80
) - standard
"WCAG2.1" | "WCAG3.0"
- The accessibility standard to use for calculation
Return Value
Returns a number
representing the contrast ratio between the two colours, truncated to 3 decimal places. The value ranges from 1 (no contrast) to 21 (maximum contrast).
Supported Hex Formats
The function accepts all standard hexadecimal colour formats:
- 3-digit:
#rgb
(e.g.,#f00
) - 6-digit:
#rrggbb
(e.g.,#ff0000
) - 4-digit:
#rgba
(e.g.,#f00f
) - 8-digit:
#rrggbbaa
(e.g.,#ff0000ff
)
Examples
Basic Usage
import { getContrastRatioFromHex } from "@sardine/colour";
// Black and white - maximum contrast
const maxContrast = getContrastRatioFromHex("#000000", "#ffffff", "WCAG2.1");
console.log(maxContrast); // 21
// Same colours - no contrast
const noContrast = getContrastRatioFromHex("#ffffff", "#ffffff", "WCAG2.1");
console.log(noContrast); // 1
Short Hex Formats
// 3-digit hex colours
const shortHex = getContrastRatioFromHex("#000", "#fff", "WCAG2.1");
console.log(shortHex); // 21
// Mixed formats
const mixed = getContrastRatioFromHex("#f00", "#00ff00", "WCAG2.1");
console.log(mixed); // 2.913
Accessibility Testing
// Testing text readability
const textContrast = getContrastRatioFromHex("#333333", "#ffffff", "WCAG2.1");
console.log(textContrast); // 12.627
// Check if contrast meets WCAG AA standards (4.5:1 for normal text)
if (textContrast >= 4.5) {
console.log("Text passes WCAG AA standards");
}
// Check if contrast meets WCAG AAA standards (7:1 for normal text)
if (textContrast >= 7) {
console.log("Text passes WCAG AAA standards");
}
Alpha Channel Support
// Colours with alpha channels
const alphaContrast = getContrastRatioFromHex(
"#000000ff",
"#ffffff80",
"WCAG2.1"
);
console.log(alphaContrast); // Calculated including alpha values
// 4-digit hex with alpha
const shortAlpha = getContrastRatioFromHex("#000f", "#fff8", "WCAG2.1");
console.log(shortAlpha); // Includes alpha channel calculation
WCAG Standards Comparison
// Compare WCAG 2.1 vs WCAG 3.0
const wcag21 = getContrastRatioFromHex("#777777", "#ffffff", "WCAG2.1");
const wcag30 = getContrastRatioFromHex("#777777", "#ffffff", "WCAG3.0");
console.log(`WCAG 2.1: ${wcag21}`); // 4.478
console.log(`WCAG 3.0: ${wcag30}`); // Slightly different due to calculation refinements
Error Handling
The function will throw an error if invalid hexadecimal values are provided:
try {
getContrastRatioFromHex("invalid", "#ffffff", "WCAG2.1");
} catch (error) {
console.error(error.message);
// "convertHextoRGB expects an valid hexadecimal colour value but got invalid"
}
try {
getContrastRatioFromHex("#ff0000", "not-hex", "WCAG2.1");
} catch (error) {
console.error(error.message);
// "convertHextoRGB expects an valid hexadecimal colour value but got not-hex"
}
WCAG Contrast Guidelines
Understanding contrast ratios for accessibility compliance:
- WCAG AA Normal Text: Minimum 4.5:1 ratio
- WCAG AA Large Text: Minimum 3:1 ratio
- WCAG AAA Normal Text: Minimum 7:1 ratio
- WCAG AAA Large Text: Minimum 4.5:1 ratio
function checkAccessibility(ratio) {
if (ratio >= 7) return "AAA compliant";
if (ratio >= 4.5) return "AA compliant";
if (ratio >= 3) return "AA large text only";
return "Not compliant";
}
const ratio = getContrastRatioFromHex("#666666", "#ffffff", "WCAG2.1");
console.log(checkAccessibility(ratio)); // "AAA compliant"
Interactive Demo
Try the function yourself with our interactive playground: