Gölge sınırı, semantiğin ve ARIA'nın işleyiş şeklini değiştirir. İki hata öne çıkıyor: Gölge ağacında eksik semantikler ve gölge köklerini geçemedikleri için sessizce bozulan ARIA referansları.
Semantik işaretlemeden başlayın: Şablonda gerçek <button>, <nav>, <ul> kullanın. Böylece çoğu semantik ücretsiz olarak sunulur ve boşluklar için ElementInternals/ARIA'yı ayırın.
ElementInternals ARIA mixin aracılığıyla varsayılan semantikler
Özel bir öğenin rolünü ve ARIA durumunu, ARIA özelliklerini ana makineye yazmak yerine ElementInternals aracılığıyla JS'de ayarlayın. Bu sayede, bileşenin sahip olduğu varsayılan semantikler korunurken tüketicinin Light DOM'daki özelliklerle bunları geçersiz kılmasına olanak tanınır.
class ToggleSwitch extends HTMLElement {
#internals;
constructor() {
super();
this.#internals = this.attachInternals();
this.#internals.role = 'switch'; // default role, no host attribute needed
this.#internals.ariaChecked = 'false'; // exposed to the accessibility tree
this.addEventListener('click', () => this.toggle());
this.addEventListener('keydown', (e) => {
if (e.key === ' ') { e.preventDefault(); this.toggle(); }
});
}
connectedCallback() {
// Put the host in the tab order on connect (setting tabIndex in the constructor throws on createElement).
if (!this.hasAttribute('tabindex')) this.tabIndex = 0;
}
toggle() {
const on = this.#internals.ariaChecked !== 'true';
this.#internals.ariaChecked = String(on);
}
}
customElements.define('toggle-switch', ToggleSwitch);
Bu, DOM'un ARIA özellikleriyle kirlenmesini önler ve tüketicilerin bunları yanlışlıkla bozmasını engeller. Erişilebilirlik ağacı ise doğru rolü ve durumu görmeye devam eder.
Odak yönetimi ve delegatesFocus
- Ana öğenin kendisi etkileşimli kontrol olduğunda ve rol ile durumu
ElementInternalsaracılığıyla taşıdığında (yukarıdakiToggleSwitchgibi), ana öğeyiconnectedCallback(if (!this.hasAttribute('tabindex')) this.tabIndex = 0) içindeki sekme sırasına yerleştirin (document.createElementüzerinde hata veren oluşturucuya hiçbir zaman yerleştirmeyin). Böylece odak ana öğeye yönlendirilir ve yardımcı teknoloji, rolünü ve durumunu duyurur. Statik, etkileşimli olmayan bileşenler (ör. açıklama metni veya kart) için ana makinedetabindexdeğerini ayarlamayın. - Bileşen, semantiğe sahip dahili bir odaklanılabilir denetimi sarmaladığında (veya
static formAssociated = trueiçeren formla ilişkili özel bir öğede) gölge kökünüdelegatesFocus: trueile ekleyin. Ana makineye odaklanıldığında (ve formla ilişkili öğeler için ilişkili bir<label>tıklandığında) odak, odaklanılabilir ilk alt öğeye yönlendirilir ve:focus, ana makineyle eşleşir.delegatesFocus: trueöğesini ana makinedeki bir rol/durum ile birleştirmeyin. Aksi takdirde odak, iç öğeye yönlendirilir ve ana makinenin durumu atlanır. - Gezici odaklama veya odağı yeni gösterilen bir bölgeye taşımak için hedefe
tabindex="-1"verin ve.focus()yöntemini çağırın. Sekme sırasına güvenmek yerine programatik olarak odaklanılabilir hedefleri açıkça belirtin.
Gölge kökler arasında ARIA ilişkileri
- ZORUNLU:
aria-labelledby,aria-describedby,aria-controlsvb. tarafından referans verilen birid, yalnızca referans veren öğenin kendi ağacında çözümlenir. Light DOM'dakiidtabanlı bir özellik, gölge ağacındaki biridöğesini işaret edemez ve bunun tersi de geçerlidir. Referans sessizce yoksayılır. - Sınırı aşmak için kimlikler yerine doğrudan JS öğesi referanslarını alan yansıtılmış ARIA öğe özelliklerini (ör.
ariaLabelledByElements,ariaDescribedByElementsvb.) kullanın. Dışa doğru çözümlenirler: Gölge ağacındaki bir öğe, Light DOM'daki bir hedefi veya herhangi bir üst ağacı (yuvalı içerik dahil) işaret edebilir. Böylece, Light DOM içeriğinden gölge içi bir denetimi etiketleyebilirsiniz. Bu,idreferanslarının ifade edemediği bir şeydir. - İçe doğru çözümlenmezler: Bir öğe, alt gölge ağacına referans veremez (ör. bir ana makine kendi gölge içeriğiyle etiketlenemez). Bu yönde, yeni ortaya çıkan Referans Hedef mekanizması standartlar yönüdür ancak henüz geniş çapta kullanıma sunulmamıştır.
- Bir ilişki her iki şekilde de ifade edilemiyorsa ilişkiyi tek bir ağaçta tutun (etiketi aynı ağaçta oluşturun) veya
idreferansı yerinearia-labelmetni kullanın.
Yedek stratejiler
ElementInternals ARIA mixin'inin kullanılamadığı durumlarda, rolü ve ARIA durumunu ana makinede özellik olarak ayarlayın (this.setAttribute('role', 'switch')). Bu yöntem her yerde çalışır ancak tüketicinin geçersiz kılabileceği özellikleri DOM'a yerleştirir.
Yansıtılan ARIA öğe özellikleri kullanılamıyorsa aynı ağaç ilişkileri için id tabanlı bir aria-* özelliği kullanın. Sınır ötesi etiketlerin id tabanlı bir eşdeğeri olmadığından aria-label metnine geri dönün.