Saya memiliki akordeon sederhana:

<div>
  <button aria-expanded='false' aria-controls='content'>
    Open accordion
  </button>
  <div id='content' aria-hidden='true'>
    This the accordion's hidden content.
  </div>
</div>

Saya menggunakan javascript untuk membuka / menutup akordeon dan atur tag aria-*.

Semuanya berfungsi dengan baik tetapi ketika saya menambahkan tautan di dalam konten:

<div>
  <button aria-expanded='false' aria-controls='content'>
    Open accordion
  </button>
  <div id='content' aria-hidden='true'>
    This is the accordion's hidden content.
    <a href='https://www.google.com'>Go to Google</a>
  </div>
</div>

Mercusuar memberi saya ini:

[aria-hidden="true"] elements contain focusable descendents

Sepertinya saya menambahkan tabindex='-1' ke tag a memecahkan masalah:

<a tabindex='-1' href='https://www.google.com'>Go to Google</a>

Namun, itu membuat elemen "non-tabbable", yang tidak baik untuk aksesibilitas.

Saya bisa menggunakan javascript untuk menanyakan secara manual untuk semua a tag di dalam konten akordeon tetapi saya bahkan tidak yakin apakah ini benar-benar memecahkan "masalah" atau adalah pekerjaan kotor? Apakah ada alternatif yang lebih baik?

Terima kasih.

2
kibe 5 April 2021, 05:50

2 jawaban

Jawaban Terbaik

Mengapa Anda mendapatkan peringatan ini?

Peringatan ini menunjukkan meskipun Anda menggunakan aria-hidden="true" mayoritas pembaca layar akan mengabaikan aria-hidden="true" pada item induk jika anak-anak dapat menerima fokus (untuk memperhitungkan kesalahan pengembang, JavaScript tidak memuat dengan benar dll.)

Bagaimana memperbaikinya?

Saya berasumsi bahwa Anda menggunakan sesuatu seperti animasi slide-up atau serupa itulah sebabnya Anda tidak hanya menggunakan display: none pada konten.

Jika Anda tidak menggunakan animasi maka hanya display: none konten ketika Anda memiliki aria-hidden="true" diterapkan (@adam telah menunjukkan kepada Anda cara sempurna untuk melakukan itu dalam jawabannya).

Lebih baik lagi Anda bisa langsung menggunakan display: none pada div karena ini akan menyembunyikan semua konten dari pembaca layar sehingga Anda tidak perlu menggunakan Wai-Aria di sana!

Saya menggunakan animasi / transisi jadi tidak bisa hanya menyembunyikan semua konten.

Jika Anda menggunakan animasi, perubahan opacity dll., Itu berhenti Anda cukup menyembunyikan seluruh konten maka apa yang dapat Anda lakukan adalah menyembunyikan konten yang fokus dalam konten <div>.

Kita dapat melakukan ini menggunakan CSS ketika Anda memiliki aria-hidden="true" diterapkan, lalu sembunyikan elemen-elemen yang fokus ketika Anda mengubah atau menghapus aria-hidden="true".

Juga untuk menghindari "tata letak Jank" ketika kita menyembunyikan elemen-elemen lagi saya akan menyarankan menggunakan visibility: hidden daripada display: none karena yang membuat ruang yang dialokasikan untuk item tersembunyi dan masih menyembunyikannya dari pembaca layar dll.

#content[aria-hidden=true] a[href],
#content[aria-hidden=true] area[href], 
#content[aria-hidden=true] input:not([disabled]), 
#content[aria-hidden=true] select:not([disabled]), 
#content[aria-hidden=true] textarea:not([disabled]), 
#content[aria-hidden=true] button:not([disabled]), 
#content[aria-hidden=true] [tabindex]:not([disabled]), 
#content[aria-hidden=true] [contenteditable=true]:not([disabled]){
    visibility: hidden;
}

Demo cepat

Cara termudah untuk melihat apa yang saya maksud adalah dengan demo cepat, tekan tombol "toggle aria-hidden on" dan itu akan menyembunyikan semua elemen fokus di #content <div>.

var btn = document.querySelector('#toggle-aria');
var contentDiv = document.querySelector('#content');


btn.addEventListener('click', function(){
    var self = this;
    if(contentDiv.getAttribute('aria-hidden') == "false"){
      self.innerHTML = "Toggle aria-hidden off";
      contentDiv.setAttribute('aria-hidden', "true"); 
    }else{
      self.innerHTML = "Toggle aria-hidden on";
      contentDiv.setAttribute('aria-hidden', "false"); 
    }
});
#content{
padding: 20px;
border: 1px solid #333;
}

#content[aria-hidden=true] a[href],
#content[aria-hidden=true] area[href], 
#content[aria-hidden=true] input:not([disabled]), 
#content[aria-hidden=true] select:not([disabled]), 
#content[aria-hidden=true] textarea:not([disabled]), 
#content[aria-hidden=true] button:not([disabled]), 
#content[aria-hidden=true] [tabindex]:not([disabled]), 
#content[aria-hidden=true] [contenteditable=true]:not([disabled]){
    visibility: hidden;
}
<br/><br/><button id="toggle-aria">Toggle aria-hidden on</button>

<p>When aria-hidden is set to true on the below div all focusable elements should disappear.</p>

<hr/>

<div id="content" aria-hidden="false">
    <a href="https://google.com">To Google</a><br/><br/>
    <label>An input
      <input />
    </label><br/><br/>
    <label>A Select 
      <select>
        <option>option 1</option>
        <option>option 2</option>
        <option>option 3</option>
      </select>
     </label><br/><br/>
     <label>A textarea
      <textarea></textarea>
    </label><br/><br/>
    <button>A button</button><br/><br/>
    <div tabindex="0">A fake button with tabindex</div><br/><br/>
    <div contenteditable="true">A div that is cotnent editable</div><br/><br/>
    <p>Only the labels and this paragraph should be the only things left showing when you toggle the aria-hidden to true</p>
    
</div>
<br/><br/>
<button>I am a button purely so you can see there is nothing focusable within the #content div if you "Tab"</button>

Catatan Penting: Yang kedua Anda tekan tombol "Open Accordion" Anda harus menghapus aria-hidden sebelum animasi apa pun dll. Ini karena pengguna pembaca layar kemudian akan mencoba dan tab (atau navigasi melalui pintasan pembaca layar) ke dalam konten. Jika Anda menghapus aria-hidden="true" terlambat mereka dapat melewati semua konten!

1
Graham Ritchie 5 April 2021, 10:36

Solusi sederhana, gunakan properti css display:none untuk menghapus elemen dari fokus:

#content[aria-hidden=true] {
   display:none;
}

Itu tidak hanya berguna tetapi cukup diperlukan karena kami tidak ingin ScreenReaders mengumumkan hal-hal yang tidak terlihat.

3
Adam 5 April 2021, 08:05