Kiểm Tra Độ Tương Phản Màu

Kiểm tra tỷ lệ tương phản WCAG AA và AAA giữa màu chữ và màu nền

Thử ví dụ

Màu chữ (nền trước)

Màu nền

Mẫu văn bản lớn (18px đậm)

Mẫu văn bản thường — đây là cách nội dung chính của bạn sẽ hiển thị trên màu nền bạn đã chọn.

Tỷ lệ tương phản

14.63:1

Tuân thủ WCAG

Đạt

Thường AA

Đạt

Thường AAA

Đạt

Lớn AA

Đạt

Lớn AAA

WCAG AAVăn bản thường: 4.5:1, Văn bản lớn (18px+ hoặc 14px đậm): 3:1

WCAG AAAVăn bản thường: 7:1, Văn bản lớn (18px+ hoặc 14px đậm): 4.5:1

Kiểm Tra Độ Tương Phản Màu Là Gì?

Kiểm tra độ tương phản màu đo sự khác biệt về độ sáng giữa màu chữ (thường là văn bản) và màu nền, sau đó biểu thị kết quả dưới dạng tỷ lệ. Tỷ lệ 1:1 nghĩa là hai màu giống hệt nhau; 21:1 là giá trị tối đa, tương ứng với chữ đen trên nền trắng hoặc ngược lại. Hướng dẫn Truy Cập Nội Dung Web (WCAG) do W3C ban hành xác định tỷ lệ tương phản tối thiểu mà văn bản phải đáp ứng để người có thị lực kém hoặc khiếm khuyết về màu sắc có thể đọc được.

Công thức tính tỷ lệ tương phản đến từ WCAG 2.x và dựa trên độ sáng tương đối — một thước đo mức độ sáng mà màu sắc xuất hiện với mắt người. Độ sáng tương đối được tính bằng cách tuyến tính hóa từng kênh sRGB (loại bỏ gamma) và gia trọng các kênh theo hệ số ITU-R BT.709: 0,2126 cho đỏ, 0,7152 cho xanh lá, và 0,0722 cho xanh lam. Xanh lá đóng góp nhiều nhất vì mắt người nhạy cảm nhất với ánh sáng xanh lá. Tỷ lệ được tính là (L1 + 0,05) / (L2 + 0,05), trong đó L1 là độ sáng của màu sáng hơn.

WCAG xác định hai mức tuân thủ. Mức AA yêu cầu tỷ lệ tương phản tối thiểu 4,5:1 cho văn bản cỡ thường và 3:1 cho văn bản lớn (từ 18px trở lên, hoặc 14px đậm). Mức AAA nâng ngưỡng lên 7:1 và 4,5:1 tương ứng. WCAG 2.1 cũng bổ sung Tiêu Chí Thành Công 1.4.11, yêu cầu tỷ lệ 3:1 cho các thành phần giao diện không phải văn bản như đường viền, biểu tượng và chỉ báo tiêu điểm.

Tại Sao Dùng Công Cụ Kiểm Tra Tương Phản Này?

Kiểm tra tương phản bằng mắt thường không đáng tin cậy. Những màu trông rõ ràng trên màn hình được hiệu chỉnh của bạn có thể nhòe lại trên màn hình laptop chất lượng thấp, dưới ánh nắng trực tiếp, hoặc với người bị mù màu deuteranopia. Một tỷ lệ số loại bỏ sự phỏng đoán và cho bạn kết quả đạt/không đạt theo chuẩn WCAG.

Tính Tỷ Lệ Tức Thì
Chọn hoặc nhập hai màu và xem tỷ lệ tương phản cập nhật theo thời gian thực. Không cần gửi form, không cần tải lại trang.
🔒
Xử Lý Ưu Tiên Bảo Mật
Phép tính độ sáng chạy hoàn toàn trong trình duyệt của bạn. Không có giá trị màu nào rời khỏi máy bạn, và không có cookie hay phân tích theo dõi lựa chọn của bạn.
🎯
Kết Quả AA và AAA
Kết quả hiển thị trạng thái đạt/không đạt cho WCAG AA và AAA, cho cả văn bản thường và lớn, giúp bạn biết chính xác ngưỡng nào được đáp ứng.
📋
Không Cần Tài Khoản
Mở trang và bắt đầu kiểm tra ngay. Không cần đăng ký, không giới hạn tần suất. Công cụ hoạt động ngoại tuyến sau khi trang đã tải.

