Nascondere un elemento con i CSS in modo accessibile

I problemi nell’utilizzo del display:none e le alternative possibili.

Nella realizzazione di un sito è ricorrente la necessità di nascondere elementi presenti nel codice HTML: basti pensare agli skip link o alle tecniche di image replacement. Ci sono diversi modi per farlo con i CSS, ma non tutti sono corretti.

Evitare il display:none

Un metodo diffuso, che però è sbagliato, è utilizzare display: none per nascondere totalmente la parte di codice desiderata. Questa tecnica è inaccessibile, perchè elimina l’elemento dalla pagina come se non esistesse. La maggior parte degli screen reader trovando un elemento con display: none lo salterà senza leggerlo.

Pensate all’intestazione di un sito ed ai link per facilitare la navigazione nascosti in questo modo: non facendoli leggere agli screen reader l’accessibilità della pagina viene compromessa.

Trovate anche un approfondimento sul comportamento degli screen reader in questo articolo di Roger Johansson.

La soluzione con position:absolute

La soluzione più semplice è utilizzare position: absolute invece di display: none:

.skip {
position: absolute;
left: -9999px;
}

In questo modo gli screen reader continueranno a leggere l’elemento nascosto. Per migliorare ulteriormente l’accessibilità della pagina con un occhio di riguardo alla navigazione da tastiera, è utile un’aggiunta del tipo:

.skip a:active, .skip a:focus {
position: absolute;
left: 1em;
}

Così usando il tasto tab per spostarsi tra i collegamenti della pagina, gli elementi nascosti appariranno quando selezionati.

L’alternativa: text-indent

Una soluzione alternativa per nascondere un elemento della pagina può essere la proprietà text-indent, con un valore negativo:

.skip {
text-indent: -9999px;
}

Questo metodo a volte viene usato per mantenere l’elemento contenitore nella pagina, facendo sparire solo il suo contenuto testuale. E’ da verificare nei vari casi il supporto dei browser, ma tutti quelli più importanti non dovrebbero avere problemi.

Testo nascosto con JavaScript

Un ultimo aspetto da considerare è la gestione di elementi della pagina che appaiono solo dopo un’azione dell’utente, usando JavaScript. E’ sbagliato nasconderli con i CSS: se questi elementi (ad esempio un menu a tendina) appaiono grazie a JavaScript, devono essere nascosti al caricamento della pagina secondo lo stesso principio.

La tecnica più semplice è usare JavaScript per assegnare una classe all’elemento desiderato e quindi nasconderlo (senza usare display: none!) tramite CSS.

E’ importante comprendere i problemi relativi al display: none descritti in questo articolo. Usandolo con cognizione di causa eviterete dei problemi ai vostri utenti: se conoscete altre soluzioni valide i commenti sono a vostra disposizione.

Vuoi far crescere il tuo progetto online?

Tommaso Baldovino

UX/UI Designer, professionista del web con più di 15 anni di esperienza su WordPress. Sono disponibile a seguire nuovi progetti dall'ideazione alla realizzazione finale. Scrivo ogni 2 settimane la mia newsletter.

