Mert Özen Her Satırda Daha İleri
Frontend Accessibility (a11y) — #01

Accessibility Nedir ve Neden Zorunlu? WCAG 2.2, POUR, A/AA/AAA ve Türkiye ile AB'deki Yükümlülükler

Mert Özen 15 Kas 2026 15 dk 4 görüntülenme
Accessibility Nedir ve Neden Zorunlu? WCAG 2.2, POUR, A/AA/AAA ve Türkiye ile AB'deki Yükümlülükler

Accessibility, bir ürünün engeli olan insanlar dahil herkes tarafından kullanılabilmesidir ve bugün Türkiye'de 2025/10 sayılı Genelge, AB'de European Accessibility Act ile hukuki bir yükümlülük; ikisinin de teknik ölçütü pratikte WCAG 2.2 AA. WCAG'in POUR, guideline, success criterion ve seviye yapısını, 2.2'deki değişiklikleri ve Genelge ile EAA'nın geliştiriciye etkisini anlatıyor; Bookstore için seri boyunca kullanacağımız lab'ı kurup ilk axe taramasını yapıyoruz.

Sürüm notu: Bu yazı WCAG'in (Web Content Accessibility Guidelines; web içeriği için accessibility kılavuzu) 2.2 sürümünün 12 Aralık 2024 tarihli güncel metnine ve mevzuatın Kasım 2026 durumuna göre yazıldı; lab Angular 22.2 (TypeScript 6.0), Node.js 24, Playwright 1.65 (Chromium 158) ve axe-core 4.14 ile denenmiştir. Mevzuat bölümleri hukuki görüş değildir.

Önce Tahmin Et

Sitedeki serilerin ortak örnek uygulaması Bookstore (bir online kitapçı), üç sayfalık bir Angular istemcisiyle geliyor: katalog, kitap detayı ve sepet. Kod temiz, HTML'in büyük kısmı semantic: header, nav, main, gerçek button'lar, sepet için gerçek bir table. Bu üç sayfayı otomatik accessibility test aracı axe-core ile WCAG 2.2 AA (üç uyum seviyesinin ortadakisi) kurallarına göre tarayacağız.

Kaç ihlal çıkar: sıfır mı, beş mi, yirmi mi? İkinci soru daha önemli: çıkan sayı, Bookstore'u screen reader ya da yalnız klavye kullanan biri için ne kadar kullanılabilir yapar? Cevabı lab'ı kurduktan sonra vereceğiz. Önce accessibility'nin kimin için olduğunu ve "zorunlu" kelimesinin bugün Türkiye'de ve AB'de (Avrupa Birliği) geliştiriciye neye karşılık geldiğini netleştirelim.

Accessibility Kimin İçin?

Accessibility (kısaca a11y: baştaki "a" ile sondaki "y" arasında 11 harf var), bir ürünün engeli olan insanlar dahil herkes tarafından kullanılabilmesi demek. Dünya Sağlık Örgütü'nün (WHO) Mart 2023 tarihli verisine göre dünyada yaklaşık 1,3 milyar insan, yani her altı kişiden biri önemli bir engellilikle yaşıyor. Bu insanlar web'i assistive technology (yardımcı teknoloji: engelli kullanıcının cihazı kullanmasını sağlayan yazılım ve donanım) ile kullanıyor ve bu araçların çalışması büyük ölçüde bizim koda bağlı:

  • Görme: körlük, az görme, renk körlüğü. Screen reader (ekrandaki içeriği sesli okuyan ya da braille ekrana aktaran yazılım), ekran büyütme, tarayıcı zoom'u, yüksek contrast tema.
  • İşitme: video ve ses içeriği için altyazı ve transkript; bildirimin yalnız sesle verilmemesi.
  • Motor: titreme, felç, tek el kullanımı. Yalnız klavye, switch cihazları (tek tuşla tarama yapan donanım), sesle kontrol (Windows Voice Access, macOS Voice Control), göz takibi.
  • Bilişsel ve öğrenme: dikkat, hafıza, disleksi. Sade dil, tutarlı navigation, süre baskısı olmaması, hatayı önleyen ve düzeltmeyi kolaylaştıran formlar.