Các Trường Hợp Sử Dụng Công Cụ Kiểm Tra Tương Phản

Phát Triển Frontend
Trước khi triển khai thay đổi giao diện, dán màu chữ và màu nền từ CSS vào công cụ kiểm tra để xác nhận cặp màu đáp ứng WCAG AA. Điều này phát hiện lỗi tương phản trước khi chúng đến giai đoạn review code hoặc kiểm tra tự động.
Bàn Giao Thiết Kế
Nhà thiết kế có thể xác minh rằng mọi cặp màu trong file Figma đều đạt mức WCAG yêu cầu trước khi bàn giao spec cho kỹ sư. Sửa tương phản ở giai đoạn thiết kế rẻ hơn nhiều so với sửa sau khi đã triển khai.
Kiểm Tra Truy Cập
Kỹ sư QA thực hiện kiểm tra WCAG có thể spot-check các tổ hợp màu cụ thể được gắn cờ bởi các công cụ tự động như Lighthouse hoặc axe. Công cụ kiểm tra xác nhận tỷ lệ chính xác và mức nào đạt hoặc không đạt.
Token Hệ Thống Thiết Kế
Khi xác định token màu cho hệ thống thiết kế, hãy kiểm tra từng cặp chữ/nền để đảm bảo bảng màu token đáp ứng tối thiểu AA. Ghi lại tỷ lệ cùng với token để các nhóm downstream tin tưởng vào các lựa chọn đó.
Kiểm Tra Template Email
Các ứng dụng email loại bỏ các tính năng CSS như opacity và chế độ hòa trộn, nên màu sắc thực tế hiển thị có thể khác so với nguồn. Kiểm tra các giá trị chữ và nền cuối cùng đến hộp thư đến để xác minh khả năng đọc.
Học Tiêu Chuẩn Truy Cập
Sinh viên học WCAG có thể thử nghiệm với các cặp màu khác nhau và ngay lập tức thấy tỷ lệ thay đổi như thế nào. Điều chỉnh từng kênh một giúp xây dựng hiểu biết thực tế về cách độ sáng liên quan đến tương phản nhận thức.

Yêu Cầu Tỷ Lệ Tương Phản WCAG

Bảng dưới đây tóm tắt tỷ lệ tương phản tối thiểu theo WCAG 2.1 cho các loại nội dung và mức tuân thủ khác nhau. Văn bản lớn được định nghĩa là từ 18px (24 CSS pixels) trở lên ở trọng lượng thường, hoặc từ 14px (18,66 CSS pixels) trở lên ở trọng lượng đậm.

MứcTỷ lệ tối thiểuÁp dụng choGhi chú
AA Normal text4.5 : 1Body text, paragraphs, labelsMinimum for most UI text
AA Large text3.0 : 1Text >= 18px, or >= 14px boldMinimum for headings
AA UI components3.0 : 1Borders, icons, focus indicatorsNon-text contrast (WCAG 1.4.11)
AAA Normal text7.0 : 1Body text at highest standardEnhanced readability
AAA Large text4.5 : 1Large text at highest standardEnhanced for headings

Giải Thích Độ Sáng, AA và AAA

Phép tính tỷ lệ tương phản có ba giai đoạn: tính độ sáng cho từng màu, suy ra tỷ lệ, và so sánh với ngưỡng WCAG.

