{"id":484,"date":"2014-09-08T12:07:33","date_gmt":"2014-09-08T10:07:33","guid":{"rendered":"https:\/\/alistapart.com\/it\/article\/web-design-radio-comandato\/"},"modified":"2014-09-08T12:07:33","modified_gmt":"2014-09-08T10:07:33","slug":"web-design-radio-comandato","status":"publish","type":"article","link":"https:\/\/alistapart.com\/it\/article\/web-design-radio-comandato\/","title":{"rendered":"Web Design radio-comandato"},"content":{"rendered":"<p><img decoding=\"async\" src=\"http:\/\/alistapart.com\/it\/wp-content\/uploads\/sites\/2\/2014\/09\/n99a.jpg\" border=\"0\" width=\"270\" style=\"float: left;\" \/>Nel nostro mondo responsive le interfacce utente interattive sono una necessit\u00e0. Gli schermi pi\u00f9 piccoli vincolano la quantit\u00e0 di contenuto che pu\u00f2 essere mostrata in un certo momento, quindi abbiamo bisogno di tecniche che tolgano di mezzo la navigazione e le informazioni secondarie fino a quando non diventano necessarie. Abbiamo creato molti design pattern efficaci, dai tab ai modal overlay per nascondere la navigazione, che mostrano e nascondono il contenuto usando JavaScript.<\/p>\n<p>Tuttavia, anche JavaScript pone delle problematiche su mobile: gran variabilit\u00e0 di velocit\u00e0 di rete e di piani dati fanno s\u00ec ogni byte che inviamo abbia un impatto sulla velocit\u00e0 di visualizzazione delle nostre pagine o applicazioni. Quando aggiungiamo JavaScript ad una pagina, tipicamente usiamo un file JavaScript esterno e opzionalmente una libreria (solitamente grande) come jQuery. Queste interfacce non saranno utilizzabili fino a che tutto il contenuto, files JavaScript inclusi, non sar\u00e0 scaricato, creando una prima lenta e fiacca impressione negli utenti.<\/p>\n<p>Se potessimo creare questi pattern per il &#8220;contenuto on demand&#8221; senza dover dipendere da JavaScript, le interfacce si caricherebbero pi\u00f9 rapidamente e gli utenti potrebbero interagire con loro non appena diventano visibili. Spostando parte della funzionalit\u00e0 in CSS, potremmo anche ridurre la quantit\u00e0 di JavaScript necessario per mostrare il resto della nostra pagina. Il risultato sarebbe un file di dimensioni minori, tempi di caricamento della pagina pi\u00f9 rapidi, interfacce disponibili prima pur mantenendo la stessa funzionalit\u00e0 dei design pattern a cui siamo abituati.<\/p>\n<p>In questo articolo, esplorer\u00f2 una tecnica su cui sto lavorando che fa proprio questo. \u00c8 ancora un po&#8217; sperimentale, quindi valutate davvero bene se usarla nei vostri ambienti di produzione.<\/p>\n<div class=\"paragrafo\">\n<h2>Comprendiamo il ruolo di JavaScript nel mantenere lo stato<\/h2>\n<p>Per capire in che modo possiamo ottenere questi design pattern senza usare JavaScript, esaminiamo prima il ruolo giocato da JavaScript nel mantenere lo stato per una semplice interfaccia a tab.<\/p>\n<p class=\"codepen\">Guarda la demo su Codepen: <a href=\"http:\/\/codepen.io\/artlawry\/pen\/aKbBf\">Esempio Show\/hide (JavaScript Tabs &#8211; No ARIA)<\/a><\/p>\n<p>Diamo un&#8217;occhiata pi\u00f9 nel dettaglio al codice sottostante.<\/p>\n<pre><code>&lt;div class=\"js-tabs\"&gt;\n\n    &lt;div class=\"tabs\"&gt;\n        &lt;a href=\"#starks-panel\" id=\"starks-tab\"\n            class=\"tab active\"&gt;Starks&lt;\/a&gt;\n        &lt;a href=\"#lannisters-panel\" id=\"lannisters-tab\"\n            class=\"tab\"&gt;Lannisters&lt;\/a&gt;\n        &lt;a href=\"#targaryens-panel\" id=\"targaryens-tab\"\n            class=\"tab\"&gt;Targaryens&lt;\/a&gt;\n    &lt;\/div&gt;\n\n    &lt;div class=\"panels\"&gt;\n        &lt;ul id=\"starks-panel\" class=\"panel active\"&gt;\n            &lt;li&gt;Eddard&lt;\/li&gt;\n            &lt;li&gt;Caitelyn&lt;\/li&gt;\n            &lt;li&gt;Robb&lt;\/li&gt;\n            &lt;li&gt;Sansa&lt;\/li&gt;\n            &lt;li&gt;Brandon&lt;\/li&gt;\n            &lt;li&gt;Arya&lt;\/li&gt;\n            &lt;li&gt;Rickon&lt;\/li&gt;\n        &lt;\/ul&gt;\n        &lt;ul id=\"lannisters-panel\" class=\"panel\"&gt;\n            &lt;li&gt;Tywin&lt;\/li&gt;\n            &lt;li&gt;Cersei&lt;\/li&gt;\n            &lt;li&gt;Jamie&lt;\/li&gt;\n            &lt;li&gt;Tyrion&lt;\/li&gt;\n        &lt;\/ul&gt;\n        &lt;ul id=\"targaryens-panel\" class=\"panel\"&gt;\n            &lt;li&gt;Viserys&lt;\/li&gt;\n            &lt;li&gt;Daenerys&lt;\/li&gt;\n        &lt;\/ul&gt;\n    &lt;\/div&gt;\n\n&lt;\/div&gt;\n<\/code><\/pre>\n<p>Nulla di strano nel layout, solo un insieme di tab e dei corrispondenti pannelli (panel) che verranno mostrati quando si seleziona un tab. Diamo ora un&#8217;occhiata al modo in cui viene gestito lo stato del tab alterandone la class.<\/p>\n<pre><code>...\n\n.js-tabs .tab {\n    \/* inactive styles go here *\/\n}\n.js-tabs .tab.active {\n    \/* active styles go here *\/\n}\n\n.js-tabs .panel {\n    \/* inactive styles go here *\/\n}\n.js-tabs .panel.active {\n    \/* active styles go here *\/\n}\n\n...\n<\/code><\/pre>\n<p>I tab e i panel che hanno una class &#8220;active&#8221; avranno delle ulteriori regole CSS applicate per evidenziarli. Nel nostro caso, i tab &#8220;active&#8221; saranno collegati visivamente al loro contenuto mentre i tab non attivi rimarranno separati, i panel attivi saranno visibili mentre quelli inattivi rimarranno nascosti.<\/p>\n<p>A questo punto, usereste il vostro metodo di lavoro JavaScript preferito per ascoltare i &#8220;click event&#8221; sulle tab, poi manipolereste la class <code>active<\/code>, rimuovendola da tutti i tab e panel, aggiungendola al tab appena cliccato e al corrispondente panel. Questo pattern \u00e8 piuttosto flessibile e ha funzionato bene per molto tempo. Possiamo semplificare quello che succede in due parti distinte:<\/p>\n<ol>\n<li>JavaScript fa il bind degli eventi che manipolano le classi.<\/li>\n<li>CSS crea un nuovo stile per gli elementi basati su quelle classi.<\/li>\n<\/ol>\n<h3>Gestione dello stato senza JavaScript<\/h3>\n<p>Cercare di replicare il binding degli eventi e la manipolazione delle classi solo in HTML e CSS sarebbe impossibile, ma se definiamo il processo in termini pi\u00f9 ampi, diventa:<\/p>\n<ol>\n<li>L&#8217;input da parte dell&#8217;utente cambia lo stato attivo del sistema.<\/li>\n<li>Il sistema viene visualizzato nuovamente quando cambia lo stato.<\/li>\n<\/ol>\n<p>Nella nostra soluzione costituita solo da HTML e CSS, useremo i radio button per permettere all&#8217;utente di manipolare lo stato e la pseudo-classe <code>:checked<\/code> come hook per ri-visualizzare.<\/p>\n<p>Questa soluzione ha le sue radici nel <a href=\"http:\/\/css-tricks.com\/the-checkbox-hack\/\">checkbox hack<\/a> di Chris Coyier, che mi fu presentato dal mio collega Scott O&#8217;Hara con la sua demo del <a href=\"http:\/\/www.scottohara.me\/article\/css-morph-menu-button.html\">morphing menu button<\/a>. In entrambe i casi, i checkbox input vengono usati per mantenere due stati senza JavaScript e assegnare gli stili agli elementi con la pseudo-classe <code>:checked<\/code>. In questo caso, user\u00f2 i radio button per poter mantenere pi\u00f9 di due stati.<\/p>\n<\/div>\n<div class=\"paragrafo\">\n<h2>Cosa? I radio button?<\/h2>\n<p>Utilizzare i radio button per fare qualcosa che non sia la raccolta di dati inviati tramite form potrebbe far sentire a disagio pi\u00f9 di una persona, ma diamo un&#8217;occhiata a <a href=\"http:\/\/www.w3.org\/TR\/html5\/forms.html#the-input-element\">quello che dice il W3C<\/a> sull&#8217;uso degli input e vediamo se possiamo sciogliere qualche dubbio:<\/p>\n<blockquote>\n<p>L&#8217;elemento <code>&lt;input&gt;<\/code> rappresenta un campo dati inseriti via computer, solitamente con un form control per <strong>permettere all&#8217;utente di modificare<\/strong> i <strong>dati<\/strong>. (L&#8217;enfasi \u00e8 mia).<\/p>\n<\/blockquote>\n<p>&#8220;Dati&#8221; \u00e8 un termine piuttosto generico e deve esserlo per coprire la moltitudine di tipi di dati che vengono raccolti dalle form. <em>Permettiamo all&#8217;utente di modificare<\/em> lo <em>stato<\/em> di una parte della pagina. Lo stato non \u00e8 altro che un dato riguardante quella parte della pagina in ogni momento. Questo potrebbe non essere l&#8217;uso designato di <code>&lt;input&gt;<\/code>, ma siamo comunque fedeli alla specifica.<\/p>\n<p>Il W3C afferma inoltre che gli input potrebbero essere resi ovunque si pu\u00f2 usare del &#8220;contenuto di enunciazione&#8221;, ossia praticamente ovunque mettereste del testo autonomo. Questo ci permette di usare i radio button al di fuori di una form.<\/p>\n<\/div>\n<div class=\"paragrafo\">\n<h2>Tab radiocomandati<\/h2>\n<p>Perci\u00f2, adesso che sappiamo un po&#8217; di pi\u00f9 riguardo al <em>poter<\/em> usare i radio button per questo scopo, utilizziamo un esempio per vedere <em>in che modo<\/em> possono effettivamente rimuovere o ridurre la nostra dipendenza da JavaScript modificando il nostro esempio iniziale dei tab.<\/p>\n<h3>Aggiungere radio button che rappresentino lo stato<\/h3>\n<p>Ogni radio button rappresenter\u00e0 uno stato del componente interattivo. Nel nostro caso, abbiamo tre tab e ciascun tab pu\u00f2 essere attivo, quindi abbiamo bisogno di tre radio button, ciascuno dei quali rappresenter\u00e0 un particolare tab nello stato attivo. Dando ai radio button lo stesso nome, siamo sicuri che soltanto uno potr\u00e0 essere &#8220;checked&#8221; in un qualunque istante. Il nostro esempio JavaScript inizialmente aveva il primo tab attivo, quindi possiamo aggiungere l&#8217;attributo <code>checked<\/code> al radio button che rappresenta il primo tab, indicando che attualmente \u00e8 attivo.<\/p>\n<p>Dal momento che i selettori CSS possono solo assegnare stili ai selettori &#8220;sibling&#8221; o &#8220;child&#8221; basandosi sullo stato di un altro elemento, questi radio button devono trovarsi <em>prima<\/em> di qualunque contenuto che debba essere visivamente manipolato. Nel nostro caso, metteremo i nostri radio button proprio prima del <code>div<\/code> dei tab:<\/p>\n<pre><code>    \n    &lt;input class=\"state\" type=\"radio\" name=\"houses-state\"\n        id=\"starks\" checked \/&gt;\n    &lt;input class=\"state\" type=\"radio\" name=\"houses-state\"\n        id=\"lannisters\" \/&gt;\n    &lt;input class=\"state\" type=\"radio\" name=\"houses-state\"\n        id=\"targaryens\" \/&gt;\n\n    &lt;div class=\"tabs\"&gt;\n    ...\n<\/code><\/pre>\n<h3>Sostituire le aree di click e touch con i label<\/h3>\n<p>I label rispondono naturalmente agli eventi click e touch. Non possiamo dire loro <em>in che modo<\/em> reagire a questi eventi, ma il comportamento \u00e8 prevedibile e noi possiamo sfruttarlo. Quando si clicca o si tocca un label associato ad un radio button, questo viene contrassegnato e la spunta viene tolta da qualsiasi altro radio button dello stesso gruppo.<\/p>\n<p>Impostando l&#8217;attributo <code>for<\/code> dei nostri lebel all&#8217;<code>id<\/code> di un particolare radio button, possiamo sistemare i label ovunque ne abbiamo bisogno ereditando ancora il comportamento al touch e al click.<\/p>\n<p>Nell&#8217;esempio di prima, i nostri tab erano rappresentati da ancore. Sostituiamole con i label e aggiungiamo gli attributi <code>for<\/code> per collegarli ai radio button corretti. Possiamo anche eliminare la classe <code>active<\/code> da tab e panel poich\u00e9 i radio button manterranno lo stato:<\/p>\n<pre><code>...\n    &lt;input class=\"state\" type=\"radio\" title=\"Targaryens\"\n        name=\"houses-state\" id=\"targaryens\" \/&gt;\n\n    &lt;div class=\"tabs\"&gt;\n        &lt;label for=\"starks\" id=\"starks-tab\"\n            class=\"tab\"&gt;Starks&lt;\/label&gt;\n        &lt;label for=\"lannisters\" id=\"lannisters-tab\"\n            class=\"tab\"&gt;Lannisters&lt;\/label&gt;\n        &lt;label for=\"targaryens\" id=\"targaryens-tab\"\n            class=\"tab\"&gt;Targaryens&lt;\/label&gt;\n    &lt;\/div&gt;\n\n    &lt;div class=\"panels\"&gt;\n...\n<\/code><\/pre>\n<h3>Nascondere i radio button con CSS<\/h3>\n<p>Ora che abbiamo sistemato i label, possiamo tranquillamente nascondere i radio button. Vogliamo ancora che i tab siano accessibili da tastiera, quindi spostiamo semplicemente i radio button fuori dallo schermo:<\/p>\n<pre><code>...\n\n.radio-tabs .state {\n    position: absolute;\n    left: -10000px;\n}\n\n...\n<\/code><\/pre>\n<h3>Assegnare stili agli stati basandosi su <code>:checked<\/code> piuttosto che <code>.active<\/code><\/h3>\n<p>La pseudo-classe <code>:checked<\/code> ci permette di applicare CSS a un radio button quando \u00e8 selezionato. Il selettore di &#8220;sibling&#8221; <code>~<\/code> ci permette di assegnare stili agli elementi che seguono un elemento allo stesso livello. Combinandoli, possiamo assegnare stili a qualunque cosa ci sia dopo i radio button basandoci sullo stato degli stessi.<\/p>\n<p>Il pattern \u00e8 <code>#radio:checked ~ .something-after-radio<\/code> o, opzionalmente, <code>#radio:checked ~ .something-after-radio .something-nested-deeper<\/code>:<\/p>\n<pre><code>...\n\n.tab {\n    ...\n}\n#starks:checked ~ .tabs #starks-tab,\n#lannisters:checked ~ .tabs #lannisters-tab,\n#targaryens:checked ~ .tabs #targaryens-tab {\n    ...\n}\n\n.panel {\n    ...\n}\n#starks:checked ~ .panels #starks-panel,\n#lannisters:checked ~ .panels #lannisters-panel,\n#targaryens:checked ~ .panels #targaryens-panel {\n    ...\n}\n\n...\n<\/code><\/pre>\n<p>Ora, quando i label del tab vengono cliccati, verr\u00e0 contrassegnato l&#8217;appropriato radio button, che assegner\u00e0 uno stile come se fosse active al tab e al panel corretti. Il risultato:<\/p>\n<p class=\"codepen\">Guarda la demo su Codepen: <a href=\"http:\/\/codepen.io\/artlawry\/pen\/domFD\">Esempio show\/hide (Radio-Controlled Tabs &#8211; No ARIA)<\/a><\/p>\n<\/div>\n<div class=\"paragrafo\">\n<h2>Browser support<\/h2>\n<p>I requisiti per questa tecnica sono piuttosto pochi. Siamo a posto se un browser supporta la pseudo-classe <code>:checked<\/code> e il sibling selector <code>~<\/code>. Firefox, Chrome e Webkit mobile supportano da sempre questi selettori. Safari ha cominciato a supportarli a partire dalla versione 3 e Opera dalla 9. Internet Explorer ha iniziato a supportare il sibling selector nella versione 7, ma non ha aggiunto il supporto per <code>:checked<\/code> fino alla IE9. Android supporta <code>:checked<\/code> ma ha un bug che gli impedisce di essere a conoscenza dei cambiamenti a un elemento contrassegnato dopo che la pagina \u00e8 stata caricata.<\/p>\n<p>\u00c8 un supporto decente, ma con un pochino di lavoro extra possiamo far s\u00ec che anche Android e le versioni pi\u00f9 vecchie di IE funzionino altrettanto bene.<\/p>\n<h3>Correggere il bug <code>:checked<\/code> di Android 2.3<\/h3>\n<p>In alcune versioni di Android, <code>:checked<\/code> non si aggiorner\u00e0 al cambio di stato di un radio group. Fortunatamente, <a href=\"http:\/\/stackoverflow.com\/questions\/8320530\/webkit-bug-with-hover-and-multiple-adjacent-sibling-selectors\/8320736#8320736\">c&#8217;\u00e8 una fix<\/a> che richiede l&#8217;animazione infinita &#8220;webkit-only&#8221; sul body, mostrata da Tim Pietrusky nel suo <a href=\"http:\/\/timpietrusky.com\/advanced-checkbox-hack\">advanced checkbox hack<\/a>:<\/p>\n<pre><code>...\n\n\/* Android 2.3 :checked fix *\/\n@keyframes fake {\n    from {\n        opacity: 1;\n    }\n    to {\n        opacity: 1\n    }\n}\nbody {        \n    animation: fake 1s infinite;\n}\n\n...\n<\/code><\/pre>\n<h3>JavaScript shim per le vecchie versioni di Internet Explorer<\/h3>\n<p>Se dovete supportare IE7 e IE8, potete aggiungere questo shim in fondo alla vostra pagina all&#8217;interno di un tag script:<\/p>\n<pre><code>document.getElementsByTagName('body')[0]\n.addEventListener('change', function (e) {\n    var radios, i;\n    if (e.target.getAttribute('type') === 'radio') {\n        radios = document.querySelectorAll('input[name=\"' +\n            e.target.getAttribute('name') + '\"]');\n        for (i = 0; i &lt; radios.length; i += 1) {\n            radios[ i ].className = \n                radios[ i ].className.replace(\n                    \/(^|\\s)checked(\\s|$)\/,\n                    ' '\n                );\n            if (radios[ i ] === e.target) {\n                radios[ i ].className += ' checked';\n            }\n        }\n    }\n});\n<\/code><\/pre>\n<p>Questo aggiunge una class <code>checked<\/code> al radio button attualmente contrassegnato, permettendovi di raddoppiare i selettori e mantenere il supporto. I vostri selettori dovranno essere aggiornati per includere entrambe le versioni di checked, <code>:checked<\/code> e <code>.checked<\/code>, cos\u00ec:<\/p>\n<pre><code>...\n\n.tab {\n    ...\n}\n#starks:checked ~ .tabs #starks-tab,\n#starks.checked ~ .tabs #starks-tab,\n#lannisters:checked ~ .tabs #lannisters-tab,\n#lannisters.checked ~ .tabs #lannisters-tab,\n#targaryens:checked ~ .tabs #targaryens-tab,\n#targaryens.checked ~ .tabs #targaryens-tab {\n    ...\n}\n\n.panel {\n    ...\n}\n#starks:checked ~ .panels #starks-panel,\n#starks.checked ~ .panels #starks-panel,\n#lannisters:checked ~ .panels #lannisters-panel,\n#lannisters.checked ~ .panels #lannisters-panel,\n#targaryens:checked ~ .panels #targaryens-panel,\n#targaryens.checked ~ .panels #targaryens-panel {\n    ...\n}\n\n...\n<\/code><\/pre>\n<p>Usare uno script inline ci fa inoltre risparmiare una potenziale richiesta http e accelera le interazioni nei browser pi\u00f9 nuovi. Quando scegliete di non supportare IE7 e IE8, potete eliminare lo shim senza cambiare alcuna parte del vostro codice.<\/p>\n<\/div>\n<div class=\"paragrafo\">\n<h2>Mantenere l&#8217;accessibilit\u00e0<\/h2>\n<p>Mentre i nostri tab JavaScript inizialmente mostravano la gestione dello stato tra tab che cambiano, un esempio pi\u00f9 robusto dovrebbe utilizzare il progressive enhancement per cambiare tre liste con il titolo in tab. Dovrebbe anche gestire l&#8217;aggiunta di tutti gli ARIA roles e gli attributi che lo screen reader e altre tecnologie assistive usano per navigare i contenuti di una pagina. Un migliore esempio JavaScript potrebbe essere questo:<\/p>\n<p class=\"codepen\">Guarda la demo su Codepen: <a href=\"http:\/\/codepen.io\/artlawry\/pen\/DazeL\">Esempio show\/hide (JavaScript Tabs &#8211; ARIA)<\/a><\/p>\n<p>Parti di HTML vengono rimosse e saranno ora aggiunte con dell&#8217;altro JavaScript; \u00e8 stato aggiunto del nuovo HTML che verr\u00e0 nascosto con del JavaScript in pi\u00f9. \u00c8 stato inoltre aggiunto un nuovo CSS per gestire gli stati pre-enhanced e post-enhanced. In generale, il nostro codice \u00e8 aumentato di un bel po&#8217;.<\/p>\n<p>Per supportare ARIA, in particolar modo per gestire lo stato <code>aria-selected<\/code>, dovremo rimettere del JavaScript nei tab radio-comandati. Tuttavia, la quantit\u00e0 di progressive enhancement che dobbiamo fare \u00e8 enormemente ridotta.<\/p>\n<p>Se non avete familiarit\u00e0 con ARIA o siete un po&#8217; arrugginiti, potreste far riferimento alle <a href=\"http:\/\/www.w3.org\/TR\/wai-aria-practices\/#tabpanel\">ARIA Authoring Practices per tabpanel<\/a>.<\/p>\n<h3>Aggiungere gli ARIA roles e attributes<\/h3>\n<p>Per prima cosa, aggiungeremo il ruolo di <code>tablist<\/code> al <code>div<\/code> contenitore.<\/p>\n<pre><code>&lt;div class=\"radio-tabs\" role=\"tablist\"&gt;\n  \n    &lt;input class=\"state\" type=\"radio\" name=\"houses-state\"\n        id=\"starks\" checked \/&gt;\n    ...\n<\/code><\/pre>\n<p>Poi, aggiungeremo il ruolo di <code>tab<\/code> e l&#8217;attributo <code>aria-controls<\/code> a ciascun radio button. Il valore di <code>aria-controls<\/code> sar\u00e0 l&#8217;<code>id<\/code> del corrispondente panel da mostrare. Inoltre, aggiungeremo i title ad ogni radio button, cos\u00ec che gli screen reader possano associare un label ad ogni tab. Il radio button contrassegnato avr\u00e0 anche <code>aria-selected=\"true\"<\/code>:<\/p>\n<pre><code>&lt;div class=\"radio-tabs\" role=\"tablist\"&gt;\n  \n    &lt;input class=\"state\" type=\"radio\" title=\"Starks\"\n        name=\"houses-state\" id=\"starks\" role=\"tab\"\n        aria-controls=\"starks-panel\" aria-selected=\"true\"checked \/&gt;\n    &lt;input class=\"state\" type=\"radio\" title=\"Lanisters\" \n        name=\"houses-state\" id=\"lannisters\" role=\"tab\" \n        aria-controls=\"lannisters-panel\" \/&gt;\n    &lt;input class=\"state\" type=\"radio\" title=\"Targaryens\" \n        name=\"houses-state\" id=\"targaryens\" role=\"tab\" \n        aria-controls=\"targaryens-panel\" \/&gt;\n\n    &lt;div class=\"tabs\"&gt;\n<\/code><\/pre>\n<p>Nasconderemo i tab visuali dalla tecnologia assistiva perch\u00e9 sono futili interfacce per i veri tab (i radio button). Facciamo ci\u00f2 aggiungendo <code>aria-hidden=\"true\"<\/code> al nostro <code>div<\/code> <code>.tabs<\/code>:<\/p>\n<pre><code>    ...\n    &lt;input class=\"state\" type=\"radio\" title=\"Targaryens\"\n        name=\"houses-state\" id=\"targaryens\" role=\"tab\"\n        aria-controls=\"targaryens-panel\" \/&gt;\n\n    &lt;div class=\"tabs\" aria-hidden=\"true\"&gt;\n        &lt;label for=\"starks\" id=\"starks-tab\"\n            class=\"tab\"&gt;Starks&lt;\/label&gt;\n    ...\n<\/code><\/pre>\n<p>L&#8217;ultimo pezzetto di supporto per ARIA che dobbiamo aggiungere \u00e8 sui panel. Ogni panel avr\u00e0 il ruolo di <code>tabpanel<\/code> e un attributo <code>aria-labeledby<\/code> con il valore del corrispondente id del tab:<\/p>\n<pre><code>   ...\n   &lt;div class=\"panels\"&gt;\n        &lt;ul id=\"starks-panel\" class=\"panel active\"\n            role=\"tabpanel\" aria-labelledby=\"starks-tab\"&gt;\n            &lt;li&gt;Eddard&lt;\/li&gt;\n            &lt;li&gt;Caitelyn&lt;\/li&gt;\n            &lt;li&gt;Robb&lt;\/li&gt;\n            &lt;li&gt;Sansa&lt;\/li&gt;\n            &lt;li&gt;Brandon&lt;\/li&gt;\n            &lt;li&gt;Arya&lt;\/li&gt;\n            &lt;li&gt;Rickon&lt;\/li&gt;\n        &lt;\/ul&gt;\n        &lt;ul id=\"lannisters-panel\" class=\"panel\"\n            role=\"tabpanel\" aria-labelledby=\"lannisters-tab\"&gt;\n            &lt;li&gt;Tywin&lt;\/li&gt;\n            &lt;li&gt;Cersei&lt;\/li&gt;\n            &lt;li&gt;Jamie&lt;\/li&gt;\n            &lt;li&gt;Tyrion&lt;\/li&gt;\n        &lt;\/ul&gt;\n        &lt;ul id=\"targaryens-panel\" class=\"panel\"\n            role=\"tabpanel\" aria-labelledby=\"targaryens-tab\"&gt;\n            &lt;li&gt;Viserys&lt;\/li&gt;\n            &lt;li&gt;Daenerys&lt;\/li&gt;\n        &lt;\/ul&gt;\n    &lt;\/div&gt;\n    ...\n<\/code><\/pre>\n<p>Tutto quello che dobbiamo fare con JavaScript \u00e8 di impostare il valore di <code>aria-selected<\/code> al cambio dei radio button:<\/p>\n<pre><code>$('.state').change(function () {\n    $(this).parent().find('.state').each(function () {\n        if (this.checked) {\n            $(this).attr('aria-selected', 'true');\n        } else {\n            $(this).removeAttr('aria-selected');\n        }       \n    });\n});\n<\/code><\/pre>\n<p>Questo fornisce anche un hook alternativo per il supporto di IE7 e IE8. Entrambe i browser supportano i selettori di attributo, quindi potreste aggiornare il CSS per fargli usare <code>[aria-selected]<\/code> invece di <code>.checked<\/code> e rimuovere lo shim di supporto.<\/p>\n<pre><code>...\n\n#starks[aria-selected] ~ .tabs #starks-tab,\n#lannisters[aria-selected] ~ .tabs #lannisters-tab,\n#targaryens[aria-selected] ~ .tabs #targaryens-tab,\n#starks:checked ~ .tabs #starks-tab,\n#lannisters:checked ~ .tabs #lannisters-tab,\n#targaryens:checked ~ .tabs #targaryens-tab {\n    \/* active tab, now with IE7 and IE8 support! *\/\n}\n\n...\n<\/code><\/pre>\n<p>Il risultato \u00e8 un supporto completo di ARIA con un minimo utilizzo di JavaScript, pur mantenendo i benefici dei tab che possono essere usati non appena il browser li mostra.<\/p>\n<p class=\"codepen\">Guarda la demo su Codepen: <a href=\"http:\/\/codepen.io\/artlawry\/pen\/gbLev\">Esempio Show\/hide (Radio-Controlled Tabs &#8211; ARIA)<\/a><\/p>\n<p>Ecco fatto. Notate che dal momento che l&#8217;HTML sottostante \u00e8 disponibile fin da subito, a differenza dell&#8217;esempio iniziale con JavaScript, non abbiamo dovuto manipolare o creare dell&#8217;HTML in pi\u00f9. In effetti, a parte aggiungere gli ARIA roles e i parametri, dopo tutto non abbiamo dovuto fare granch\u00e9.<\/p>\n<\/div>\n<div class=\"paragrafo\">\n<h2>Limitazioni da tenere a mente<\/h2>\n<p>Come la maggior parte delle tecniche, anche questa ha alcune limitazioni. La prima e pi\u00f9 importante \u00e8 che lo stato di queste interfacce \u00e8 transitorio. Quando si fa il refresh della pagina, queste interfacce ritorneranno al loro stato iniziale. Questo funziona bene per alcuni pattern, come le modali o i menu offscreen, e meno bene per altri. Se avete bisogno di persistenza nello stato della vostra interfaccia, \u00e8 sempre meglio usare i link, le form submission o le AJAX requests per essere sicuri che il server possa tenere traccia dello stato tra le visite o i page load.<\/p>\n<p>La seconda limitazione \u00e8 che c&#8217;\u00e8 uno &#8220;scope gap&#8221; in quello che pu\u00f2 ricevere stili usando questa tecnica. Dal momento che non si possono mettere i radio button prima degli elementi <code>&lt;body&gt;<\/code> o <code>&lt;html&gt;<\/code> e potete solo assegnare uno stile agli elementi che seguono i radio button, non potete influenzare alcun altro elemento con questa tecnica.<\/p>\n<p>La terza limitazione \u00e8 che potete applicare questa tecnica solo alle interfacce che vengono attivate mediante un click, un tap o un input da tastiera. Potete usare il progressive enhancement per ascoltare interazioni pi\u00f9 complesse come lo scrolling, gli swipes, il double-tap o il multitouch, ma se le vostre interfacce sono basate solo su questi eventi, le tecniche standard di progressive enhnacement potrebbero andare meglio.<\/p>\n<p>La limitazione finale riguarda il modo in cui i radio group interagiscono con il flusso dei tab nel documento. Se avete notato nell&#8217;esempio dei tab, toccare un tab vi porta nel tab group, ma ritoccandolo di nuovo rimanete nello stesso gruppo. Questo va bene per i tab ed \u00e8 il comportamento atteso per le ARIA tablist, ma se volete usare questa tecnica per qualcosa come un pulsante di apertura e chiusura, dovrete essere in grado di avere entrambe i pulsanti nel flusso dei tab della pagina indipendentemente dalla posizione del pulsante. Possiamo sistemare in quattro passi questa situazione con un po&#8217; di JavaScript:<\/p>\n<ol>\n<li>Impostate i radio button e i label a <code>display: none<\/code> per toglierli dal flusso dei tab e non mostrarli sulla pagina.<\/li>\n<li>Usate JavaScript per aggiungere <code>buttons<\/code> dopo ciascun <code>label<\/code>.<\/li>\n<li>Assegnate uno stile ai button proprio come ai label.<\/li>\n<li>Ascoltate i click sul <code>button<\/code> e fate in modo che i click partano sui <code>label<\/code> vicini.<\/li>\n<\/ol>\n<p>Anche usando questo processo, vi raccomando caldamente di usare una tecnica standard di progressive enhancement per essere sicuri che gli utenti senza JavaScript che interagiscono con le vostre interfacce mediante tastiera non siano confusi dai radio button. Raccomando il seguente JavaScript da inserire nella head del vostro documento:<\/p>\n<pre><code>&lt;script&gt;document.documentElement.className+=\" js\";&lt;\/script&gt;\n<\/code><\/pre>\n<p>Prima che qualsiasi contenuto venga mostrato, questo aggiunger\u00e0 la classe <code>js<\/code> al vostro elemento <code>&lt;html&gt;<\/code>, permettendovi di assegnare uno stile al contenuto a seconda se il JavaScript sia attivo oppure no. Il vostro CSS quindi sar\u00e0 simile a questo:<\/p>\n<pre><code>.thing {\n    \/* base styles - when no JavaScript is present\n       hide radio button labels, show hidden content, etc. *\/\n}\n\n.js .thing {\n    \/* style when JavaScript is present\n       hide content, show labels, etc. *\/\n}\n<\/code><\/pre>\n<p>Ecco un esempio di menu offscreen implementato usando il processo di cui sopra. Se JavaScript \u00e8 disabilitato, il menu appare sempre aperto senza alcun overlay:<\/p>\n<p class=\"codepen\">Guarda la demo su Codepen: <a href=\"http:\/\/codepen.io\/artlawry\/pen\/wsbfC\">Esempio show\/hide (Radio-Controlled Offscreen Menu)<\/a><\/p>\n<\/div>\n<div class=\"paragrafo\">\n<h2>Implementare altri pattern di &#8220;contenuto on demand&#8221;<\/h2>\n<p>Diamo una rapida occhiata al modo in cui potreste creare alcune interfacce utente comuni con questa tecnica. Tenete a mente che una robusta implementazione gestir\u00e0 l&#8217;accessibilit\u00e0 attraverso gli ARIA roles e gli attributes.<\/p>\n<h3>Finestre modali con overlay<\/h3>\n<ul>\n<li>Due radio button che rappresentano la visibilit\u00e0 della modale<\/li>\n<li>Uno o pi\u00f9 label per modal-open che possono avere qualsiasi aspetto<\/li>\n<li>Un label per modal-close con stili che lo facciano sembrare un overlay semitrasparente<\/li>\n<li>Un label per modal-close con stili che lo facciano sembrare un pulsante chiuso<\/li>\n<\/ul>\n<p class=\"codepen\">Guarda la demo su Codepen: <a href=\"http:\/\/codepen.io\/artlawry\/pen\/npsCd\">Esempio show\/hide (Radio-Controlled Modal Window)<\/a><\/p>\n<h3>Menu offscreen<\/h3>\n<ul>\n<li>Due radio button che rappresentano la visibilit\u00e0 del menu<\/li>\n<li>Un label per menu-open con stili che lo facciano sembrare un menu button<\/li>\n<li>Un label per menu-close con stili che lo facciano sembrare un overlay semi-trasparente<\/li>\n<li>Un label per menu-close con stili che lo facciano sembrare un pulsante chiuso<\/li>\n<\/ul>\n<p class=\"codepen\">Guarda la demo su Codepen: <a href=\"http:\/\/codepen.io\/artlawry\/pen\/wsbfC\">Esempio show\/hide (Radio-Controlled Offscreen Menu)<\/a><\/p>\n<h3>Cambio di layout su richiesta<\/h3>\n<ul>\n<li>Radio button che rappresentino ciascun layout<\/li>\n<li>Label per ciascun radio button con stili da pulsanti<\/li>\n<\/ul>\n<p class=\"codepen\">Guarda la demo su Codepen: <a href=\"http:\/\/codepen.io\/artlawry\/pen\/gbehv\">Esempio show\/hide (Radio-Controlled Layout Manipulation)<\/a><\/p>\n<h3>Cambio di stili su richiesta<\/h3>\n<ul>\n<li>Radio button che rappresentino ciascuno stile<\/li>\n<li>Label per ogni radio button con stili da pulsanti<\/li>\n<\/ul>\n<p class=\"codepen\">Guarda la demo su Codepen: <a href=\"http:\/\/codepen.io\/artlawry\/pen\/ncAfK\">Esempio show\/hide (Radio-Controlled Style Manipulation)<\/a><\/p>\n<h3>Content carousels<\/h3>\n<ul>\n<li>X radio button, uno per ciascun panel, rappresentanti il panel attivo<\/li>\n<li>Label per ciascun panel con stili che li facciano apparire come controlli pagina precedente\/successiva<\/li>\n<\/ul>\n<p class=\"codepen\">Guarda la demo su Codepen: <a href=\"http:\/\/codepen.io\/artlawry\/pen\/ioCaA\">Esempio show\/hide (Radio-Controlled Carousel)<\/a><\/p>\n<h3>Altre interfacce touch-based o click-based<\/h3>\n<p>Finch\u00e9 l&#8217;interazione non dipende dall&#8217;aggiunta di nuovo contenuto alla pagina o dall&#8217;assegnare stili all&#8217;elemento <code>&lt;body&gt;<\/code>, dovreste essere in grado di utilizzare questa tecnica per ottenere alcune interazioni molto simili a quelle in JavaScript.<\/p>\n<p>Occasionalmente, dovrete gestire pi\u00f9 stati sovrapposti nello stesso sistema, ad esempio il colore e la dimensione di un font. In queste situazioni, potrebbe essere pi\u00f9 semplice mantenere insiemi multipli di radio button per gestire ciascun stato.<\/p>\n<p>\u00c8 inoltre <em>caldamente<\/em> raccomandato usare <code>autocomplete=\"off\"<\/code> con i radio button per evitare conflitti con l&#8217;autofill delle form da parte dei browser, che potrebbe far cambiare stato ai vostri utenti.<\/p>\n<\/div>\n<div class=\"paragrafo\">\n<h2>Radio-comandare il web?<\/h2>\n<p>Il vostro progetto \u00e8 adatto a questa tecnica? Fatevi queste domande:<\/p>\n<ol>\n<li>Nella mia pagina o nel mio sito, sto usando un JavaScript complesso che non pu\u00f2 essere gestito con questa tecnica?<\/li>\n<li>Devo supportare Internet Explorer 6 o altri browser legacy?<\/li>\n<\/ol>\n<p>Se la risposta ad una qualunque di queste domande \u00e8 &#8220;s\u00ec&#8221;, probabilmente non dovreste cercare di integrare i radio control nel vostro progetto. Altrimenti potreste prenderli in considerazione come una robusta tecnica di progressive enhancement.<\/p>\n<p>La maggior parte delle volte, sarete in grado di eliminare un po&#8217; di byte dai vostri files JavaScript e CSS. Occasionalmente, sarete anche in grado di eliminare completamente JavaScript. In ogni caso, guadagnerete l&#8217;impressione della velocit\u00e0 e creerete un&#8217;esperienza molto pi\u00f9 gradevole per i vostri utenti.<\/p>\n<p>Illustrazioni: {carlok}<\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Tab, modal overlay, navigazione nascosta: abbiamo sviluppato molti pattern che ci aiutano nella progettazione di design per schermi mobile, ma questi pattern tendono a mostrare e a nascondere il contenuto usando JavaScript, che gi\u00e0 di per s\u00e9 pone delle sfide. Art Lawry esplora delle tecniche per ridurre questa dipendenza da JavaScript usando un&#8217;improbabile tool: i radio button.<\/p>\n","protected":false},"author":818,"featured_media":7000741,"comment_status":"open","ping_status":"open","template":"","categories":[244,247,271,116],"tags":[],"coauthors":[428],"class_list":["post-484","article","type-article","status-publish","has-post-thumbnail","hentry","category-css","category-html","category-javascript","category-numero-99-8-settembre-2014"],"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/article\/484","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/article"}],"about":[{"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/types\/article"}],"author":[{"embeddable":true,"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/users\/818"}],"replies":[{"embeddable":true,"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/comments?post=484"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/media\/7000741"}],"wp:attachment":[{"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/media?parent=484"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/categories?post=484"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/tags?post=484"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/coauthors?post=484"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}