Engellilik yalnız kalıcı bir durum değil. Microsoft'un Inclusive Design rehberi bunu üç katmanla anlatır: kalıcı (tek kolu olmayan biri), geçici (bileği kırık biri) ve durumsal (kucağında bebek olan biri). Üçü de telefonu tek elle kullanmak zorunda. Güneş altında telefona bakan kullanıcı düşük contrast'tan, yaşı ilerleyen herkes küçük tıklama alanlarından etkilenir; accessibility için yazdığın kod hepsine yarar.

Seri boyunca Bookstore'u dört kullanıcı senaryosuyla test edeceğiz: NVDA (Windows için ücretsiz ve açık kaynak bir screen reader) ile kitap arayan bir screen reader kullanıcısı, mouse kullanamadığı için her şeyi Tab ve Enter ile yapan biri, sayfayı %200 zoom'la okuyan az gören bir kullanıcı ve "Click Add to cart" diyerek sesle gezinen biri. Her biri koddan farklı bir şey bekliyor: doğru adlar, mantıklı bir focus sırası, büyütülünce bozulmayan bir layout ve görünen yazıyla aynı adı taşıyan butonlar.

Lab'ı Kurmak: Bookstore Kopyası, Mock API ve İlk Tarama

Serinin kodu üç klasörlük küçük bir lab. web/bookstore-web, referans Bookstore'un Angular 22 istemcisinin değiştirilmemiş kopyası; seri boyunca düzeltmeleri burada yapacağız. mock-api/server.mjs, Bookstore.Api'nin aynı route'larını aynı JSON şekilleriyle bellekte cevaplayan, bağımlılığı olmayan küçük bir Node.js sunucusu; seed'deki 20 klasik kitabı ve stok değerlerini (Don Quixote tükenmiş, War and Peace'ten 3 adet) aynen taşıyor ve build edilmiş Angular uygulamasını da aynı adresten sunuyor. Accessibility testinde backend'den tek beklentimiz doğru JSON, bu yüzden SQL Server'a gerek yok. a11y/ ise test araçları: Playwright, @axe-core/playwright ve ileride kullanacağımız Lighthouse.

Lab'ın kendi Git repo'su var, her yazı bir commit; Bookstore reposunda bu seri series/accessibility-a11y branch'i, her yazı accessibility-a11y/NN tag'i. Sunucu 5080'deki Bookstore.Api ile çakışmasın diye varsayılan olarak 127.0.0.1:52411'i dinliyor. Windows'ta PowerShell ile:

cd web/bookstore-web
npm ci
npx ng build
cd ../..
node mock-api/server.mjs
Bookstore mock API on http://127.0.0.1:52411

İkinci bir terminalde test araçlarını kuruyoruz. Playwright'ın kurulumu ve locator'ları Integration ve E2E (uçtan uca) Test serisinin "Playwright'a Giriş" yazısında; burada yalnız tarayıcıyı indiriyoruz:

cd a11y
npm ci
npx playwright install chromium
node scan.mjs

Script'lerin ortak kısmı lib.mjs'te: test edilecek sayfalar ve her sayfanın hazır olduğunu anlamak için beklenecek element. Sepet sayfası boşken tablo yok, o yüzden önce katalogdan bir kitap ekleniyor:

// Lab script'lerinin ortak kısmı: adres ve test edilecek Bookstore sayfaları
export const base = process.env.BOOKSTORE_URL ?? 'http://127.0.0.1:52411';

export const pages = {
  catalog: { path: '/', ready: '.book-card' },
  book: { path: '/books/9780441172719', ready: 'h1' },
  cart: { path: '/cart', ready: 'table', async setup(page) {
    // Sepet boş olmasın: önce katalogdaki ilk kitabı (1984) ekle
    await page.goto(base + '/');
    await page.locator('.book-card').first().getByRole('button', { name: /Add to cart/ }).click();
    await page.getByTestId('cart-link').filter({ hasText: '(1)' }).waitFor();
  } },
};

export async function open(page, name) {
  const p = pages[name];
  await p.setup?.(page);
  await page.goto(base + p.path);
  await page.locator(p.ready).first().waitFor();
  return p;
}

Tarama script'i her sayfada axe'ı iki kez çalıştırıyor: bir kez yalnız WCAG 2.0, 2.1 ve 2.2'nin A ve AA kurallarıyla, bir kez de varsayılan ayarla. İkincide çıkıp birincide olmayanlar axe'ın "best practice" kuralları, yani WCAG'de bir kritere bağlı olmayan ama Deque'nin önerdiği kontroller. Her ihlalin tag'lerinden ilgili success criterion numarasını da çıkarıyoruz:

// Bookstore sayfalarını axe-core ile tarar, ihlalleri sayfa sayfa yazdırır
// Kullanım: node scan.mjs   (BOOKSTORE_URL varsayılanı http://127.0.0.1:52411)
import { chromium } from 'playwright';
import { AxeBuilder } from '@axe-core/playwright';
import { open, pages } from './lib.mjs';

const wcagTags = ['wcag2a', 'wcag2aa', 'wcag21a', 'wcag21aa', 'wcag22aa'];
const browser = await chromium.launch();
// AxeBuilder bir browser context ister; browser.newPage() ile açılan sayfada hata verir
const page = await (await browser.newContext()).newPage();
let total = 0;
for (const name of Object.keys(pages)) {
  const { path } = await open(page, name);
  const wcag = await new AxeBuilder({ page }).withTags(wcagTags).analyze();
  const all = await new AxeBuilder({ page }).analyze();
  const bestPractice = all.violations.filter(v => !v.tags.some(t => wcagTags.includes(t)));
  console.log(`--- ${name} (${path})`);
  for (const v of wcag.violations) {
    const sc = v.tags.filter(t => /^wcag\d{3,4}$/.test(t)).map(t => `${t[4]}.${t[5]}.${t.slice(6)}`).join(',');
    console.log(`  WCAG ${v.id.padEnd(20)} ${v.impact.padEnd(9)} SC ${sc.padEnd(7)} nodes=${v.nodes.length}`);
  }
  for (const v of bestPractice) {
    console.log(`  BP   ${v.id.padEnd(20)} ${v.impact.padEnd(9)} ${''.padEnd(10)} nodes=${v.nodes.length}`);
  }
  console.log(`  passed rules=${wcag.passes.length}`);
  total += wcag.violations.length;
}
console.log(`axe-core ${(await new AxeBuilder({ page }).analyze()).testEngine.version}, WCAG violations: ${total}`);
await browser.close();
--- catalog (/)
  BP   page-has-heading-one moderate             nodes=1
  passed rules=21
--- book (/books/9780441172719)
  passed rules=13
--- cart (/cart)
  WCAG label                critical  SC 4.1.2   nodes=1
  BP   empty-table-header   minor                nodes=1
  passed rules=15
axe-core 4.14.0, WCAG violations: 1

Taramanın Söyledikleri ve Söylemedikleri

Tahmin sorusunun cevabı: üç sayfada tek bir WCAG ihlali. Sepetteki adet input'unun bir label'ı yok; axe bunu critical olarak işaretledi ve 4.1.2'ye (Name, Role, Value) bağladı. Yanında iki best practice bulgusu var: katalog sayfasında hiç h1 yok, sepet tablosunun son sütun başlığı boş. Kitap detayı sayfası temiz çıktı.

Peki screen reader bu sayfalardan ne alıyor? tree.mjs, Playwright'ın ariaSnapshot()'ı ile bir bölümün accessibility tree'sini (tarayıcının sayfadaki element'lerden üretip assistive technology'ye verdiği, role ve adlardan oluşan ağaç) yazdırıyor. Sepet satırı ve sipariş formu:

// Sayfanın bir bölümünün accessibility tree'sini (Playwright aria snapshot) yazdırır
// Kullanım: node tree.mjs <catalog|book|cart> [css selector]
import { chromium } from 'playwright';
import { open } from './lib.mjs';

const [name = 'catalog', selector = 'body'] = process.argv.slice(2);
const browser = await chromium.launch();
const page = await (await browser.newContext()).newPage();
await open(page, name);
console.log(await page.locator(selector).first().ariaSnapshot());
await browser.close();
node tree.mjs cart "tbody tr"
node tree.mjs cart form.checkout
- row "1984 ₺279.00 ₺279.00 Remove":
  - cell "1984":
    - link "1984":
      - /url: /books/9780451524935
  - cell "₺279.00"
  - cell:
    - spinbutton: "1"
  - cell "₺279.00"
  - cell "Remove":
    - button "Remove"
- textbox "Full name"
- textbox "E-mail"
- button "Place order"

Adet alanı ağaçta yalnız spinbutton: "1": bir role ve bir değer var, ad yok. Screen reader "spin button, 1" der; neyin adedi olduğunu söylemez. Sipariş formundaki iki textbox ise "Full name" ve "E-mail" adlarını taşıyor ve axe bunları geçti. Bu adlar placeholder'dan geliyor: kullanıcı yazmaya başladığında görsel ipucu kayboluyor, ve placeholder'ın label yerine geçmediği HTML serisinin "HTML Form'ları 1" yazısında anlatıldı. Kriter açısından bu 3.3.2'nin (Labels or Instructions) konusu ve bir insanın karar vermesi gerekiyor.

Taramanın hiç bakmadığı şeyler daha fazla: "Add to cart"a bastığında ekranda beliren "Added." mesajını screen reader duyuruyor mu, kitap detayına geçtiğinde focus nereye gidiyor, sepetten bir satırı silince klavye kullanıcısı nerede kalıyor, katalogdaki yirmi "Add to cart" butonundan hangisinin hangi kitaba ait olduğu anlaşılıyor mu? Bunların hiçbiri statik bir taramayla ölçülemiyor; önümüzdeki yazıların konusu. "Bir ihlal" sonucu Bookstore'un erişilebilir olduğunu değil, otomatik aracın yakalayabildiği sorunların az olduğunu söylüyor.

WCAG'in Yapısı: POUR, Guideline ve Success Criterion

WCAG, W3C'nin (World Wide Web Consortium; web standartlarını yayımlayan kuruluş) WAI (Web Accessibility Initiative; W3C'nin accessibility çalışmalarını yürüten birimi) bünyesinde hazırlanan standart. Dört katmanlı bir yapısı var:

