Bhinish Dhiman
Pasang pengecekan kontras warna di CI agar build gagal
Diterjemahkan dari versi asli berbahasa Inggris. Baca versi asli
Tuliskan token warna Anda ke dalam tes yang menguji setiap pasangan teks di atas permukaan terhadap kebutuhan kontrasnya, lalu jalankan di CI. Perubahan token yang merusak kontras akan menggagalkan build seperti regresi lainnya, alih-alih terlanjur dirilis dan menunggu audit.
Kontras diperiksa ketika ada yang ingat untuk memeriksanya. Itulah inti masalahnya. Pemeriksaan ini adalah langkah manual di akhir proses, ia bersaing dengan tenggat, dan ia kalah.
Solusinya adalah menjadikannya assertion otomatis, cara yang sama untuk menangani setiap jenis regresi lainnya.
Mengapa review manual gagal
Terjadi terlalu terlambat. Kontras biasanya ditinjau menjelang akhir, ketika warna sudah menjadi tumpuan dan mengubahnya berarti membuka kembali keputusan yang sudah final.
Tidak bertahan saat refactor. Seseorang menggeser abu-abu satu langkah lebih terang di file token, enam bulan setelah audit, dan tidak ada yang menangkapnya.
Tidak ikut berkembang seiring tema. Terang dan gelap menggandakan cakupan, dan sisi gelap adalah tempat WCAG 2 paling tidak bisa dipercaya.
Tidak ada yang memeriksa ulang sistem desain. Satu token dengan kontras kurang menyebar ke setiap produk yang memakainya.
Masing-masing adalah ciri dari sesuatu yang seharusnya menjadi tes.
Apa yang perlu diuji
Bukan semua pasangan yang mungkin, melainkan pasangan yang benar-benar Anda rilis. Untuk kebanyakan sistem, daftarnya pendek:
- Teks isi di atas latar halaman
- Teks isi di atas kartu atau permukaan yang ditinggikan
- Teks redup atau sekunder di atas keduanya
- Warna tautan di atas keduanya
- Label tombol di atas latar tombol, untuk setiap varian
- Warna border di atas latar sekitarnya, jika border itu menandai sebuah kontrol
Kalikan dengan jumlah tema. Dua belas sampai dua puluh assertion sudah mencakup sebagian besar sistem desain.
Contoh lengkap
import { describe, expect, it } from 'vitest';
import { contrastRatio } from './wcag';
const LIGHT = {
ink: '#10141c',
inkSoft: '#2a313d',
muted: '#5a6473',
paper: '#f7f8fa',
card: '#ffffff',
accent: '#006ad5',
};
const PAIRS = [
{ name: 'body on paper', fg: LIGHT.inkSoft, bg: LIGHT.paper, required: 4.5 },
{ name: 'body on card', fg: LIGHT.inkSoft, bg: LIGHT.card, required: 4.5 },
{ name: 'muted on paper', fg: LIGHT.muted, bg: LIGHT.paper, required: 4.5 },
{ name: 'heading on paper', fg: LIGHT.ink, bg: LIGHT.paper, required: 3 },
{ name: 'button label', fg: '#ffffff', bg: LIGHT.accent, required: 4.5 },
];
describe('design tokens pass contrast', () => {
for (const p of PAIRS) {
it(`${p.name} clears ${p.required}:1`, () => {
const ratio = contrastRatio(p.fg, p.bg);
expect(ratio, `${p.name}: got ${ratio.toFixed(2)}:1`).toBeGreaterThanOrEqual(p.required);
});
}
});
Pesan kegagalan itu penting. expected 4.21 to be greater than or equal to 4.5 membuat orang harus berburu penyebabnya. muted on paper: got 4.21:1 memberi tahu mereka persis token mana yang harus diubah.
Tambahkan assertion APCA untuk semua yang berukuran kecil
WCAG 2 tidak bisa melihat tipografi, jadi rasio yang lolos pada label 12px bukanlah bukti. Jika Anda peduli pada pengalaman membaca, bukan hanya angka kepatuhan, uji APCA juga, dan terapkan ambang yang berbeda untuk peran teks yang berbeda.
APCA meminta Lc 90 untuk kolom teks isi dan Lc 60 untuk konten dan subjudul. Menerapkan ambang teks isi pada label 13px akan memaksanya mendekati hitam dan meruntuhkan hierarki Anda, yang tidak membantu siapa pun. Ujilah standar yang benar-benar berlaku untuk setiap peran.
Apa yang kami temukan saat melakukannya
Kami menambahkan ini ke situs kami sendiri setelah membangun alatnya, dan mengira hasilnya akan lolos. Ternyata ditemukan tujuh kegagalan APCA pada elemen antarmuka (chrome) yang lolos WCAG 2 di mana-mana. Yang terburuk adalah warna tautan dark mode kami di Lc 37 terhadap kebutuhan 75: benar-benar sulit dibaca, dan tidak terlihat oleh setiap pemeriksaan berbasis rasio.
Dua perbaikannya bersifat tipografis, bukan soal warna. Label 11px kami tidak bisa lolos di kontras berapa pun, jadi diubah menjadi 13px dengan ketebalan 500. Label tombol kami tidak bisa lolos dengan putih di atas warna aksen pada 15px, jadi diubah menjadi 17px dengan ketebalan 600.
Tidak satu pun dari perbaikan itu akan Anda temukan dengan menggeser-geser nilai hex.
Menurunkan perbaikan alih-alih menebak
Saat sebuah assertion gagal, godaannya adalah menggelapkan warna sampai lolos. Begitulah palet lama-lama menjadi keruh.
Lebih baik hitung perubahan minimumnya: kunci hue dan kroma, lalu cari di sumbu kecerahan nilai terdekat yang melewati ambang. Anda mendapat perubahan visual terkecil yang menyelesaikan masalah, bukan perubahan sembarang, dan warnanya tetap mudah dikenali sebagai dirinya sendiri.
Kami menghasilkan setiap nilai koreksi di palet kami sendiri dengan cara ini, bukan memilih dengan perkiraan mata. Beberapa perubahannya di bawah ΔE 1: tidak terlihat oleh mata, tetapi menjadi pembeda antara gagal dan lolos.
Sisi budayanya
Alasan cara ini berhasil bukanlah alasan teknis. Build yang gagal adalah sinyal bersama yang tidak ambigu, sedangkan review aksesibilitas adalah opini satu orang yang bersaing dengan tanggal rilis.
Begitu kontras menjadi tes, tidak ada yang perlu memperjuangkannya. Hasilnya merah, dan yang merah pasti diperbaiki.
Pemeriksa kontras kami adalah bagian interaktifnya: saat sebuah tes gagal, alat ini memberi Anda warna terdekat yang lolos untuk ditempelkan kembali ke file token.