Độ Sáng Tương Đối
Một số duy nhất từ 0 (đen) đến 1 (trắng) biểu thị mức độ sáng mà màu sắc xuất hiện. Nó tính đến đường cong gamma sRGB phi tuyến và độ nhạy không đều của mắt người với đỏ, xanh lá và xanh lam. Xanh lá thuần (#00FF00) có độ sáng 0,7152, trong khi xanh lam thuần (#0000FF) chỉ có 0,0722.
WCAG AA
Mức truy cập cơ bản được yêu cầu bởi hầu hết các tiêu chuẩn pháp lý, bao gồm Đạo Luật Truy Cập Châu Âu (EAA) và Mục 508 tại Hoa Kỳ. AA yêu cầu tỷ lệ 4,5:1 cho văn bản thường và 3:1 cho văn bản lớn. Hầu hết các hệ thống thiết kế lấy AA làm mức tối thiểu cho tất cả các phần tử văn bản.
WCAG AAA
Mức nâng cao dành cho nội dung phải được đọc bởi đối tượng rộng nhất có thể, bao gồm người dùng có khiếm thị đáng kể. AAA yêu cầu 7:1 cho văn bản thường và 4,5:1 cho văn bản lớn. Ít trang web nào đạt AAA trên toàn bộ, nhưng nội dung quan trọng như thông báo pháp lý và thông tin y tế thường hướng tới mức này.

Ví Dụ Code

Tính tỷ lệ tương phản WCAG theo chương trình. Mỗi ví dụ triển khai công thức độ sáng tương đối từ WCAG 2.x và phép tính tỷ lệ tương phản. Cùng một cặp màu đen-trên-trắng và indigo-trên-trắng được kiểm tra để so sánh.

JavaScript
// Calculate relative luminance per WCAG 2.x (sRGB)
function luminance(r, g, b) {
  const [rs, gs, bs] = [r, g, b].map(c => {
    c /= 255
    return c <= 0.04045 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4)
  })
  return 0.2126 * rs + 0.7152 * gs + 0.0722 * bs
}

// Contrast ratio between two RGB colors
function contrastRatio(fg, bg) {
  const l1 = luminance(...fg)
  const l2 = luminance(...bg)
  const lighter = Math.max(l1, l2)
  const darker  = Math.min(l1, l2)
  return (lighter + 0.05) / (darker + 0.05)
}

contrastRatio([0, 0, 0], [255, 255, 255])  // -> 21.0
contrastRatio([99, 102, 241], [255, 255, 255]) // -> 3.95
contrastRatio([29, 78, 216], [255, 255, 255])  // -> 6.06 (AA pass)
Python
def luminance(r: int, g: int, b: int) -> float:
    """Relative luminance per WCAG 2.x, ITU-R BT.709 coefficients."""
    channels = []
    for c in (r, g, b):
        c /= 255
        channels.append(c / 12.92 if c <= 0.04045 else ((c + 0.055) / 1.055) ** 2.4)
    return 0.2126 * channels[0] + 0.7152 * channels[1] + 0.0722 * channels[2]

def contrast_ratio(fg: tuple, bg: tuple) -> float:
    l1 = luminance(*fg)
    l2 = luminance(*bg)
    lighter, darker = max(l1, l2), min(l1, l2)
    return (lighter + 0.05) / (darker + 0.05)

print(f"{contrast_ratio((0, 0, 0), (255, 255, 255)):.2f}")  # -> 21.00
print(f"{contrast_ratio((99, 102, 241), (255, 255, 255)):.2f}")  # -> 3.95

# Check WCAG AA for normal text
ratio = contrast_ratio((29, 78, 216), (255, 255, 255))
print(f"{ratio:.2f} — {'AA pass' if ratio >= 4.5 else 'AA fail'}")  # -> 6.06 — AA pass
Go
package main

import (
	"fmt"
	"math"
)

func linearize(c float64) float64 {
	c /= 255
	if c <= 0.04045 {
		return c / 12.92
	}
	return math.Pow((c+0.055)/1.055, 2.4)
}

func luminance(r, g, b int) float64 {
	return 0.2126*linearize(float64(r)) +
		0.7152*linearize(float64(g)) +
		0.0722*linearize(float64(b))
}

func contrastRatio(fgR, fgG, fgB, bgR, bgG, bgB int) float64 {
	l1 := luminance(fgR, fgG, fgB)
	l2 := luminance(bgR, bgG, bgB)
	lighter := math.Max(l1, l2)
	darker := math.Min(l1, l2)
	return (lighter + 0.05) / (darker + 0.05)
}

func main() {
	ratio := contrastRatio(0, 0, 0, 255, 255, 255)
	fmt.Printf("%.2f\n", ratio) // -> 21.00

	ratio = contrastRatio(29, 78, 216, 255, 255, 255)
	fmt.Printf("%.2f\n", ratio) // -> 6.06 (AA pass for normal text)
}
CSS
/* WCAG-safe color pairs — tested contrast ratios */

/* 12.63:1 — passes AAA normal text */
.high-contrast {
  color: #1e293b;          /* slate-800 */
  background: #f8fafc;     /* slate-50  */
}

/* 7.07:1 — passes AAA normal text */
.dark-theme-text {
  color: #e2e8f0;          /* slate-200 */
  background: #0f172a;     /* slate-900 */
}

