Ders 03 / 25
Seçim Denetimleri
Onay kutusu, seçenek düğmesi ve anahtarın çözdüğü ayrı sorunlar; grubun adlandırılması, karma durumun bildirimi ve iki farklı klavye sözleşmesinin sınanması.
İçindekiler
Metin girdisinde adın kaynağı alanın kendi etiketiydi. Ödünç alma formundaki “Bildirim yöntemi” bölümü ise üç ayrı denetimden oluşur — “E-posta”, “SMS”, “Bildirim yok” — ve kullanıcının yanıtladığı soru bu üç adın hiçbirinde yazmaz. Soru grubun kendisine aittir.
Bu ders üç seçim denetimini belirtir: onay kutusu, seçenek düğmesi ve anahtar. Üçünün görünümü birbirine yakındır, çözdükleri sorunlar ve klavye sözleşmeleri ise ayrıdır. Ayrımın yanlış kurulması, arayüzün klavyeyle çalışmayı sürdürdüğü ama beklenenden farklı davrandığı bir sonuç üretir.
Üç Denetim, Üç Ayrı Sorun
Onay kutusu bağımsız bir açık/kapalı seçimdir. Katalogun süzgeç panelinde “Yalnız rafta olanlar”, “Yalnız e-kitaplar” ve “Süreli yayınlar” birbirinden bağımsızdır; hiçbiri diğerini kapatmaz. Sıfır tanesi seçili olabilir, hepsi seçili olabilir.
Seçenek düğmesi birbirini dışlayan bir seçimdir ve her zaman bir grup içinde bulunur. Ödünç süresi 14, 21 ya da 28 gündür; biri seçildiğinde diğeri kapanır. Tek başına bir seçenek düğmesi anlamsızdır — kullanıcı onu seçtikten sonra seçimden vazgeçemez.
Anahtar açık/kapalı bir ayardır ve değiştirildiği anda etkili olur. Kullanıcı hesabındaki “İade hatırlatması gönder” ayarı böyledir: değiştirilir, kaydedilir, sayfada bir gönderim düğmesi beklemez.
Ayrım buradan çıkar: bir gönderim düğmesiyle onaylanacak bir form içinde anahtar kullanılmaz, onay kutusu kullanılır. Anahtarın verdiği söz “şimdi etkili oldu”dur; formun gönderilmesini bekleyen bir anahtar bu sözü tutmaz.
Yerel Öge Önce
Onay kutusunun ve seçenek düğmesinin yerel karşılıkları vardır: input ögesinin checkbox
ve radio türleri. İkisi de rolü, işaretlilik durumunu, klavye sözleşmesini ve gönderim
listesine katılmayı birlikte getirir. Seçenek düğmelerini bir gruba bağlayan şey name
özniteliğinin aynı olmasıdır; grup, işaretlemedeki komşuluktan değil bu addan doğar.
Anahtarın yerel karşılığı yoktur. Karşılanma yolu, role="switch" bildirimi taşıyan bir
düğmedir; durumu aria-checked ile yazılır. Onay kutusuna role="switch" yazmak da
tanımlıdır ve o durumda ögenin yerel işaretlilik durumu ağaca anahtar durumu olarak geçer.
Grubun Adı
Grubun bir adı olmadığında kullanıcı üç seçeneği duyar, sorusunu duymaz. Yerel karşılık
fieldset ve legend ögeleridir: fieldset ögesi ağaçta grup rolü üretir, legend
ögesinin metni grubun adı olur.
<fieldset> <legend>Bildirim yöntemi</legend> <p><label><input type="radio" name="bildirim" value="eposta" checked> E-posta</label></p> <p><label><input type="radio" name="bildirim" value="sms"> SMS</label></p> <p><label><input type="radio" name="bildirim" value="yok"> Bildirim yok</label></p> </fieldset> <fieldset> <legend>Süzgeçler</legend> <p><label><input type="checkbox" name="raf" value="rafta"> Yalnız rafta olanlar</label></p> <p><label><input type="checkbox" name="tur" value="e-kitap"> Yalnız e-kitaplar</label></p> </fieldset>
İki ayrıntı bağlayıcıdır. Birincisi, her denetimin kendi etiketinin label ögesiyle
kurulmasıdır; etiketin denetimi içine alması (örtük bağ) for ve id çifti yazmadan aynı
sonucu verir ve etiket metnini de tıklanabilir alana katar. İkincisi, seçenek düğmelerinin
name değerinin aynı olmasıdır; farklı yazıldığında üç ayrı tek seçenekli grup oluşur ve
kullanıcı üçünü birden seçebilir.
Grup ögesi kullanılamadığında karşılık role="group" ya da seçenek düğmeleri için
role="radiogroup" bildirimidir; grubun adı aria-labelledby ile başlık ögesine bağlanır.
Bu yol yalnız fieldset ögesinin düzen kısıtları sorun çıkardığında seçilir.
Rol, Ad ve Durum
Üç denetimin de adı kendi etiketinden gelir; grubun adı, denetimin adının yerine geçmez, onun bağlamı olur.
Durum bildirimi işaretliliktir. Yerel ögelerde checked özelliğinden ağaca geçer; elle
kurulan bir denetimde aria-checked değeriyle yazılır ve her değişimde güncellenir.
Onay kutusunun üçüncü bir durumu vardır: karma durum (mixed). Süzgeç panelinde
“Hepsini seç” kutusu, alt kutuların bir bölümü seçiliyken bu durumdadır. Yerel ögede
karma durum bir öznitelikle değil, indeterminate özelliğiyle kurulur ve ağaca karma
olarak bildirilir. Karma durum bir üçüncü seçenek değildir: kullanıcı ona tıkladığında
denetim ya tümünü seçer ya tümünü bırakır, karmaya geri dönmez.
Anahtarda karma durum yoktur. Ayrıca anahtarın durumu metinle de bildirilir mi sorusu
tasarım kararıdır: “Açık”/“Kapalı” metni denetimin adının parçası değildir, çünkü ad
değişmez; durum yalnızca aria-checked üzerinden bildirilir ve metin bir ek gösterge olur.
İki Klavye Sözleşmesi
Seçenek grubu:
| Tuş | Davranış |
|---|---|
Tab |
Odağı gruba getirir; grubun tamamı tek sekme durağıdır ve odak seçili düğmeye gelir. |
| Ok tuşları | Odağı ve seçimi birlikte taşır; uçlarda başa döner. |
Boşluk |
Odaktaki düğmeyi seçer. |
Tab (grup içindeyken) |
Grubun tamamından çıkar, sonraki durağa geçer. |
Onay kutusu ve anahtar:
| Tuş | Davranış |
|---|---|
Tab |
Her denetim ayrı bir sekme durağıdır. |
Boşluk |
Durumu değiştirir. |
| Ok tuşları | Etkisizdir; odak ve seçim değişmez. |
İki sözleşmenin farkı, seçenek grubunun dönen sekme durağı düzenini kullanmasıdır: grupta yalnızca bir öge sekme sırasındadır, kalanlarına ok tuşlarıyla ulaşılır. On beş seçenekli bir grup böylece on beş değil bir durak tutar. Onay kutuları bağımsız oldukları için bu düzeni kullanamaz; kullanıcı her birine ayrı ayrı ulaşmak zorundadır.
Aşağıdaki sınama iki sözleşmeyi durum makinesi olarak kurar ve tuş dizileriyle denetler.
// secim.test.mjs — secenek grubu ile onay kutusu grubunun klavye sozlesmesi // Kosum: node --test secim.test.mjs import { test } from "node:test"; import assert from "node:assert/strict"; const OGELER = ["E-posta", "SMS", "Bildirim yok"]; const ILERI = new Set(["ArrowDown", "ArrowRight"]); const GERI = new Set(["ArrowUp", "ArrowLeft"]); // odak: null ise odak grubun disinda const secenek = (secili = null) => ({ tur: "secenek", ogeler: OGELER, secili, odak: null }); const onay = () => ({ tur: "onay", ogeler: OGELER, secili: new Set(), odak: null }); // Grubun kapladigi sekme duragi sayisi function sekmeDuragi(d) { return d.tur === "secenek" ? 1 : d.ogeler.length; } function tus(d, t) { const n = d.ogeler.length; if (d.tur === "secenek") { if (d.odak === null) return t === "Tab" ? { ...d, odak: d.secili ?? 0 } : d; if (t === "Tab") return { ...d, odak: null }; if (ILERI.has(t)) { const i = (d.odak + 1) % n; return { ...d, odak: i, secili: i }; } if (GERI.has(t)) { const i = (d.odak + n - 1) % n; return { ...d, odak: i, secili: i }; } if (t === "Space") return { ...d, secili: d.odak }; return d; } if (d.odak === null) return t === "Tab" ? { ...d, odak: 0 } : d; if (t === "Tab") return d.odak === n - 1 ? { ...d, odak: null } : { ...d, odak: d.odak + 1 }; if (t === "Space") { const s = new Set(d.secili); if (s.has(d.odak)) s.delete(d.odak); else s.add(d.odak); return { ...d, secili: s }; } return d; // ok tuslari onay kutusu grubunu etkilemez } const uygula = (d, dizi) => dizi.reduce(tus, d); test("secenek grubu tek sekme duragi, onay kutulari ogesi kadar durak tutar", () => { assert.equal(sekmeDuragi(secenek()), 1); assert.equal(sekmeDuragi(onay()), 3); }); test("gruba giriste odak secili ogeye gelir", () => { assert.equal(uygula(secenek(2), ["Tab"]).odak, 2); }); test("hic secim yokken giriste odak ilk ogede olur ve secim yapilmaz", () => { const d = uygula(secenek(), ["Tab"]); assert.equal(d.odak, 0); assert.equal(d.secili, null); }); test("ok tusu odagi ve secimi birlikte tasir, sonda basa doner", () => { const d = uygula(secenek(0), ["Tab", "ArrowDown", "ArrowDown", "ArrowDown"]); assert.equal(d.odak, 0); assert.equal(d.secili, 0); const g = uygula(secenek(0), ["Tab", "ArrowUp"]); assert.equal(g.secili, 2); }); test("Tab grubun tamamindan tek basista cikar", () => { const d = uygula(secenek(1), ["Tab", "ArrowDown", "Tab"]); assert.equal(d.odak, null); assert.equal(d.secili, 2); }); test("onay kutusunda ok tusu hicbir sey yapmaz", () => { const d = uygula(onay(), ["Tab", "ArrowDown", "ArrowRight"]); assert.equal(d.odak, 0); assert.equal(d.secili.size, 0); }); test("onay kutulari birbirinden bagimsiz acilip kapanir", () => { const d = uygula(onay(), ["Tab", "Space", "Tab", "Tab", "Space"]); assert.deepEqual([...d.secili].sort(), [0, 2]); const k = uygula(d, ["Space"]); assert.deepEqual([...k.secili], [0]); }); test("bosluk tusu secenek grubunda odaktaki ogeyi secer", () => { const d = uygula(secenek(0), ["Tab", "Space"]); assert.equal(d.secili, 0); });
✔ secenek grubu tek sekme duragi, onay kutulari ogesi kadar durak tutar (0.361166ms) ✔ gruba giriste odak secili ogeye gelir (0.08225ms) ✔ hic secim yokken giriste odak ilk ogede olur ve secim yapilmaz (0.045375ms) ✔ ok tusu odagi ve secimi birlikte tasir, sonda basa doner (0.04925ms) ✔ Tab grubun tamamindan tek basista cikar (0.339708ms) ✔ onay kutusunda ok tusu hicbir sey yapmaz (0.072458ms) ✔ onay kutulari birbirinden bagimsiz acilip kapanir (0.360833ms) ✔ bosluk tusu secenek grubunda odaktaki ogeyi secer (0.046833ms) ℹ tests 8 ℹ suites 0 ℹ pass 8 ℹ fail 0 ℹ cancelled 0 ℹ skipped 0 ℹ todo 0 ℹ duration_ms 35.587
Parantez içindeki süreler ve toplam süre koşumdan koşuma değişir; sınamanın sonucu değişmez.
Üçüncü sınama sözleşmenin en çok atlanan yerini yakalıyor: hiçbir seçenek işaretli değilken gruba girildiğinde odak ilk ögeye gelir ama seçim yapılmaz. Odağın seçimi sürüklediği kural yalnızca ok tuşları için geçerlidir; giriş anı bunun dışındadır. Elle yazılan gruplarda bu ayrım gözden kaçtığında, kullanıcı sekme tuşuna bastığı için istemediği bir ödünç süresini seçmiş olur.
Beşinci sınama, dönen sekme durağının doğrudan sonucudur: grup içinde ok tuşuyla iki adım
gidilmiş olsa da Tab tek basışta gruptan çıkar.
Ölçülebilir Kısıtlar
Hedef boyutu. Onay kutusunun görsel kutusu genelde 16 ile 20 piksel arasındadır ve tek
başına 2.5.8 ölçütünü karşılamaz. Etiket metninin denetimle birlikte tıklanabilir olması —
label ögesi bunu kendiliğinden sağlar — hedefi metnin genişliğine kadar büyütür. Süzgeç
listesindeki kutuların dikey aralığı da 2.5.8’in aralık istisnasını sağlayacak kadar
açılmalıdır.
1.4.11 Metin Dışı Kontrast. Kutunun ve düğmenin sınırı, sayfa yüzeyinden en az 3:1 ile ayrılmalıdır. Aynı ölçü işaretlilik göstergesi için de geçerlidir: işaret, kutunun içindeki dolgudan ayırt edilebilmelidir.
1.4.1 Rengin Tek Taşıyıcı Olmaması. İşaretli durum yalnızca dolgu rengiyle bildirilemez; bir onay imi, bir nokta ya da anahtarın kaydırılmış konumu ikinci kanaldır.
3.2.2 Girdide Bağlam Değişikliği. Bir onay kutusunun değiştirilmesi formu kendiliğinden göndermemeli ya da sayfayı değiştirmemelidir. Süzgeç panelinde bir kutu işaretlendiğinde sonuç tablosunun tazelenmesi kabul edilebilir bir davranıştır, çünkü bağlam değişmez; sayfa adresinin değişmesi ve odağın kaybolması kabul edilemez.
Sık Yapılan Hata
Onay kutusunun birbirini dışlayan seçim için kullanılması. Saptaması davranıştandır: kullanıcı ikinci kutuyu işaretlediğinde birincisi kendiliğinden kapanıyorsa, bileşen yanlış seçilmiştir. Kullanıcı için bu, kapanma nedeninin hiçbir yerde bildirilmemesi anlamına gelir.
Grubun adsız bırakılması. Saptaması bir varlık kuralıyla yapılır: seçenek düğmesi taşıyan her grubun bir adı olmalıdır. Ekranda grubun üstünde duran bir başlık metni, bir bağ kurulmadıkça ad değildir.
Anahtarın gönderim düğmesi bekleyen bir forma konması. Saptaması, anahtarın değiştirilmesinden sonra bir kaydetme adımı gerekip gerekmediğinin sorulmasıdır. Gerekiyorsa bileşen onay kutusuna çevrilir.
Karma durumun false olarak bildirilmesi. “Hepsini seç” kutusu, alt kutuların bir
bölümü seçiliyken kapalı görünüyorsa kullanıcıya yanlış bilgi verilir. Saptaması, alt
kutuların sayımıyla üst kutunun bildirilen durumunun karşılaştırılmasıdır.
Özet
- Onay kutusu bağımsız açık/kapalı seçim, seçenek düğmesi birbirini dışlayan seçim, anahtar ise değiştirildiği anda etkili olan bir ayardır; gönderim bekleyen formda anahtar kullanılmaz.
- Onay kutusunun ve seçenek düğmesinin yerel karşılığı vardır; anahtarın yoktur ve
role="switch"ile kurulur. Seçenek grubununameözniteliğinin aynılığı oluşturur. - Grubun adı
fieldsetvelegendile verilir; grup adı denetimin adının yerine geçmez, bağlamı olur. - Seçenek grubu dönen sekme durağı kullanır: grup tek durak tutar, ok tuşları odağı ve seçimi birlikte taşır; onay kutuları ise ayrı duraklardır ve ok tuşlarına yanıt vermez.
- Gruba ilk girişte hiçbir seçenek seçili değilse odak ilk ögeye gelir ama seçim yapılmaz; bu, elle yazılan gruplarda en çok atlanan kuraldır.
- Karma durum bir üçüncü seçenek değil, alt seçimlerin özetidir; kullanıcı tıkladığında ya tümü seçilir ya tümü bırakılır.
Sonraki Adım
Seçenek grubu, seçenekler sayılabilir ve az sayıda olduğunda çalışır. Katalogun süzgeç panelinde “Konu” alanı ise iki yüz elli değer taşır ve hepsi ekranda gösterilemez. Bu, seçim işini kapalı bir listeye devretmeyi gerektirir: kullanıcı listeyi açar, gezinir, yazarak daraltır ve bir değer seçer. Sonraki ders bu bileşeni iki ayrı kalıp olarak belirtir — yerel seçim ögesi ile elle kurulan birleşik giriş alanı — ve ikincisinin neden en çok bildirim gerektiren kalıp olduğunu gösterir.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.