01-wcag-structure-tr.png

En üstte POUR (dört ilkenin İngilizce adlarının baş harfleri) diye kısaltılan dört ilke var. Perceivable: içerik kullanıcının algılayabileceği bir biçimde sunulmalı; görsele metin alternatifi, videoya altyazı, yeterli contrast. Operable: arayüz kullanılabilmeli; her şey klavyeyle yapılabilmeli, kullanıcıya yeterli süre tanınmalı, sayfada yolunu bulabilmeli. Understandable: içerik ve davranış anlaşılır olmalı; sayfanın dili belirli, navigation tutarlı, formlar hatayı açıklıyor. Robust: içerik, assistive technology dahil farklı araçlarla güvenilir biçimde çalışmalı; her element'in doğru bir adı, role'ü ve durumu olmalı.

İlkelerin altında 13 guideline var: 1.1 Text Alternatives, 2.1 Keyboard Accessible, 3.3 Input Assistance gibi. Guideline'lar hedefi tarif eder ama test edilemez. Test edilebilir olan, onların altındaki success criterion'lar: "bu sayfa 1.1.1'i karşılıyor mu?" sorusunun cevabı evet ya da hayırdır. WCAG 2.2'de 86 success criterion var ve her birinin bir seviyesi var: A (en temel engelleri kaldıran kriterler), AA (yasal düzenlemelerin genelde hedef aldığı seviye) ve AAA (en sıkı seviye).