/* 4.57:1 — passes AA normal, fails AAA */
.accent-on-white {
  color: #1d4ed8;          /* blue-700  */
  background: #ffffff;
}

/* 2.14:1 — fails AA for text, but passes 3:1 for large text */
.muted-heading {
  color: #94a3b8;          /* slate-400 */
  background: #ffffff;
}

Câu Hỏi Thường Gặp

Tỷ lệ tương phản tốt cho văn bản là bao nhiêu?
Với văn bản nội dung trên web, hãy đặt mục tiêu ít nhất 4,5:1 (WCAG AA). Tỷ lệ trên 7:1 đáp ứng WCAG AAA và thoải mái hơn khi đọc lâu dài. Chữ đen trên nền trắng cho tỷ lệ tối đa 21:1, nhưng màu xám rất tối (#1e293b) trên trắng vẫn đạt khoảng 12,6:1, vượt xa AAA.
Văn bản lớn trong WCAG được định nghĩa như thế nào?
WCAG định nghĩa văn bản lớn là 18px (24 CSS pixels) ở trọng lượng thường, hoặc 14px (18,66 CSS pixels) ở trọng lượng đậm. Văn bản lớn có ngưỡng tương phản thấp hơn vì chữ to hơn dễ nhận thấy hơn. Trong CSS, 1px bằng 0,75pt, nên 18pt bằng 24px.
WCAG AA có yêu cầu bắt buộc về mặt pháp lý không?
Tại nhiều quốc gia, có. Đạo Luật Truy Cập Châu Âu (EAA), có hiệu lực từ tháng 6/2025, tham chiếu WCAG 2.1 AA. Mục 508 của Đạo Luật Phục Hồi Chức Năng Hoa Kỳ yêu cầu các cơ quan liên bang đáp ứng WCAG 2.0 AA. Đạo Luật Người Khuyết Tật Hoa Kỳ (ADA) đã được tòa án Hoa Kỳ giải thích là yêu cầu website truy cập được, với WCAG AA là tiêu chuẩn. Canada, Úc và Anh có các quy định tương tự.
Độ sáng tương đối được tính như thế nào?
Mỗi giá trị kênh sRGB (0-255) được chia cho 255, sau đó tuyến tính hóa: các giá trị từ 0,04045 trở xuống được chia cho 12,92, và các giá trị trên đó được biến đổi bằng ((c + 0,055) / 1,055) ^ 2,4. Ba kênh đã tuyến tính hóa được gia trọng theo hệ số ITU-R BT.709 (0,2126 R, 0,7152 G, 0,0722 B) và cộng lại. Kết quả là một số từ 0 đến 1.
Tại sao WCAG dùng offset 0,05 trong công thức tương phản?
Offset 0,05 ngăn phép chia cho 0 khi một trong hai màu là đen thuần (độ sáng = 0). Nó cũng tính đến ánh sáng môi trường và phản chiếu màn hình, làm tăng nhẹ độ sáng cảm nhận ngay cả của các điểm ảnh tối nhất. Không có offset này, chữ đen trên bất kỳ màu tối nào cũng sẽ cho tỷ lệ vô hạn hoặc cao một cách đánh lừa.
Hai màu có thể đạt AA nhưng vẫn khó đọc không?
Có. Tỷ lệ tương phản WCAG đo sự khác biệt về độ sáng, không phải sự khác biệt về màu sắc. Màu đỏ bão hòa trên xanh lá bão hòa có thể kỹ thuật đạt ngưỡng tỷ lệ nhưng vẫn gây khó chịu khi đọc với một số người, đặc biệt là người bị mù màu đỏ-xanh lá. Ghép các màu khác nhau cả về độ sáng lẫn màu sắc thường cho kết quả thoải mái hơn.
Sự khác biệt giữa tương phản WCAG 2.x và APCA là gì?
WCAG 2.x sử dụng tỷ lệ độ sáng đơn giản, coi chữ và nền đối xứng nhau. APCA (Advanced Perceptual Contrast Algorithm), được đề xuất cho WCAG 3.0, sử dụng mô hình độ sáng nhận thức tính đến cực tính: chữ tối trên nền sáng có tương phản nhận thức khác với chữ sáng trên nền tối ở cùng một sự khác biệt độ sáng. APCA vẫn là bản nháp và chưa thay thế phương pháp WCAG 2.x trong bất kỳ quy định nào.