{"id":471,"date":"2014-07-29T14:27:06","date_gmt":"2014-07-29T12:27:06","guid":{"rendered":"https:\/\/alistapart.com\/it\/article\/accessibilita-ingrediente-mancante\/"},"modified":"2014-07-29T14:27:06","modified_gmt":"2014-07-29T12:27:06","slug":"accessibilita-ingrediente-mancante","status":"publish","type":"article","link":"https:\/\/alistapart.com\/it\/article\/accessibilita-ingrediente-mancante\/","title":{"rendered":"Accessibilit\u00e0: l&#8217;ingrediente mancante"},"content":{"rendered":"<p><img decoding=\"async\" src=\"http:\/\/alistapart.com\/it\/wp-content\/uploads\/sites\/2\/2014\/07\/n95accessibile.png\" border=\"0\" align=\"left\" \/>Tanto tanto tempo fa, trattavo l&#8217;accessibilit\u00e0 web come un extra. Certo, le mie immagini avevano l&#8217;attributo <abbr title=\"alternative text\"><code>alt<\/code><\/abbr>. S\u00ec, i miei link avevano i title. Onoravo anche la <a href=\"http:\/\/webaim.org\/standards\/508\/checklist\">compatibilit\u00e0 con la 508<\/a>, ma solitamente era l&#8217;ultima cosa che facevo. Per come la vedevo, la torta era pronta da mangiare: l&#8217;accessibilit\u00e0 era la glassa decorativa da spalmarci sopra alla fine.<\/p>\n<p>Purtroppo, non ero l&#8217;unico. Molti sviluppatori con cui ho recentemente parlato sembra che mettano l&#8217;accessibilit\u00e0 all&#8217;ultimo posto, sempre che la gestiscano. Perch\u00e9 l&#8217;accessibilit\u00e0 viene spesso trattata come un ripensamento? Tra i motivi principali vanno inclusi la mancanza di tool e specifiche, una bassa domanda da parte del settore e la pigrizia da parte degli sviluppatori.<\/p>\n<p>Tornando alla fine degli anni &#8217;90, l&#8217;accessibilit\u00e0 web era al massimo &#8220;primitiva&#8221;. <abbr title=\"Job Access With Speech\">JAWS<\/abbr> era ancora nella sua infanzia e <abbr title=\"Web Accessibility Initiative - Accessible Rich Internet Applications\"><a href=\"http:\/\/www.w3.org\/TR\/wai-aria\/\">WAI-ARIA<\/a><\/abbr> non era ancora stata concepita. Tutto quello che sembrava avere importanza era quanto rapidamente si potesse impressionare in maniera visuale un utente. <abbr title=\"Dynamic HTML\">DHTML<\/abbr> e Flash dettavano legge e le camicie di flanella piacevano di pi\u00f9 portate legate in vita.<\/p>\n<p>Mentre l&#8217;accessibilit\u00e0 cominciava a prendere velocit\u00e0 nel 2004-2005, molti sviluppatori e molte aziende prestavano ancora poca attenzione alla materia. I web developer erano persi nella magia nera di <abbr title=\"Cascading Style Sheets\">CSS<\/abbr>, nei tutorial PHP e nei libri su JavaScript. In qualit\u00e0 di freelancer con una certa esperienza potevo dire di non aver mai sentito menzionare l&#8217;accessibilit\u00e0 tra i requisiti di un progetto.<\/p>\n<p>Malgrado ora sia ben pubblicizzata e <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/Accessibility\/ARIA\/Web_applications_and_ARIA_FAQ#Where_is_ARIA_Supported.3F\">supportata<\/a>, <abbr title=\"Web Accessibility Initiative - Accessible Rich Internet Applications\">WAI-ARIA<\/abbr>, una specifica progettata specificamente per aiutare gli utenti disabili, non viene implementata spesso da noi sviluppatori. Forse stiamo aspettando che un cliente con una mente portata all&#8217;accessibilit\u00e0 catalizzi il processo di apprendimento. Forse ci sentiamo sopraffatti e non sappiamo da dove cominciare. Qualunque sia la scusa, non \u00e8 pi\u00f9 valida date le risorse e la tecnologia attualmente a nostra disposizione.<\/p>\n<p>Dopo alcuni mesi di lavoro in <a href=\"http:\/\/www.ibm.com\/us\/en\/\" title=\"Link to IBM website\">IBM<\/a>, io e i miei colleghi stavamo devolvendo le nostre ore settimanali ad un&#8217;applicazione web che doveva soddisfare una rigorosa checklist di accessibilit\u00e0. Dovevamo testare attentamente l&#8217;intera applicazione web affinch\u00e9 fosse conforme a <abbr title=\"Web Accessibility Initiative - Accessible Rich Internet Applications\">WAI-ARIA<\/abbr> e alle <abbr title=\"Web Content Accessibility Guidelines\">WCAG<\/abbr>. All&#8217;improvviso, mi venne dato il compito di creare un piano generale che descrivesse nel dettaglio le questioni aperte, oltre a stimare quanto ci avrebbe messo il team per sistemarle. Mettere l&#8217;accessibilit\u00e0 all&#8217;ultimo posto per cos\u00ec tanti anni mi aveva lasciato poco istruito e impreparato.<\/p>\n<p>Attraverso un processo di prove ed errori, con l&#8217;aiuto dei miei colleghi pi\u00f9 edotti e leggendo molto riguardo a questa materia, ne sono uscito come uno sviluppatore diverso. Scrivere codice accessibile non \u00e8 una cosa extra da considerare alla fine di un progetto, ma semplicemente un&#8217;altra cosa da considerare fin dall&#8217;inizio. Vediamo passo a passo un esempio fatto in casa che mostra alcuni utili <abbr title=\"Web Accessibility Initiative - Accessible Rich Internet Applications\">WAI-ARIA<\/abbr> <a href=\"http:\/\/www.w3.org\/TR\/wai-aria\/roles\" title=\"Link to WAI-ARIA roles specification\">roles<\/a>, <a href=\"http:\/\/www.w3.org\/TR\/wai-aria\/states_and_properties\" title=\"Link to WAI-ARIA states and properties specification\">states e properties<\/a>.<\/p>\n<div class=\"paragrafo\">\n<h2>Prima di iniziare<\/h2>\n<p>Gli screen reader, cos\u00ec come i browser, cambiano molto a seconda di chi li produce. Non ho intenzione di fornire un tutorial esaustivo su questo vasto argomento. Sceglier\u00f2 <a href=\"https:\/\/chrome.google.com\/webstore\/detail\/chromevox\/kgejglhpjiefppelpmljglcjbhoiplfn?hl=en\" title=\"Link to ChromeVox download\">ChromeVox<\/a> per questo tutorial perch\u00e9 \u00e8 uno screen reader plugin gratuito che funziona sia su Mac sia su Windows. Comunque, esistono <a href=\"http:\/\/en.wikipedia.org\/wiki\/List_of_screen_readers\">moltissimi altri screen reader<\/a>. Per lo sviluppo web con <abbr title=\"Web Accessibility Initiative - Accessible Rich Internet Applications\">WAI-ARIA<\/abbr>, le scelte pi\u00f9 popolari sono le seguenti:<\/p>\n<h3 id=\"windows_users\">Utenti Windows<\/h3>\n<ul>\n<li><a href=\"http:\/\/www.freedomscientific.com\/products\/fs\/jaws-product-page.asp\">JAWS<\/a><\/li>\n<li><a href=\"http:\/\/www.nvaccess.org\/\">NVDA<\/a><\/li>\n<li><a href=\"https:\/\/www.gwmicro.com\/Window-Eyes\/\">Window-Eyes<\/a><\/li>\n<li><a href=\"https:\/\/chrome.google.com\/webstore\/detail\/chromevox\/kgejglhpjiefppelpmljglcjbhoiplfn?hl=en\">ChromeVox<\/a><\/li>\n<\/ul>\n<h3 id=\"mac_users\">Utenti Mac<\/h3>\n<ul>\n<li><a href=\"http:\/\/www.apple.com\/accessibility\/osx\/voiceover\/\">VoiceOver<\/a><\/li>\n<li><a href=\"https:\/\/chrome.google.com\/webstore\/detail\/chromevox\/kgejglhpjiefppelpmljglcjbhoiplfn?hl=en\">ChromeVox<\/a><\/li>\n<\/ul>\n<h3 id=\"linux_users\">Utenti Linux<\/h3>\n<ul>\n<li><a href=\"https:\/\/wiki.gnome.org\/action\/show\/Projects\/Orca?action=show&amp;redirect=Orca\">Orca<\/a><\/li>\n<\/ul>\n<p>Come gi\u00e0 detto, ogni screen reader \u00e8 unico. Se seguite questa demo con uno screen reader diverso da ChromeVox, noterete delle differenze nel modo in cui la tecnologia assistiva fa il parse di ARIA.<\/p>\n<\/div>\n<div class=\"paragrafo\">\n<h2>Cosa stiamo cercando di ottenere?<\/h2>\n<p>Il nostro cliente vorrebbe uno shopping cart per il suo negozio che vende parti di robot, Robot Shopper. Il carrello deve soddisfare le linee guida di <abbr title=\"Web Accessibility Initiative - Accessible Rich Internet Applications\">WAI-ARIA<\/abbr> e funzionare bene da tastiera. Per testare il nostro carrello con uno screen reader, useremo <a href=\"https:\/\/chrome.google.com\/webstore\/detail\/chromevox\/kgejglhpjiefppelpmljglcjbhoiplfn?hl=en\" title=\"Link to ChromeVox plugin\">ChromeVox<\/a>, che ci permetter\u00e0 di fare l&#8217;esperienza uditiva della nostra pagina web. Quando avremo finito, potrete disabilitare il plugin. Per farlo, andate su chrome:\/\/extensions e togliete la spunta dal box accanto al plugin ChromeVox.<\/p>\n<p>Per gestire gli oggetti nel carrello useremo <a href=\"http:\/\/diveintohtml5.info\/storage.html\" title=\"Link to tutorial on HTML storage\">HTML5 storage<\/a> e useremo un sistema di templating JavaScript con <a href=\"http:\/\/handlebarsjs.com\/\" title=\"Link to Handlebars website\">Handlebars<\/a> per mostrare il markup del nostro magazzino. Per quel che riguarda il design, vogliamo:<\/p>\n<div class=\"illustration full left\"><img decoding=\"async\" src=\"http:\/\/alistapart.com\/it\/wp-content\/uploads\/sites\/2\/2014\/07\/robot_shopper_cart_closed.png\" border=\"0\" alt=\"Visualizzazione iniziale con il carrello chiuso.\" width=\"100%\" \/><\/p>\n<p>Visualizzazione iniziale con il carrello chiuso.<\/p>\n<\/div>\n<div class=\"illustration full left\"><img decoding=\"async\" src=\"http:\/\/alistapart.com\/it\/wp-content\/uploads\/sites\/2\/2014\/07\/robot_shopper_cart_empty.png\" border=\"0\" alt=\"Il carrello \u00e8 aperto e vuoto.\" width=\"100%\" \/><\/p>\n<p>Il carrello \u00e8 aperto e vuoto.<\/p>\n<\/div>\n<div class=\"illustration full left\"><img decoding=\"async\" src=\"http:\/\/alistapart.com\/it\/wp-content\/uploads\/sites\/2\/2014\/07\/robot_shopper_cart_full.png\" border=\"0\" alt=\"Il carrello \u00e8 aperto con degli oggetti.\" width=\"100%\" \/><\/p>\n<p>Il carrello \u00e8 aperto con degli oggetti.<\/p>\n<\/div>\n<h3>Markup iniziale<\/h3>\n<h4><code>first_pass\/index.html<\/code><\/h4>\n<pre><code>&lt;body <strong>role=\"application\"<\/strong>&gt;\n\n\t&lt;div id=\"container\"&gt;\n\t\t&lt;header&gt;\n\t\t\t&lt;h1&gt;Robot Shopper&lt;\/h1&gt;\n\n\t\t\t&lt;button\n\t\t\t\ttitle=\"Cart count\"\n\t\t\t\tid=\"shopping_cart\"&gt;\n\t\t\t&lt;\/button&gt;\n\t\t&lt;\/header&gt;\n\n\t\t&lt;!-- dynamically loaded from our template --&gt;\n\n\t\t&lt;div\n\t\t\tid=\"main\"\n\t\t\ttabindex=\"-1\"&gt;\n\t\t&lt;\/div&gt;\n\n\t\t&lt;footer&gt;\n\t\t\t&lt;p&gt;Robot Shopper \u00a9 2014&lt;\/p&gt;\n\t\t&lt;\/footer&gt;\n\t&lt;\/div&gt;\n\n\t&lt;div\n\t\tid=\"my_cart\"\n\t\ttabindex=\"0\"&gt;\n\n\t\t&lt;div id=\"my_cart_contents\"&gt;&lt;\/div&gt;\n\n\t\t&lt;button\n\t\t\ttitle=\"Close dialog\"\n\t\t\tid=\"close_cart\"&gt;\n\t\t\tx\n\t\t&lt;\/button&gt;\n\t&lt;\/div&gt;\n\n\t&lt;div id=\"page_mask\"&gt;&lt;\/div&gt;\n\t\n&lt;\/body&gt;<\/code><\/pre>\n<h3>Il role application<\/h3>\n<p>Sebbene non fosse mia intenzione buttarmi negli ARIA role al primo passo del codice, aggiungere il role application al <code>body<\/code> \u00e8 obbligatorio per l&#8217;esperienza che vogliamo creare. Questo breve passaggio tratto dallo <a href=\"https:\/\/developer.yahoo.com\/blogs\/ydn\/aria-role-application-53608.html\">Yahoo! Accessibility blog<\/a> cattura bene l&#8217;essenza di questo role:<\/p>\n<blockquote>\n<p>In media, la vostra pagina web \u00e8 un documento. L&#8217;utente si aspetta di leggervi del contenuto e che possa avere dei comportamenti interattivi. Le applicazioni sono pi\u00f9 simili alle applicazioni desktop. L&#8217;utente si aspetta un insieme di strumenti, cambiamenti istantanei, interazioni dinamiche.<\/p>\n<\/blockquote>\n<p>Una feature &#8220;must-have&#8221; della nostra applicazione Robot Shopper \u00e8 che gli utenti possano navigare rapidamente tra le sezioni dei prodotti usando i tasti freccia su e gi\u00f9. Per alcuni screen reader, come NVDA, rimuovere il role application impedir\u00e0 al nostro JavaScript personalizzato di sovrascrivere questi eventi da tastiera. Senza un role application, quando si premono le frecce su e gi\u00f9 si sposter\u00e0 invece il focus tra tutti gli elementi della pagina, che non \u00e8 quello che vogliamo. Usando questo role, stiamo dicendo al browser: &#8220;So quello che faccio, non sovrascrivere i miei comportamenti definiti&#8221;. Tenete a mente che ciascuna regione che dichiariamo come application richiede che noi, gli sviluppatori, implementiamo una navigazione da tastiera personalizzata.<\/p>\n<h3>Il template<\/h3>\n<p>Potreste aver notato nel codice precedente che il nostro <code>div<\/code> principale che era stato designato per la memorizzazione di tutti i nostri prodotti \u00e8 vuoto. Il motivo \u00e8 che il nostro template Handlebars carica immediatamente i dati <abbr title=\"JavaScript Object Notation\">JSON<\/abbr> del nostro prodotto in questo elemento.<\/p>\n<h4><code>first_pass\/index.html<\/code><\/h4>\n<pre><code>&lt;script id=\"all_products\" type=\"text\/x-handlebars-template\"&gt;\n\t&lt;div id=\"product_sections\"&gt;\n\t\t{{#products}}\n\t\t\t&lt;section tabindex=\"-1\"&gt;\n\t\t\t\t&lt;div class=\"product_information\"&gt;\n\t\t\t\t\t&lt;h2 class=\"product_title\"&gt;{{title}}&lt;\/h2&gt;\n\t\t\t\t\t&lt;span class=\"product_price\"&gt;${{price}}&lt;\/span&gt;\n\t\t\t\t&lt;\/div&gt;\n\t\t\t\t&lt;div class=\"product_details\"&gt;\n\t\t\t\t\t&lt;a href=\"#\" title=\"{{title}} details\"&gt;\n\t\t\t\t\t\t&lt;img class=\"product_thumb\" src=\"{{img_uri}}\" alt=\"{{title}}\"&gt;\n\t\t\t\t\t&lt;\/a&gt;\n\t\t\t\t\t&lt;p class=\"product_description\"&gt;{{description}}&lt;\/p&gt;\n\t\t\t\t&lt;\/div&gt;\n\t\t\t\t&lt;button\n\t\t\t\t\ttitle=\"Add to Cart\"\n\t\t\t\t\tclass=\"button add_to_cart\"\n\t\t\t\t\ttab-index=\"0\"\n\t\t\t\t\tdata-pid=\"{{pid}}\"&gt;\n\t\t\t\t\tAdd to Cart\n\t\t\t\t&lt;\/button&gt;\n\t\t\t&lt;\/section&gt;\n\t\t{{\/products}}\n\t&lt;\/div&gt;\n&lt;\/script&gt;<\/code><\/pre>\n<h4><code>first_pass\/products.js<\/code><\/h4>\n<pre><code class=\"language-javascript\">data = { products: [\n\t{\n\t\ttitle: \"Jet Engines\",\n\t\tprice: \"500.00\",\n\t\timg_uri:\t\"http:\/\/goo.gl\/riaO3q\",\n\t\tdescription: \"It's only a jetpack--a simple, high-thrust, fuel-thirsty jetpack. I would add this puppy to the cart. What could go wrong?\",\n\t\tpid: \"product_093A14\"\n\t},\n\t\n\t\u2026\n\n]};\ndocument.getElementById(<strong>\"main\"<\/strong>).innerHTML = <strong>template(data)<\/strong>;<\/code><\/pre>\n<h3>L&#8217;ora di ChromeVox  (<a href=\"https:\/\/alistapart.github.io\/code-samples\/395\/accessibility-the-missing-ingredient\/first_pass\/index.html\" title=\"Link to first pass of demo\">Demo<\/a>)<\/h3>\n<p>Vediamo in azione il nostro Robot Shopper. Nella demo, cliccate su &#8220;Add to Cart&#8221; e vedrete aumentare il contatore del carrello sul torace blu del robot. Semplice, vero? Ma come si traduce questa esperienza nel contesto di uno screen reader?<\/p>\n<p>Per prima cosa, parliamo della navigazione della pagina. Sebbene possiamo usare il tasto &#8220;tab&#8221; per raggiungere l&#8217;anchor del dettaglio del prodotto e i pulsanti &#8220;Add to Cart&#8221;, l&#8217;utente deve premere due volte il tab per attraversare ciascun oggetto: un lavoro fastidioso se l&#8217;utente disabile vuole raggiungere un oggetto molto in basso nella lista usando la tastiera. Abbiamo risolto questo problema aggiungendo la navigazione con i tasti freccia della tastiera.<\/p>\n<h4><code>first_pass\/app.js<\/code><\/h4>\n<pre><code>$(document.documentElement).keyup(function (event) {\n\n\t\u2026\n\n\tif (key_pressed === UP) {\n\t\tdirection = \"prev\";\n\t} else if (key_pressed === DOWN) {\n\t\tdirection = \"next\";\n\t}\n\n\t\u2026\n\n$(\".selected\")[direction]()\n\t.addClass(\"selected\")\n\t.focus()\n\t.siblings()\n\t.removeClass(\"selected\");\n\t\n\t\u2026\n\t\t\n});<\/code><\/pre>\n<p>Un aspetto interessante di questo codice \u00e8 che abbiamo associato i tasti freccia premuti con la direzione in cui vorremmo muoverci nella lista prodotti. La stringa direzionale (<code>\"prev\"<\/code> e <code>\"next\"<\/code>) viene interpolata con la funzione jQuery che si occupa del movimento al posto nostro. Usando i tasti freccia su e gi\u00f9, possiamo muoverci pi\u00f9 rapidamente e in maniera pi\u00f9 efficiente tra gli oggetti. Dopo essere giunti mediante frecce (o cliccando) nella sezione del prodotto a cui siamo interessati, possiamo poi usare il tasto tab per raggiungere la thumbnail ancorata a ciascun prodotto o il pulsante &#8220;Add to Cart&#8221;.<\/p>\n<h3>Una esperienza del carrello senza vitalit\u00e0<\/h3>\n<p>Dal carrello vuoto, clicchiamo sul pulsante &#8220;Add to Cart&#8221;. Gli utenti vedenti possono vedere l&#8217;incremento del numero sul torace blu del robot. Gli utenti non vedenti possono solo sentire &#8220;Add to Cart button&#8221;.<\/p>\n<p>Cliccando sul robot blu si lancia la modale del carrello. Ovviamente, un utente non pu\u00f2 saperlo a meno che non lo <em>veda<\/em> mentre succede. Gli utenti dipendenti da screen reader sentiranno &#8220;One button&#8221;, o il numero degli oggetti nel carrello.<\/p>\n<p>Una volta che siamo nella modale visibile, possiamo aggiungere, sottrarre e rimuovere tutti gli oggetti dal carrello. Nel nostro primo passaggio, comunque, l&#8217;accesso a questi pulsanti porta ad una UX piuttosto scarsa per gli utenti con disabilit\u00e0 visiva. &#8220;Plus button&#8221; non \u00e8 una risposta sufficientemente buona da parte del nostro screen reader quando premiamo il pulsante &#8220;+&#8221;.<\/p>\n<p>In maniera simile, quando chiudiamo la modale del carrello usando il pulsante &#8220;x&#8221;, il nostro reader ci dice &#8220;x button&#8221;.<\/p>\n<p>Non \u00e8 nemmeno colpa dello screen reader. Il nostro reader non ha quello di cui ha bisogno per offrire una ricca esperienza agli utenti che dipendono da esso. Per fornire un&#8217;esperienza ricca agli gli utenti non vedenti, dobbiamo migliorare la nostra semantica usando i role, gli state e le property di  <abbr title=\"Web Accessibility Initiative - Accessible Rich Internet Applications\">WAI-ARIA<\/abbr>.<\/p>\n<h3>Aggiustamenti al primo passaggio<\/h3>\n<p>Il nostro approccio ai miglioramenti dell&#8217;accessibilit\u00e0 sar\u00e0 di tipo &#8220;dal generico allo specifico&#8221;.<\/p>\n<h4>1. Landmark roles<\/h4>\n<p>Sebbene sia in qualche modo semantico, il nostro markup del primo passaggio non contiene alcun landmark role. Perch\u00e9 usare i landmark role? Secondo il guru e sostenitore dell&#8217;accessibilit\u00e0 <a href=\"http:\/\/blog.paciellogroup.com\/author\/admin\/\">Steve Faulkner<\/a>:<\/p>\n<blockquote>\n<p>Aggiungendo gli ARIA landmark al proprio sito o a un sito che si sta sviluppando, forniamo delle feature di navigazione globale e degli aiuti per la comprensione della struttura del contenuto da parte degli utenti.<\/p>\n<\/blockquote>\n<p>I landmark role permettono agli utenti di screen reader di navigare verso le maggiori sezioni del vostro sito web usando semplicemente un tasto. Al nostro markup mancano anche gli states e le properties di ARIA, che sono dei termini che, <a href=\"http:\/\/www.w3.org\/TR\/wai-aria\/states_and_properties\">secondo il W3C<\/a> &#8220;forniscono specifiche informazioni su un oggetto ed entrambe formano parte della definizione della natura dei roles&#8221;.<\/p>\n<h4><code>second_pass\/index.html<\/code><\/h4>\n<pre><code>&lt;!-- Header --&gt;\n&lt;header <strong>role=\"banner\"<\/strong>&gt;\n\n&lt;!-- Main content element replaces original div element--&gt;\n&lt;<strong>main<\/strong>\n\tid=\"main\"\n\ttabindex=\"-1\"&gt;\n<strong>&lt;\/main&gt;<\/strong><\/code><\/pre>\n<p>Se avessimo scelto di restare con il nostro <code>div<\/code> come genitore del nostro contenuto principale, aggiungergli <code>role=\"main\"<\/code> sarebbe accettabile per scopi legati all&#8217;accessibilit\u00e0. Tuttavia, faremo a meno del role al posto del pi\u00f9 diretto tag <code><a href=\"http:\/\/www.sitepoint.com\/html5-main-element\/\">main<\/a><\/code>.<\/p>\n<h4>Finestra di dialogo del carrello:<\/h4>\n<h5><code>second_pass\/index.html<\/code><\/h5>\n<pre><code>&lt;div\n\tid=\"my_cart\"\n\ttabindex=\"0\"\n\t<strong>role=\"dialog\"\n\taria-hidden=\"true\"\n\taria-labelledby=\"my_cart_title\"<\/strong>&gt;&lt;\/div&gt;<\/code><\/pre>\n<p>Quando si aggiungono gli oggetti al carrello per la prima volta, il markup viene creato dinamicamente usando il codice nella funzione <code>updateCartDialog<\/code>. Gli utenti vedenti noteranno che il carrello non \u00e8 ancora visibile. Per gli utenti non vedenti, dobbiamo assicurarci che il carrello non venga annunciato dallo screen reader. Per farlo, abbiamo aggiunto l&#8217;attributo <code>aria-hidden<\/code> che, <a href=\"http:\/\/www.w3.org\/TR\/wai-aria\/states_and_properties#aria-hidden\">secondo la specifica<\/a>, imposta uno state su un dato elemento &#8220;indicante che l&#8217;elemento e tutti i suoi discendenti non sono visibili o percepibili da alcun utente come sono implementati dall&#8217;autore&#8221;. Prosegue dicendo: &#8220;se un elemento \u00e8 visibile solo dopo una qualche azione da parte dell&#8217;utente, gli autori <strong>DEVONO<\/strong> impostare l&#8217;attributo <code>aria-hidden<\/code> a <code>true<\/code>&#8220;. La finestra di dialogo del carrello \u00e8 etichettata dall&#8217;elemento <code>caption<\/code> di questa tabella.<\/p>\n<h5><code>second_pass\/app.js<\/code><\/h5>\n<pre><code>$cart_contents\n\t.html(\"\")\n\t.append(\"\\\n\t&lt;table id='cart_summary'&gt;\\\n\t\t&lt;caption <strong>id='my_cart_title'<\/strong>&gt;Cart Contents&lt;\/caption&gt;\\\n\t\u2026\n\t\n\t&lt;\/table&gt;\\<\/code><\/pre>\n<h4>2. L&#8217;aggiunta\/rimozione degli oggetti dal carrello dovrebbe notificare gli utenti<\/h4>\n<p>Cliccando sul pulsante &#8220;Add to Cart&#8221; si attiva ChromeVox, che dice: &#8220;Add to Cart button&#8221;, che non \u00e8 di grande aiuto per un utente che dipende da segnali uditivi. Gli utenti dovrebbero sapere esattamente quello che si sta aggiungendo al carrello. Inoltre, l&#8217;azione di aggiungere e rimuovere oggetti dall&#8217;interno della modale del carrello dovrebbe dare informazioni uditive all&#8217;utente su quanti oggetti ci sono nel carrello <em>nel momento in cui cambia il contatore degli oggetti nel carrello<\/em>.<\/p>\n<p>Per far s\u00ec che questo accada, modifichiamo per prima cosa il markup del pulsante &#8220;Add to Cart&#8221; nel nostro template Handlebars.<\/p>\n<h5><code>second_pass\/index.html<\/code><\/h5>\n<pre><code class=\"language-markup\">&lt;script id=\"all_products\" type=\"text\/x-handlebars-template\"&gt;\n\t\n\t\u2026\n\t\n\t&lt;button\n\t\tclass=\"button add_to_cart\"\n\t\ttabindex=\"0\"\n\t\t<strong>aria-label=\"Add {{title}} to the cart\"\n\t\taria-controls=\"shopping_cart cart_count\"<\/strong>\n\t\tdata-pid=\"{{pid}}\"&gt;\n\t\tAdd to Cart\n\t&lt;\/button&gt;\n\t\n\t\u2026\n\n&lt;\/script&gt;<\/code><\/pre>\n<p>L&#8217;azione associata a questo pulsante <em>controlla<\/em> gli elementi <code>shopping_cart<\/code> e <code>cart_count<\/code> incrementando il numero totale di oggetti presenti nel carrello.<\/p>\n<pre><code>&lt;script id=\"all_products\" type=\"text\/x-handlebars-template\"&gt;\n\t\n\t\u2026\n\t\n\t&lt;button\n\t\ttitle=\"Cart Count\"\n\t\t<strong>id=\"shopping_cart\"\n\t\taria-owns=\"cart_contents\"\n\t\taria-label=\"Cart count\"<\/strong>&gt;\n\t&lt;\/button&gt;\n\t\n\t\u2026\n\t\n&lt;\/script&gt;<\/code><\/pre>\n<p>Il pulsante dello shopping cart (il robot blu) memorizza il numero attuale di oggetti nel carrello. Tuttavia, per notificare in maniera uditiva l&#8217;utente dei cambiamenti man mano che avvengono, useremo un nuovo approccio.<\/p>\n<pre><code>&lt;div\n\tclass=\"aria_counter\"\n\t<strong>id=\"cart_count\"\n\taria-live=\"polite\"<\/strong>&gt;\n&lt;\/div&gt;<\/code><\/pre>\n<p>Quando l&#8217;utente aggiunge un oggetto al carrello, aggiorniamo il nostro contatore aria che contiene un attributo <code><a href=\"http:\/\/www.w3.org\/TR\/wai-aria\/states_and_properties#aria-live\">aria-live<\/a><\/code>. Un elemento che usa questo attributo annuncia il suo contenuto quando qualcosa cambia.<\/p>\n<h4>3. I pulsanti della finestra di dialogo del carrello hanno bisogno delle propriet\u00e0 ARIA<\/h4>\n<div class=\"illustration full left\"><img decoding=\"async\" src=\"http:\/\/alistapart.com\/it\/wp-content\/uploads\/sites\/2\/2014\/07\/dialog_buttons.png\" border=\"0\" alt=\"Pulsanti della finestra di dialogo del carrello.\" \/><\/p>\n<p>Pulsanti della finestra di dialogo del carrello.<\/p>\n<\/div>\n<h4>3a. Pulsante \u201cx\u201d (rimuovi tutto)<\/h4>\n<p>Come detto prima, se attualmente clicchiamo sul pulsante &#8220;x&#8221;, ChromeVox dice &#8220;x button&#8221;.<\/p>\n<h5><code>first_pass\/app.js<\/code><\/h5>\n<pre><code>&lt;button class='button row_button remove_row_items' title='Remove all items of this type' data-pid='\" + element.pid + \"'&gt;x&lt;\/button&gt;<\/code><\/pre>\n<p>Il codice migliorato del nostro pulsante &#8220;x&#8221; risiede nella funzione <code>updateCartDialog<\/code>.<\/p>\n<h5><code>second_pass\/app.js<\/code><\/h5>\n<pre><code>&lt;button <strong>aria-controls='row_\" + index  +  \" cart_count item_count'<\/strong> class='button row_button remove_row_items' <strong>aria-label='Remove all \" + element.title + \"s from the cart?'<\/strong> data-pid='\" + element.pid + \"'&gt;x&lt;\/button&gt;\\<\/code><\/pre>\n<p>Introducendo l&#8217;attributo <a href=\"http:\/\/www.w3.org\/TR\/wai-aria\/states_and_properties#aria-controls\"><code>aria-controls<\/code><\/a> al nostro pulsante forniamo pi\u00f9 significato semantico. Stiamo dicendo agli screen reader che una data riga nel nostro carrello \u00e8 controllata dal pulsante &#8220;x&#8221; all&#8217;interno di ogni riga, e che possiamo rimuovere l&#8217;intera riga cliccando il pulsante e confermando la rimozione. In aggiunta, il pulsante &#8220;x&#8221; \u00e8 ora etichettato, cos\u00ec agli utenti di screen reader verr\u00e0 detto esattamente quale oggetto verr\u00e0 rimosso dal carrello.<\/p>\n<h4>3b. Pulsante &#8220;-&#8221; (decrementa la quantit\u00e0 di uno specifico oggetto)<\/h4>\n<p>Quando lo si preme, ChromeVox legge ad alta voce &#8220;dash button&#8221;. Memorizziamo l&#8217;<code>id<\/code> del campo target della quantit\u00e0, il pulsante cambia all&#8217;interno di un data attribute non semantico.<\/p>\n<h5><code>first_pass\/app.js<\/code><\/h5>\n<pre><code>&lt;button class='button row_button decrement_row_item'  title='Decrease quantity by one' <strong>data-pid='\" + element.pid + \"' data-product-quantity='product_quantity_\" + index  + \"'<\/strong>&gt;-&lt;\/button&gt;\n\n\u2026\n\n$(document).on(\"click\", \".decrement_row_item\", function() {\n\tapp.decrementItemQuantity(this.dataset.pid, <strong>this.dataset.productQuantity<\/strong>);\n\t\n\t\u2026\n\n});<\/code><\/pre>\n<p>Eliminiamo il data attribute non semantico e sostituiamolo con un attributo ARIA semantico. Ecco la nostra versione migliorata:<\/p>\n<h5><code>second_pass\/app.js<\/code><\/h5>\n<pre><code>&lt;button <strong>aria-controls='product_quantity_\" + index  + \" cart_count item_count'<\/strong> class='button row_button decrement_row_item' <strong>aria-label='Decrease \" + item_title + \" quantity'<\/strong> data-pid='\" + element.pid + \"'&gt;-&lt;\/button&gt;\n\n$(document).on(\"click\", \".decrement_row_item\", function() {\n\tvar aria_controls = $(this).attr(\"aria-controls\").split(\" \")[0];\n\tapp.decrementItemQuantity(this.dataset.pid, <strong>aria_controls<\/strong>);\n\t\n\t\u2026\n  \n});<\/code><\/pre>\n<p>Adesso il pulsante &#8220;-&#8221; \u00e8 etichettato. Per una UX migliore, la nostra etichetta include ora il title del prodotto. Aggiungendo <code>aria-controls<\/code> al mix, dichiariamo gli elementi nel DOM che sono controllati da questo pulsante:<\/p>\n<ol>\n<li><strong>Product quantity:<\/strong> il <code>td<\/code> contenente la quantit\u00e0 del prodotto attuale<\/li>\n<li><strong>Cart count:<\/strong> il contatore off-screen il cui valore viene annunciato quando cambia il numero degli oggetti nel carrello<\/li>\n<li><strong>Item count:<\/strong> un altro contatore off-screen il cui valore viene annunciato quando cambia la quantit\u00e0 di ciascun oggetto nel carrello<\/li>\n<\/ol>\n<p>Ecco il JS che gestisce il click del pulsante:<\/p>\n<pre><code>$(document).on(\"click\", \".decrement_row_item\", function() {\n\t\/\/ get the product quantity id of the row\n\tvar aria_controls = $(this).attr(\"aria-controls\").split(\" \")[0];\n\t<strong>app.decrementItemQuantity(this.dataset.pid, aria_controls<\/strong>);\n\t\n\t\u2026\n\t\n});<\/code><\/pre>\n<p>Migliorare il nostro markup ha anche il beneficio aggiunto di rendere pi\u00f9 specifico il nostro JS. Il secondo argomento di <code>decrementItemQuantity<\/code> diventa parte del valore dell&#8217;attributo <code>aria-controls<\/code>. Quindi, non solo il pulsante \u00e8 pi\u00f9 accessibile, ma anche il nostro codice \u00e8 diventato pi\u00f9 leggibile.<\/p>\n<h4>4. La modale del carrello ha bisogno di ARIA state<\/h4>\n<p>Attualmente, quando lanciamo la modale del carrello, ChromeVox non indica questo dettaglio all&#8217;utente. Questo perch\u00e9 aggiungiamo e togliamo solo un class name semanticamente debole sul body per far s\u00ec che questa interazione funzioni.<\/p>\n<h5><code>first_pass\/app.js<\/code><\/h5>\n<pre><code>showModal: function() {\n\t$(\"body\").addClass(\"show_cart\");\n},\n\nremoveModal: function() {\n\t$(\"body\").removeClass(\"show_cart\");\n}<\/code><\/pre>\n<p>Per far s\u00ec che il reader funzioni meglio, gli diamo una semantica migliore. Quando il carrello \u00e8 aperto, vorremmo nascondere il nostro container (tutto quello che sta dietro alla modale del carrello) dalle tecnologie assistive. Al contrario, il nostro carrello adesso viene fuori dallo stato in cui \u00e8 nascosto ed \u00e8 chiaramente rivelato alle tecnologie assistive.<\/p>\n<h5><code>second_pass\/app.js<\/code><\/h5>\n<pre><code>showModal: function() {\n\tif (app.elements.$my_cart.attr(\"aria-hidden\") === \"true\") {\n\t\t$(\"body\").addClass(\"show_cart\");\n\t\t\n\t\t\u2026\n\t\t\n\t\t<strong>app.elements.$container.attr(\"aria-hidden\", \"true\");\n\t\tapp.elements.$my_cart.attr(\"aria-hidden\", \"false\");<\/strong>\n\t}\n\t\n\t\u2026\n\t\n}<\/code><\/pre>\n<h4>5. Sezioni del prodotto selezionato hanno bisogno di ARIA state<\/h4>\n<p>Quando gli utenti premono i tasti freccia su e gi\u00f9, una class &#8220;selected&#8221; viene aggiunta per rappresentare la sezione del prodotto attualmente selezionato. Sostituiamo la class con un <a href=\"http:\/\/www.w3.org\/TR\/wai-aria\/states_and_properties#aria-selected\"><code>aria-selected<\/code><\/a>.<\/p>\n<h5><code>second_pass\/app.js<\/code><\/h5>\n<pre><code>$(document.documentElement).keyup(function(event) {\n\n\t\u2026\n\n\tif (key_pressed === UP) {\n\t\tdirection = \"prev\";\n\t} else if (key_pressed === DOWN) {\n\t\tdirection = \"next\";\n\t}\n\t\n\t\u2026\n\t\n\t$selected[direction]()\n\t\t<strong>.attr(\"aria-selected\", \"true\")<\/strong>\n\t\t.focus()\n\t\t.siblings()\n\t\t<strong>.attr(\"aria-selected\", \"false\");<\/strong>\n\t\t\n\t\u2026\n\t\t\n});<\/code><\/pre>\n<\/div>\n<div class=\"paragrafo\">\n<h2>Round 2 (<a href=\"https:\/\/alistapart.github.io\/code-samples\/395\/accessibility-the-missing-ingredient\/second_pass\/index.html\" title=\"Link al secondo passaggio della demo\">Demo<\/a>)<\/h2>\n<p>Continuate a seguire e notate come abbiamo migliorato la UX per gli utenti disabili attraverso delle semantiche migliori.<\/p>\n<ol>\n<li>Da un carrello vuoto, aggiungi un qualunque oggetto al carrello.\n<ul>\n<li><strong>Prima<\/strong>: \u201cAdd to cart button\u201d <\/li>\n<li><strong>Dopo<\/strong>: \u201cAdd {{title of product}} to the cart button. Cart count one\u201d <\/li>\n<\/ul>\n<\/li>\n<li>\n<p>Usare il tasto tab per portare il focus sul robot.<\/p>\n<ul>\n<li><strong>Prima<\/strong>: \u201cOne button\u201d <\/li>\n<li><strong>Dopo<\/strong>: \u201cBanner, cart count one\u201d <\/li>\n<\/ul>\n<\/li>\n<li>\n<p>Cliccare sul robot per aprire il carrello.<\/p>\n<ul>\n<li><strong>Prima<\/strong>: (contents of the cart) <\/li>\n<li><strong>Dopo<\/strong>: \u201cEnter dialog\u201d (contents of the cart) <\/li>\n<\/ul>\n<\/li>\n<li>\n<p>Cliccare il pulsante \u201c+\u201d nel carrello aperto che contiener un oggetto.<\/p>\n<ul>\n<li><strong>Prima<\/strong>: \u201cPlus button\u201d<\/li>\n<li><strong>Dopo<\/strong>: \u201cIncrease {{title of product }} quantity button. Item quantity two. Cart count two\u201d<\/li>\n<\/ul>\n<\/li>\n<li>\n<p>Cliccare la \u201cx\u201d per rimuovere tutti gli oggetti di un certo tipo.<\/p>\n<ul>\n<li><strong>Prima<\/strong>: \u201cX button\u201d<\/li>\n<li><strong>Dopo<\/strong>: \u201cRemove all {{title of product}}s from the cart button\u201d<\/li>\n<\/ul>\n<\/li>\n<li>\n<p>Cancellare il pop-up di conferma JavaScript ed uscire dalla &#8220;modal dialog&#8221; usando il tasto &#8220;esc&#8221; o il pulsante &#8220;x&#8221;.<\/p>\n<ul>\n<li><strong>Prima<\/strong>: \u201c\u201d<\/li>\n<li><strong>Dopo<\/strong>: \u201cExited dialog\u201d<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<p>Il nostro focus ritorna poi all&#8217;ultimo prodotto selezionato prima che il carrello fosse aperto. Se non \u00e8 stata precedentemente selezionata alcuna sezione di prodotto, il focus ritorna alla prima sezione di prodotto nell&#8217;elenco.<\/p>\n<\/div>\n<div class=\"paragrafo\">\n<h2>Conclusioni<\/h2>\n<p>Sarei un bugiardo se vi dicessi che scrivere codice accessibile non richiede lavoro extra. Quando prototipiamo e creiamo degli schizzi con il product designer, esaminiamo le nostre decisioni ancora pi\u00f9 attentamente di prima. Ogni design deve portare ad una UX accessibile. In maniera simile, gli sviluppatori che non hanno familiarit\u00e0 con le pratiche di accessibilit\u00e0 potrebbero passare pi\u00f9 tempo a rivedere i propri commit prima di vedere il proprio codice &#8220;merged&#8221;.<\/p>\n<p>I bravi product manager realizzano che le nuove sfide generano requisiti temporali pi\u00f9 grandi da parte dei designer e dei developer. \u00c8 incoraggiante che noi si sia delle creature altamente adattabili: questi costi di lavoro anticipati diminuiranno nel tempo. Ancora pi\u00f9 importante, questo duro lavoro porter\u00e0 a un prodotto pi\u00f9 usabile per tutti i clienti e ad una codebase pi\u00f9 leggibile per gli sviluppatori. Dobbiamo essere d&#8217;accordo sul non trattare l&#8217;accessibilit\u00e0 come la glassa sulla torna, ma piuttosto come un&#8217;essenziale ingrediente.<\/p>\n<p>Illustrazioni: {carlok}<\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Se l&#8217;economia \u00e8 la scienza triste, l&#8217;accessibilit\u00e0 \u00e8 stata per molto tempo la branca meno amata del web design and development, nonch\u00e9 la richiesta avanzata di meno da parte dei clienti. La tipografia e le griglie (specialmente quelle flessibili) hanno moltissimi fan. CSS, Sass e i framework attirano grandi folle di appassionati. Ma perfino i front-ender pi\u00f9 tosti e i pi\u00f9 devoti seguaci delle best practice sembrano ammosciarsi di fronte alle attuali nonch\u00e9 molto migliorate tecniche di accessibilit\u00e0. Come risultato, mentre la maggior parte di noi \u00e8 rimasta alla pari con i metodi, le tecnologie e le sfide emergenti del design e dello sviluppo multi-device, specifiche essenziali e ben supportate come WAI-ARIA rimangono dolorosamente sotto-implementate. Anche i migliori tra noi sembrano considerare l&#8217;accessibilit\u00e0 un qualcosa che va fatto alla fine del lavoro. Andrew Hoffman spiega i vantaggi e le necessit\u00e0 di un approccio accessibility first.<\/p>\n","protected":false},"author":818,"featured_media":7000735,"comment_status":"open","ping_status":"open","template":"","categories":[245,247,113],"tags":[],"coauthors":[423],"class_list":["post-471","article","type-article","status-publish","has-post-thumbnail","hentry","category-accessibilita","category-html","category-numero-95-29-luglio-2014"],"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/article\/471","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=471"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/media\/7000735"}],"wp:attachment":[{"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/media?parent=471"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/categories?post=471"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/tags?post=471"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/coauthors?post=471"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}