Bağlayıcı olan yalnız bu kriterler ve uyum kuralları. "Understanding WCAG 2.2" sayfaları her kriterin amacını, "Techniques" sayfaları bilinen çözümleri ve sık hataları anlatır; bunlar bilgilendirici, bir tekniği uygulamamak tek başına ihlal değildir. Kriter metni kısa ve hukuki dille yazıldığı için karar verirken önce Understanding sayfasını oku.

Uyum, kriterlerin tek tek karşılanmasından fazlası. AA uyumlu bir sayfa, bütün A ve AA kriterlerini karşılar. Uyum tam sayfa için verilir; sayfanın bir bölümü hariç tutulamaz. Bir süreç birden fazla sayfaya yayılıyorsa, örneğin sepet, adres ve ödeme adımları, sürecin bütün sayfaları uyumlu olmalı; ödeme adımı erişilemiyorsa sepet sayfasının uyumlu olması bir şey ifade etmez. Uyumsuz bir parça (otomatik oynayan bir video, klavyeyi içine hapseden bir widget) sayfanın geri kalanını kullanılamaz yapmamalı. W3C, AAA'nın bütün bir site için genel politika olarak istenmesini önermiyor, çünkü bazı içerik türleri için AAA kriterlerinin hepsini karşılamak mümkün değil. Pratikte hedef WCAG 2.2 AA.