17 commenti su “Nascondere un elemento con i CSS in modo accessibile”

  1. Se lo scopo è nasconderlo dalla lettura secondo me và bene.
    Se invece si vogliono creare effetti carini visivamente in effetti ci sono soluzioni migliori, come hai illustrato ;)

  2. Non capisco…

    “Un metodo diffuso, che però è sbagliato, è utilizzare display: none per nascondere totalmente la parte di codice desiderata. Questa tecnica è inaccessibile, perchè elimina l’elemento dalla pagina come se non esistesse. La maggior parte degli screen reader trovando un elemento con display: none lo salterà senza leggerlo.”

    Ma, se io uso display:none vuol dire che non voglio che quel div venga visualizzato, quindi MI VA BENE che non lo leggano nemmeno gli screen reader. Di solito io lo uso per poi poterlo modificare dopo tramite javascript, e renderlo visibile quando voglio io. Una volta modificata la proprieta’, sara’ in grado di visualizzarlo anche lo screen reader…

  3. @wse: sì, gli screen reader come JAWS leggono i CSS, è proprio quello il motivo per cui bisogna fare attenzione all’utilizzo del display: none. Se non sbaglio non succede in tutte le versioni, ma le più recenti si comportano così di default.

    Ci sono poi utenti che disabilitano i CSS e quindi non hanno problemi di questo tipo, ma la maggioranza mantiene le impostazioni standard, come è logico aspettarsi.

  4. @Foo: il problema è che così consideri JavaScript un requisito necessario per leggere la tua pagina. Ho cercato di spiegarlo nell’ultimo paragrafo: meglio fare in modo che tutti i contenuti siano inizialmente leggibili, e nasconderli successivamente con JavaScript.

  5. Io ho usato spesso e volentieri display:none proprio per un discorso di accessibilità, ovvero per inserire nel sito menù di navigazione rapida, titoli di testi che per motivi di design sul sito non ne hanno, o elementi tipo link #top per tornare al menù di navigazione rapida.
    Disabilitando i CSS il tutto è perfetto, la navigazione è intuitiva e semplice. Ma se gli screen reader non leggono “display:none” credo che dovrò usare { position: absolute; left: -9999px; }
    Non l’avevo mai usato prima pensando che non fosse un codice molto gradito ai motori di ricerca. Che ne pensi Tom?
    Due siti dove ho implementato accessibilità e questa regola css in partcolare sono http://www.ordineavvocatipesaro.it e http://www.serigrafiadia.it
    Che ve ne pare? (a livello usabilità/accessibilità ovviamente)

  6. @Marco Pedota: per quanto riguarda skip link e contenuti nascosti che hanno un’alternativa grafica (es. titoli con image replacement) non ho mai avuto problemi con i motori di ricerca, non ci sono rischi, quindi vai tranquillo. Google penalizza quando ci sono contenuti nascosti senza motivo, che contengono delle keyword.

  7. ciao tom…
    ti leggo da tanto, ma non sono mai intervenuto…
    stanotte ho un dubbio relativo al nascondimento di elementi via css… vorrei discuterlo con te…
    l’utilizzo di visibility:hidden; può essere considerato accessibile?

    così (su WP):

    markup:
    <h1><a href="<?php echo get_settings(‘home’); ?>" title="Vai alla home page"><img src="<?php bloginfo(‘template_directory’); ?>/img/logo.png" alt="logo <?php bloginfo(‘name’);?>" /><span><?php bloginfo(‘name’);?></span></a></h1>

    css:
    .header h1 span {
    font-size:1px;
    color: #fff;
    visibility:hidden;
    }

    naturalmente l’aria tra gli elementi regge a una riga di testo di 1px e il colore la confonde col bg…

    :)

  8. @EsseZeta: ciao, grazie per aver deciso di intervenire! Se usi visibility: hidden non hai problemi con gli screen reader, che continueranno a leggere l’elemento.

    Se però il logo che utilizzi ha al suo interno il titolo del blog e non è una semplice immagine, ti consiglio di aggiungerlo come background tramite CSS e non nel codice della pagina, altrimenti uno screen reader leggerà: “Logo Titolo del blog – Titolo del blog”, invece di un più semplice “Titolo del blog”.

    Spero di esserti stato di aiuto :)

  9. solo per ringraziarti dell’attenzione… :)

    la notazione che fai aproposito della duplicazione del titolo-del-blog è giustissima e molto attenta e pertinente…

    per la cronaca, opterò per far leggere allo screen reader “Logo del blog – Titolo-del-blog”… perché devo/voglio lasciare l’immagine nel codice… così ce l’ho anche con css disattivati…

    PS (una curiosità: ne discutevo su Edit nei giorni scorsi): ti capita di realizzare progetti che reggano anche senza css? è un po’ ozioso ed estremo… ma lo è anche lavorare per quando .js è disabilitato (css e js si equivalgono per quanto riguarda la loro presenza/abilitazione), solo che per .js ci impegniamo a non farlo intrusivo, e per css mai (o comunque con minor coscienza)… eppure credo si dia l’opportunita del concetto di “non-intrusive css” (che è un po’ ciò che facciamo quando ordiniamo il markup in maniera SEO oriented con i contenuti “duri” prima del resto e poi spostiamo con margini negativi e simili)

    buona giornata…

  10. @EsseZeta: cerco sempre di fare in modo che i miei siti siano leggibili anche senza CSS, è quello che dovrebbero fare tutti quando sviluppano, scrivendo prima l’HTML e pensando solo dopo alla presentazione.

    Adoro iniziative come il CSS Naked Day (che però non seguo per questioni di target), non so se hai presente. Comunque è vero, non sempre è possibile raggiungere la perfezione, ma è bene impegnarsi per provarci :)

  11. Sono passati tre anni dall’ultimo commento ma il problema è sempre attuale.
    Ultimamente ci sono tanti siti che usano il “responsive design” e in più delle volte bisogna nascondere intere parti del sito (con il display: none) per quelli che si collegano con lo smartphone.
    Anche in questo caso e’ una cosa “sbagliata”? Oppure position: absolute; left: -9999px; è sempre la soluzione migliore?
    E dal punto di vista SEO come si comporta Google?
    grazie

  12. @flo hai pienamente ragione, l’accessibilità dei contenuti resta importante, non solo in ottica SEO ma soprattutto per i visitatori. Parlando di responsive design non ci sono grosse preoccupazioni per i vari “display: none”: Google & co. continuano a leggere la versione integrale del sito, io non mi preoccupo troppo se qualche sezione viene nascosta utilizzando le media query.
    L’importante è utilizzare soluzioni accessibili per i contenuti che hanno un valore aggiunto indipendentemente dal dispositivo.