Cerca contenuti nascosti

Le interfacce web spesso nascondono i contenuti per migliorare l'esperienza utente, risparmiare spazio sullo schermo o aumentare le prestazioni della pagina. I metodi tradizionali come display: none o visibility: hidden nascondono i contenuti visivamente, ma li rendono anche completamente inaccessibili agli screen reader e alle funzionalità del browser come "Trova nella pagina".

Per nascondere visivamente i contenuti, ma consentire comunque agli utenti di cercarli e di creare deep link tramite frammenti di URL e link "Scorri fino al frammento di testo", puoi utilizzare l'elemento HTML <details> o l'attributo hidden="until-found". In genere, l'elemento <details> è consigliato perché è più semplice da implementare e gestire, ma esistono alcuni casi più complessi in cui <details> non è sufficiente ed è necessario hidden="until-found".

Ad esempio:

  • Se vuoi il controllo completo sullo stile del meccanismo di visualizzazione/nascondimento.
  • Se i controlli UI per mostrare/nascondere i contenuti si trovano in un'altra parte del DOM.
  • Se non vuoi supportare la possibilità di nascondere i contenuti dopo che sono stati mostrati.

Come implementare

L'elemento <details> ha un testo accessibile e disponibile per la ricerca per impostazione predefinita e non richiede un'implementazione speciale. Se possibile, preferisci l'utilizzo di <details> rispetto a hidden="until-found".

Se invece devi utilizzare hidden="until-found", segui queste istruzioni:

  1. Applica l'attributo: aggiungi l'attributo HTML hidden="until-found" direttamente agli elementi contenenti i contenuti che devono essere nascosti alla vista.
  2. Sincronizza lo stato della UI: se l'interfaccia ha stati correlati che dipendono dalla visibilità dei contenuti (ad esempio, l'aggiornamento degli attributi ARIA, l'attivazione/disattivazione delle classi CSS di apertura/chiusura o la rotazione delle icone della fisarmonica):
    • DEVI aggiungere un listener di eventi per l'evento beforematch.
    • Registra il listener di eventi beforematch direttamente sull'elemento che contiene l'attributo hidden="until-found". Poiché l'evento si propaga, in alternativa puoi utilizzare la delega degli eventi registrando un singolo listener su un elemento principale (ad esempio un contenitore di schede) per gestire più sezioni nascoste contemporaneamente.
    • All'interno del listener di eventi, esegui la logica per sincronizzare gli elementi UI correlati (ad esempio chiudere altre schede aperte o modificare lo stato di un pulsante di attivazione/disattivazione).

Esempio di codice

Obiettivo: eseguire il rendering di un contenitore nascosto in cui i contenuti rimangono invisibili all'utente finché non cerca una parola all'interno della sezione.

Utilizzo dell'elemento <details>

<details>
  <summary>Click to expand</summary>
  <p>This content is visually hidden.</p>
</details>

Informative che si escludono a vicenda

Quando gestisci regioni di contenuti che si escludono a vicenda, come una fisarmonica esclusiva, utilizza l'elemento HTML nativo <details> con un attributo name condiviso.

<div class="accordion-group">
  <!-- The name attribute creates an exclusive disclosure group -->
  <details class="disclosure" name="my-accordion">
    <summary>Section 1</summary>
    <p>Section 1 content</p>
  </details>

  <details class="disclosure" name="my-accordion" open>
    <summary>Section 2</summary>
    <p>Section 2 content</p>
  </details>

  <details class="disclosure" name="my-accordion">
    <summary>Section 3</summary>
    <p>Section 3 content</p>
  </details>
</div>

Utilizzo dell'attributo hidden="until-found"

<!-- The browser automatically removes hidden="until-found" upon a search match -->
<div class="hidden-container" hidden="until-found">
  <p>This content is visually hidden.</p>
</div>

Informativa personalizzata con opzioni che si escludono a vicenda

Quando gestisci regioni personalizzate che si escludono a vicenda controllate da pulsanti esterni, assicurati che rimanga visibile solo il riquadro corrispondente. Nel gestore di eventi beforematch, DEVI sincronizzare gli stati ARIA correlati, ad esempio impostando aria-expanded="true" sul pulsante di controllo.

<div class="custom-accordion">
  <div class="controls">
    <button aria-expanded="true" aria-controls="panel-1" id="btn-1">Section 1</button>
    <button aria-expanded="false" aria-controls="panel-2" id="btn-2">Section 2</button>
  </div>

  <div id="panel-1" class="panel">
    <p>Section 1 content (visible)</p>
  </div>

  <div id="panel-2" class="panel" hidden="until-found">
    <p>Section 2 content (hidden)</p>
  </div>
</div>
const accordion = document.querySelector('.custom-accordion');

accordion.addEventListener('beforematch', (e) => {
  // Hide all panels and synchronize button states before the browser reveals the matched panel
  accordion.querySelectorAll('.panel').forEach((panel) => {
    if (panel !== e.target) {
      panel.hidden = 'until-found';
    }
  });
  accordion.querySelectorAll('button').forEach((btn) => {
    const controls = btn.getAttribute('aria-controls');
    btn.setAttribute('aria-expanded', controls === e.target.id ? 'true' : 'false');
  });
});

Best practice per hidden="until-found"

  • SÌ: applica bordi, spaziatura interna e sfondi ai wrapper secondari nidificati anziché direttamente all'elemento con l'attributo hidden="until-found". In questo modo si evitano variazioni involontarie del layout o residui visivi mentre l'elemento è nascosto.
  • NON applicare display: none, visibility: hidden o qualsiasi proprietà CSS display o visibility associata direttamente agli elementi con l'attributo hidden="until-found". In questo modo, la funzionalità nativa viene interrotta e i contenuti vengono nascosti definitivamente dall'indice della Ricerca.
  • NON utilizzare hidden="until-found" per informazioni sensibili, token di dati interni o dati irrilevanti che non devono essere esposti tramite la ricerca.
  • NON utilizzare hidden="until-found" in sostituzione del testo "solo per screen reader" (.sr-only).

Supporto del browser e strategie di riserva

NON evitare hidden="until-found" a causa della mancanza di supporto del browser, poiché i vantaggi in termini di accessibilità superano di gran lunga il costo dell'implementazione di un fallback.

hidden="until-found" di riserva

Per gli elementi UI standard, come le sezioni a fisarmonica o "Leggi di più", utilizza JavaScript per il rilevamento delle funzionalità e mostra tutti i contenuti se la funzionalità non è supportata.

if (!('onbeforematch' in HTMLElement.prototype)) {
  // Expand all hidden content for unsupported browsers
  document.querySelectorAll('[hidden="until-found"]').forEach((el) => {
    el.removeAttribute('hidden');
    // MANDATORY: also update any aria references to this element.
  });
}

Per i paradigmi di UI che si escludono a vicenda (come i pannelli esclusivi personalizzati in cui i contenuti condividono la stessa area visiva), il comportamento di riserva deve estrarre e visualizzare tutti i contenuti in modo lineare sotto l'area interattiva principale, utilizzando frammenti di ancoraggio dell'URL per consentire agli utenti di navigare direttamente alle rispettive sezioni.