WCAG 2.0'dan 2.2'ye ve WCAG 3

WCAG 2.0 Aralık 2008'de yayımlandı ve 2012'de ISO'nun (Uluslararası Standardizasyon Örgütü) ISO/IEC 40500:2012 standardı oldu. WCAG 2.1 (Haziran 2018) mobil kullanım, az görme ve bilişsel engeller için 17 kriter ekledi: reflow, metin aralığı, metin dışı contrast gibi. WCAG 2.2 Ekim 2023'te yayımlandı, 12 Aralık 2024'te düzeltmelerle güncellendi ve dokuz yeni kriter getirdi:

KriterSeviyeBookstore'da karşılığı
2.4.11 Focus Not Obscured (Minimum)AASticky header ya da cookie banner'ı focus'taki element'i tamamen örtmemeli
2.4.12 Focus Not Obscured (Enhanced)AAAFocus'taki element'in hiçbir kısmı örtülmemeli
2.4.13 Focus AppearanceAAAFocus göstergesinin minimum alanı ve contrast'ı
2.5.7 Dragging MovementsAASürükle-bırak ile yapılan her işin tek tıklamalı bir alternatifi
2.5.8 Target Size (Minimum)AATıklama alanı en az 24x24 CSS piksel ya da yeterli boşluk
3.2.6 Consistent HelpAYardım ve iletişim bağlantısı her sayfada aynı yerde
3.3.7 Redundant EntryACheckout'ta aynı adresi ikinci kez yazdırmamak
3.3.8 Accessible Authentication (Minimum)AAGirişte bilişsel teste dayanmamak; şifre yapıştırmayı engellememek
3.3.9 Accessible Authentication (Enhanced)AAANesne ya da kişisel içerik tanıma istisnası da yok

Bir kriter de çıkarıldı: 4.1.1 Parsing. Eskiden assistive technology'ler HTML'i kendileri parse ettiği için hatasız markup isteniyordu; bugün accessibility tree'yi tarayıcı üretiyor, tekrarlanan id gibi gerçek sorunları da 1.3.1 ve 4.1.2 yakalıyor. WCAG 2.2'de 4.1.1 "obsolete and removed" olarak işaretli; WCAG 2.0 ya da 2.1'e göre rapor vermen gerekiyorsa hâlâ test etmen gerekebilir. Sürümler geriye uyumlu: WCAG 2.2'ye uyan içerik 2.1'e ve 2.0'a da uyar. 21 Ekim 2025'te WCAG 2.2, ISO/IEC 40500:2025 olarak onaylandı ve ISO'dan ücretsiz erişilebiliyor; standardı mevzuatına almak isteyen ülkeler için bu önemli bir adım.

WCAG 3 ise henüz bir Working Draft (taslak); son taslak 10 Eylül 2026 tarihli. Yapısı farklı (kriterler yerine "outcome"lar ve puanlama), ama W3C taslağın önünde hâlâ birkaç yıllık iş olduğunu ve WCAG 3'ün WCAG 2'yi geçersiz kılmadığını açıkça yazıyor. Bugün yazdığın kodun ölçüsü WCAG 2.2.

Türkiye: 2025/10 Sayılı Cumhurbaşkanlığı Genelgesi

"Web Siteleri ve Mobil Uygulamaların Erişilebilirliği" konulu 2025/10 sayılı Cumhurbaşkanlığı Genelgesi, 21 Haziran 2025 tarihli ve 32933 sayılı Resmî Gazete'de yayımlandı. Dayanağı 5378 sayılı Engelliler Hakkında Kanun. Geliştiriciyi ilgilendiren kısımları şöyle:

