Đang tải…
Đang tải…
amber-500 và indigo-500 cùng một bậc trên bảng màu. Đo ra thì độ sáng của chúng lệch nhau 0,27. Đó là lý do một hàng icon nhiều màu trông như nhiễu.

Bảy module trên site này mỗi cái một màu nhận diện. Chúng xếp cạnh nhau trong dropdown của navbar, trong dock ở mobile, trong command palette. Mình lấy màu từ thang -500 của Tailwind, vì đó là việc ai cũng làm.
Kết quả trông không giống một hệ thống. Icon amber gần như biến mất trên nền sáng, còn icon indigo thì đậm và nặng. Cùng một bậc số, cùng một hàng, hai sức nặng thị giác khác hẳn nhau.
Bậc trong thang màu của Tailwind là một quy ước đặt tên, không phải một phép đo. Đưa chúng về không gian màu OKLCH, nơi trục đầu tiên là độ sáng cảm nhận được, thì khoảng cách hiện ra ngay:
amber-500 L 0.86
indigo-500 L 0.59
violet-500 L 0.54
Chênh 0,32 giữa hai đầu. Đó không phải sai sót của Tailwind: vàng vốn sáng hơn tím ở cùng độ bão hoà, và thang màu này được dựng để mỗi họ màu tự nó chuyển bậc đẹp mắt, chứ không phải để các họ khác nhau ngang nhau khi đứng cạnh.
Vấn đề chỉ nảy sinh khi bạn dùng bậc số như thể nó là một mặt phẳng chung. Một lưới trộn amber với indigo đọc ra thành nhiễu, và đó là tín hiệu "ghép từ giá trị mặc định" lớn nhất của cả site.
Những icon này là chỉ dấu mang nghĩa, nên ngưỡng tương phản cần đạt là 3:1. Đo trên nền sáng:
amber 2.02 : 1
emerald 2.32 : 1
Cả hai đều trượt. Không phải trượt sát nút, mà chưa tới hai phần ba ngưỡng. Với phần chữ eyebrow viết hoa nhỏ dùng chung màu đó, ngưỡng còn cao hơn: 4,5:1.
Cách sửa là dựng lại cả mười bảy màu trên một mặt phẳng: khoá độ sáng và độ bão hoà theo từng theme, và chỉ để góc màu chạy.
:root {
--cat-l: 0.52;
--cat-amber: oklch(var(--cat-l) 0.11 70); /* AA 5.33 */
--cat-emerald: oklch(var(--cat-l) 0.111 162); /* AA 4.91 */
--cat-indigo: oklch(var(--cat-l) 0.15 272); /* AA 5.39 */
}
.dark {
--cat-l: 0.74;
}
Hai biến điều chỉnh cả bộ. Nền tối đọc trên nền 0.12 thay vì 0.98, nên mặt phẳng dịch lên 0.74. Màu tệ nhất trong bộ giờ là green ở 4,88 trên nền sáng và pink ở 7,35 trên nền tối. Toàn bộ đều vượt AA, và không màu nào át màu nào.
Chi tiết này nghe ngược đời. Nếu khoá độ sáng để mọi thứ ngang nhau, sao không khoá luôn độ bão hoà?
Vì làm vậy sẽ ghìm cả bộ xuống mức của màu yếu nhất. sRGB không có vàng tối mà đậm màu; ép mọi màu xuống trần của vàng ở độ sáng này sẽ kéo cả bộ về C 0.085 và làm nửa rực rỡ hoá ra xỉn. Cho nên mỗi màu được đẩy tới sát biên gamut sRGB của riêng nó, nhân 0,97 lấy khoảng an toàn, rồi chặn trần ở 0.15.
Trần đó có lý do riêng: không màu phân loại nào được phép rực hơn màu nhấn thương hiệu, thứ duy nhất trên site được quyền to tiếng.
Bạn có thể viết một giá trị oklch() nằm ngoài gamut và để engine tự xử. Mình không làm vậy, vì các engine không thống nhất cách xử.
Một số giảm độ bão hoà và giữ nguyên độ sáng, đúng như CSS Color 4 mô tả. Một số cắt theo từng kênh, và cắt kênh thì làm độ sáng dịch đi. Nghĩa là bạn vừa bỏ công cố định độ sáng, rồi trả nó lại cho một chi tiết triển khai của trình duyệt quyết định. Viết ra con số đã đo là cách giữ lời hứa ban đầu.
Một dòng khác cũng đáng chép lại: mỗi giá trị trong file đó có comment ghi tỉ số tương phản của nó với nền xấu hơn trong hai nền. Không phải để trang trí. Nếu ai đó chỉnh --cat-l, mọi con số ấy sai hết, và comment là thứ duy nhất nói cho họ biết cần đo lại.
Chưa có bình luận nào — hãy là người đầu tiên!