Kapsam ve süre iki gruba ayrılıyor. Kamu kurum ve kuruluşları, üniversiteler, belediyeler ve şirketleri, kamu iktisadi teşebbüsleri, kamu kurumu niteliğindeki meslek kuruluşları, bankalar, özel hastaneler, özel okullar, belirli yolcu taşımacılığı şirketleri, A grubu seyahat acenteleri ve 200.000'den fazla abonesi olan elektronik haberleşme işletmecileri için süre 1 yıl. 6563 sayılı Elektronik Ticaretin Düzenlenmesi Hakkında Kanun kapsamındaki elektronik ticaret hizmet sağlayıcıları için süre 2 yıl. Genelge'nin metni sürelerin başlangıcını ayrıca yazmıyor; yayım tarihinden sayılırsa ilk grup için Haziran 2026, e-ticaret için Haziran 2027 ediyor.

Ölçüt olarak iki belge gösteriliyor: Aile ve Sosyal Hizmetler Bakanlığı'nın yayımladığı "Web Siteleri ve Mobil Uygulamaların Erişilebilirliği Kontrol Listesi - A Seviyesi" ve WCAG 2.2. Bakanlığa göre kontrol listesi WCAG 2.2 temel alınarak hazırlandı, 31 maddeden ve 122 sorudan oluşuyor; WCAG 2.2'de A seviyesindeki success criterion sayısı da 31. Kurumlar kendi bünyelerinde bir İnceleme Komisyonu kurup sitelerini teknik olarak değerlendiriyor ve Bakanlık bünyesindeki İzleme Komisyonu'na raporluyor. İzleme sonunda erişilebilir bulunan site ve uygulamalar 2 yıl süreyle Bakanlığın "Erişilebilirlik Logosu"nu kullanabiliyor. Bakanlık duyurusu, verilen süre içinde gerekli koşulları sağlamayanların bilgilerinin kamuoyuyla paylaşılacağını da belirtiyor.

Geliştirici için anlamı: kontrol listesi bir taban. Genelge WCAG 2.2'yi de ayrıca andığı için, hedefi yalnız listenin A seviyesine göre koymak riskli; contrast (1.4.3) ve focus görünürlüğü (2.4.7) gibi en sık karşılaşılan sorunlar AA seviyesinde.

AB: European Accessibility Act ve EN 301 549

European Accessibility Act (EAA; AB'nin ürün ve hizmetlerde accessibility şartlarını belirleyen 2019/882 sayılı Direktifi) 28 Haziran 2025'ten beri uygulanıyor. Kapsamındaki hizmetler arasında tüketiciye sunulan e-ticaret hizmetleri, bankacılık, e-kitap ve yolcu taşımacılığının dijital kısımları var. Direktif üye ülkelerin kendi yasalarıyla uygulanıyor ve denetim de ülke bazında. Hizmet sunan mikro işletmeler (10'dan az çalışanı olan ve yıllık cirosu ya da bilançosu 2 milyon avroyu geçmeyen) hizmetler için istisna. 28 Haziran 2025'ten önce yapılmış hizmet sözleşmeleri en fazla beş yıl, yani 2030'a kadar değiştirilmeden sürebiliyor.

Direktif tek tek teknik kural yazmıyor, işlevsel gereksinimler koyuyor. Bunlara uyduğunu göstermenin yolu harmonized standard EN 301 549 (Avrupa standardizasyon kuruluşlarının ortak yayımladığı, bilgi ve iletişim teknolojileri için accessibility standardı); bu standardın web bölümü doğrudan WCAG'e dayanıyor. Bugün Avrupa Birliği Resmî Gazetesi'nde atıf yapılan sürüm 3.2.1 ve WCAG 2.1 AA'yı referans alıyor. 2 Eylül 2026'da yayımlanan 4.1.1 sürümü referansı WCAG 2.2 AA'ya taşıdı; Komisyonun yeni sürüme 16 Aralık 2026'da atıf yapması bekleniyor. Bookstore AB'deki tüketicilere EUR ile satış yapıyorsa bu düzenleme onu da ilgilendirebilir; kapsamın kesin değerlendirmesi hukukçunun işi, ama teknik hedef her iki yolda da aynı yere çıkıyor: WCAG 2.2 AA.

Üretimde Dikkat

Hedefi yazıya dök. "Accessible olsun" ölçülebilir bir hedef değil; "Bookstore'un bütün public sayfaları ve checkout süreci WCAG 2.2 AA'yı karşılar" ölçülebilir. Bu cümle Genelge'nin WCAG 2.2 atfını, Bakanlık listesinin A seviyesini ve EN 301 549 4.1.1 sürümünün AA referansını aynı anda kapsıyor.

Otomatik taramayı tek kanıt olarak kullanma. Bu yazıdaki tarama tek ihlal buldu; bir sonraki yazıdaki manuel audit çok daha fazlasını bulacak. Otomatik araç manuel kontrolün yerini tutmaz, ondan önce gelen hızlı bir filtredir.

Accessibility'yi "done" tanımına koy. Her yeni ekran merge edilmeden önce klavyeyle bir kez baştan sona kullanılsın ve axe taramasından geçsin; component'ler yayıldıktan sonra düzeltmek çok daha pahalı.

Kanıt tut. Hangi sayfayı ne zaman, hangi araç ve kontrol listesiyle test ettiğini, bulguları ve düzeltmeleri kaydet; İnceleme Komisyonu'nun değerlendirmesinde ve bir sonraki yazıdaki accessibility statement (erişilebilirlik beyanı) sayfasında bunlara ihtiyacın olacak.

Sık Düşülen Tuzaklar

Birincisi, axe'ın sıfır ihlal raporunu "erişilebilir" diye okumak. Rapor yalnız aracın kontrol edebildiği kurallar için bir şey söylüyor.

İkincisi, sayfaya eklenen bir accessibility overlay widget'ının (font büyütme, contrast değiştirme butonları sunan hazır script'ler) siteyi uyumlu yaptığını sanmak. Label'sız input, klavyeyle ulaşılamayan buton ya da yanlış focus sırası kodda duruyor; overlay bunları düzeltmez.

Üçüncüsü, Bakanlık kontrol listesinin A seviyesini nihai hedef sanmak. E-ticaret sitesi AB'ye de satış yapıyorsa EN 301 549 üzerinden AA bekleniyor; contrast gibi en sık sorunlar da AA'da.

Dördüncüsü, accessibility'yi screen reader desteğine indirgemek. Klavye, zoom, contrast, sesle kontrol ve bilişsel yük de aynı ölçüde önemli; kullanıcıların çoğu screen reader kullanmıyor.

Küçük Bir Deneme

★☆☆ tree.mjs ile katalog sayfasındaki .toolbar'ı yazdır. Arama kutusunun ve kategori seçicinin adları nereden geliyor: görünen bir label'dan mı, aria-label'dan mı, placeholder'dan mı?

★★☆ scan.mjs'teki tag listesini yalnız ['wcag2a', 'wcag21a'] olacak şekilde değiştirip çalıştır; Bakanlık listesinin A seviyesine yakın bir tarama elde edersin. Sonra listeye wcag22aa'yı geri ekle ve axe'ın target-size kuralının yalnız bu tag istendiğinde çalıştığını, varsayılan taramada çalışmadığını doğrula (ipucu: sonucun passes ve inapplicable listelerinde kuralın id'sini ara).

★★★ Kendi projenden üç sayfa seç ve scan.mjs'i onlara uyarla. Bulguları POUR ilkelerine göre grupla, sonra her sayfayı beş dakika boyunca yalnız klavyeyle kullan ve otomatik taramanın kaçırdığı sorunları ayrı bir listeye yaz. İki listenin uzunluğunu karşılaştır.

Bir sonraki yazıda WCAG 2.2'yi kriter kriter değil, gerçek dünyada en sık düşülen sorunlar üzerinden okuyoruz: düşük contrast, eksik alt text, label'sız input'lar, boş link ve butonlar. Bookstore'un manuel audit tablosunu çıkarıp ilk düzeltmeleri yapacağız, WCAG 2.2'nin yeni kriterlerini ölçeceğiz ve bir accessibility statement sayfası taslağı yazacağız.