Acessibilidade
A acessibilidade da web (também conhecida como a11y) refere-se a prática de criar páginas e aplicações de web que podem ser usadas por qualquer um — seja essa uma pessoa com uma deficiência, uma conexão lenta, hardware destroçado ou desatualizado ou simplesmente alguém em um ambiente desfavorável. Por exemplo, adicionar legendas à um vídeo ajuda tanto os teus utilizadores surdos e com dificuldades de audição quanto os teus utilizadores que estão em um ambiente ruidoso e que não podem ouvir seus telemóveis. Similarmente, certificar-te que o teu texto não é de muito contraste muito baixo ajudará tanto os teus utilizadores de visão fraca quanto os teus utilizadores que estão a tentar usar os seus telemóveis na luz do sol forte.
Pronto para começar mas não sem a certeza de por onde?
Consulte o guia de planeamento e gerência da acessibilidade da web fornecido pelo Consórcio da World Wide Web (W3C)
Ligação de Salto
Tu deves adicionar uma ligação no topo de cada página que vai diretamente para a área do conteúdo principal assim os utilizadores podem salter o conteúdo que é repetido em várias páginas de Web.
Normalmente, isto é feito no topo de App.vue
visto que será o primeiro elemento concentrável em todas as tuas páginas:
template
<ul class="skip-links"> <li> <a href="#main" ref="skipLink" class="skip-link">Skip to main content</a> </li> </ul>
Para esconder a ligação se não ela é focada, podes adicionar o seguinte estilo:
css
.skip-link { white-space: nowrap; margin: 1em auto; top: 0; position: fixed; left: 50%; margin-left: -72px; opacity: 0; } .skip-link:focus { opacity: 1; background-color: white; padding: 0.5em; border: 1px solid black; }
Uma vez que o utilizador mudar a rota, traga o foco de volta para a ligação saltar. Isto pode ser alcançado chamando o foco na referência do modelo de marcação da ligação saltar (assumindo o uso da vue-router
):
vue
<script setup> import { ref, watch } from 'vue' import { useRoute } from 'vue-router' const route = useRoute() const skipLink = ref() watch( () => route.path, () => { skipLink.value.focus() } ) </script>
Leia a documentação sobre a ligação "saltar para o conteúdo principal"
Estrutura de Conteúdo
Um dos pedaços mais importantes da acessibilidade é garantir que o desenho possa suportar a implementação acessível. O desenho deve considerar não apenas o contraste de cor, seleção de fonte, tamanho de texto, e linguagem mas também como o conteúdo é estruturado na aplicação.
Cabeçalhos
Os utilizadores podem navegar em uma aplicação através dos cabeçalhos. Ter cabeçalhos descritivos para cada seção da tua aplicação torna mais fácil para os utilizadores prever o conteúdo de cada seção. Quando falamos de cabeçalhos, existem algumas práticas de acessibilidade recomendadas:
- Encaixar cabeçalhos nas suas ordem de classificação:
<h1>
-<h6>
- Não saltar cabeçalhos dentro de uma seção
- Usar marcadores de cabeçalho verdadeiros ao invés da estilização de texto para dar a aparência visual dos cabeçalhos
template
<main role="main" aria-labelledby="main-title"> <h1 id="main-title">Main title</h1> <section aria-labelledby="section-title"> <h2 id="section-title"> Section Title </h2> <h3>Section Subtitle</h3> <!-- Content --> </section> <section aria-labelledby="section-title"> <h2 id="section-title"> Section Title </h2> <h3>Section Subtitle</h3> <!-- Content --> <h3>Section Subtitle</h3> <!-- Content --> </section> </main>
Marcos
Os marcos fornecem acesso programático às seções dentro de uma aplicação. Os utilizadores que dependem de tecnologia ajustantes podem navegar para cada seção da aplicação e saltar sobre o conteúdo. Tu podes usar os papeis de ARIA para ajudar-te a alcançar isto.
HTML | Papeis de ARIA | Propósito do Marco |
---|---|---|
header | role="banner" | Cabeçalho principal: título da página. |
nav | role="navigation" | Coleção de ligações adequadas para uso quando estiveres a navegar pelo documento ou documentos relacionados. |
main | role="main" | O conteúdo principal ou central do documento. |
footer | role="contentinfo" | Informação sobre o documento pai: notas de rodapé ou direitos de autor ou ligações para o relatório de privacidade. |
aside | role="complementary" | Sustenta o conteúdo principal, mais é separado e significativo em seu próprio conteúdo. |
search | role="search" | Esta seção contém a funcionalidade de pesquisa para a aplicação. |
form | role="form" | Coleção de elementos associados ao formulário. |
section | role="region" | O conteúdo que é relevante e para o qual os utilizadores provavelmente quererão navegar. O rótulo deve ser fornecido para este elemento. |
DICA:
É recomendado usar os elementos de HTML de marco com atributos do papel do marco redundante para maximizar a compatibilidade com navegadores antigos que não suportam os elementos semânticos da HTML5.
Formulários Semânticos
Quando criares um formulário, podes usar os seguintes elementos: <form>
, <label>
, <input>
, <textarea>
, e <button>
.
Os rótulos são normalmente colocados no princípio ou a esquerda dos campos do formulário:
template
<form action="/dataCollectionLocation" method="post" autocomplete="on"> <div v-for="item in formItems" :key="item.id" class="form-item"> <label :for="item.id">{{ item.label }}: </label> <input :type="item.type" :id="item.id" :name="item.id" v-model="item.value" /> </div> <button type="submit">Submit</button> </form>
Nota como podes incluir autocomplete='on'
no elemento de formulário e aplicar-se-á à todas entradas no teu formulário. Tu podes também definir valores diferentes para o atributo autocomplete
para cada entrada.
Rótulos
Forneça rótulos para descrever o propósito de todos os mecanismo de controlo do formulário: ligando for
e id
:
template
<label for="name">Name</label> <input type="text" name="name" id="name" v-model="name" />
Se inspecionares este elemento nas ferramentas de programação do teu navegador Google Chrome e abrires a aba de Acessibilidade dentro da aba de Elementos, verás como a entrada recebe o seu nome a partir do rótulo:
Aviso:
Embora tenhas visto rótulos envolvendo os campos de entrada como este:
template
<label> Name: <input type="text" name="name" id="name" v-model="name" /> </label>
A definição explícita dos rótulos com um identificador correspondente é melhor suportado pela tecnologia ajudante.
aria-label
Tu podes também atribuir a entrada um nome acessível com o aria-label
:
template
<label for="name">Name</label> <input type="text" name="name" id="name" v-model="name" :aria-label="nameLabel" />
Esteja a vontade para inspecionar este elemento nas Ferramentas de Programação do Chrome para veres como o nome acessível tem mudado:
aria-labelledby
O uso de aria-labelledby
é parecido com o aria-label
exceto que é usado se o texto do rótulo estiver visível na tela. É emparelhado com os outros elementos pelo seu id
e podes ligar vários id
:
template
<form class="demo" action="/dataCollectionLocation" method="post" autocomplete="on" > <h1 id="billing">Billing</h1> <div class="form-item"> <label for="name">Name:</label> <input type="text" name="name" id="name" v-model="name" aria-labelledby="billing name" /> </div> <button type="submit">Submit</button> </form>
aria-describedby
O aria-describedby
é usado da mesma maneira que o aria-labelledby
exceto que fornece uma descrição com informação adicional que o utilizador possa precisar. Isto pode ser usado para descrever o critério para qualquer entrada:
template
<form class="demo" action="/dataCollectionLocation" method="post" autocomplete="on" > <h1 id="billing">Billing</h1> <div class="form-item"> <label for="name">Full Name:</label> <input type="text" name="name" id="name" v-model="name" aria-labelledby="billing name" aria-describedby="nameDescription" /> <p id="nameDescription">Please provide first and last name.</p> </div> <button type="submit">Submit</button> </form>
Tu podes ver a descrição inspecionando as Ferramentas de Programação do Chrome:
Espaço Reservado
Evite usar espaços reservados visto que podem confundir muitos utilizadores.
Um dos problemas com os espaços reservados é que não cumprem com o critério de contraste de cor por padrão; corrigir o contraste de cor faz o espaço reservado parecer como dados pré-povoado nos campos de entrada. Olhando no seguinte exemplo, podes ver que o espaço reservado do Último Nome o qual cumpre com o critério de contraste de cor parece-se com dado pré-povoado:
template
<form class="demo" action="/dataCollectionLocation" method="post" autocomplete="on" > <div v-for="item in formItems" :key="item.id" class="form-item"> <label :for="item.id">{{ item.label }}: </label> <input type="text" :id="item.id" :name="item.id" v-model="item.value" :placeholder="item.placeholder" /> </div> <button type="submit">Submit</button> </form>
css
/* https://www.w3schools.com/howto/howto_css_placeholder.asp */ #lastName::placeholder { /* Chrome, Firefox, Opera, Safari 10.1+ */ color: black; opacity: 1; /* Firefox */ } #lastName:-ms-input-placeholder { /* Internet Explorer 10-11 */ color: black; } #lastName::-ms-input-placeholder { /* Microsoft Edge */ color: black; }
É melhor fornecer todas as informações que o utilizador precisa para preencher os formulários fora de quaisquer entradas.
Instruções
Quando estiveres a adicionar as instruções para os teus campos de entrada, certifica-te de ligá-lo corretamente ao campo de entrada. Tu podes fornecer instruções adicionais e vincule vários identificadores dentro de um aria-labelledby
. Isto permite um desenho mais flexível:
template
<fieldset> <legend>Using aria-labelledby</legend> <label id="date-label" for="date">Current Date:</label> <input type="date" name="date" id="date" aria-labelledby="date-label date-instructions" /> <p id="date-instructions">MM/DD/YYYY</p> </fieldset>
Alternativamente, podes atribuir as instruções ao campo de entrada com o aria-describedby
:
template
<fieldset> <legend>Using aria-describedby</legend> <label id="dob" for="dob">Date of Birth:</label> <input type="date" name="dob" id="dob" aria-describedby="dob-instructions" /> <p id="dob-instructions">MM/DD/YYYY</p> </fieldset>
Escondendo Conteúdo
Normalmente não é recomendado esconder visualmente os rótulos, mesmo se a entrada tiver um nome acessível. No entanto, se a funcionalidade da entrada pode ser entendida com o conteúdo circundante, então podemos esconder o rótulo visual.
Observemos este campo de pesquisa:
template
<form role="search"> <label for="search" class="hidden-visually">Search: </label> <input type="text" name="search" id="search" v-model="search" /> <button type="submit">Search</button> </form>
Nós podemos fazer isto porque o botão de pesquisa ajudará os utilizadores visuais a identificarem o propósito do campo de entrada.
Nós podemos usar a CSS para esconder visualmente os elementos mas mantê-los disponíveis para a tecnologia assistiva:
css
.hidden-visually { position: absolute; overflow: hidden; white-space: nowrap; margin: 0; padding: 0; height: 1px; width: 1px; clip: rect(0 0 0 0); clip-path: inset(100%); }
aria-hidden="true"
Adding aria-hidden="true"
will hide the element from assistive technology but leave it visually available for other users. Do not use it on focusable elements, purely on decorative, duplicated or offscreen content.
template
<p>This is not hidden from screen readers.</p> <p aria-hidden="true">This is hidden from screen readers.</p>
Botões
Quando estiveres a usar os botões dentro de um formulário, deves definir o tipo para evitar a submissão do formulário. Tu podes também usar uma entrada para criar os botões:
template
<form action="/dataCollectionLocation" method="post" autocomplete="on"> <!-- Botões --> <button type="button">Cancel</button> <button type="submit">Submit</button> <!-- Botões de entrada --> <input type="button" value="Cancel" /> <input type="submit" value="Submit" /> </form>
Imagens Funcionais
Tu podes usar esta técnica para criar imagens funcionais.
Campos de entrada
- Estas imagens agirão como um botão de tipo submissão em formulários
template<form role="search"> <label for="search" class="hidden-visually">Search: </label> <input type="text" name="search" id="search" v-model="search" /> <input type="image" class="btnImg" src="https://img.icons8.com/search" alt="Search" /> </form>
Ícones
template
<form role="search"> <label for="searchIcon" class="hidden-visually">Search: </label> <input type="text" name="searchIcon" id="searchIcon" v-model="searchIcon" /> <button type="submit"> <i class="fas fa-search" aria-hidden="true"></i> <span class="hidden-visually">Search</span> </button> </form>
Padrões
A Iniciativa de Acessibilidade da Web (WAI, sigla em Inglês) do Consórcio da World Wide Web (W3C, sigla em Inglês) desenvolve os padrões de acessibilidade da web para os diferentes componentes:
- Diretrizes de Acessibilidade do Agente do Utilizador (UAAG, sigla em Inglês)
- Os navegadores da web e leitores de media, incluindo alguns aspetos de tecnologias assistivas.
- Diretrizes de Acessibilidade de Ferramenta de Autoria (ATAG, sigla em Inglês)
- As ferramentas de autoria
- Diretrizes de Acessibilidade do Conteúdo da Web (WCAG, sigla em Inglês)
- O conteúdo da web - usado por programadores, ferramentas de autoria, e ferramentas de avaliação da acessibilidade.
Diretrizes de Acessibilidade do Conteúdo da Web (WCAG)
A WCAG 2.1 estende o WCAG 2.0 e permite a implementação de novas tecnologias endereçando as mudanças para a web. O W3C encoraja o uso da versão mais atual de WCAG quando estiveres a desenvolver ou a atualizar as políticas de acessibilidade da Web.
WCAG 2.1 Quatro Princípios Orientadores Principais (abreviado como POUR, em Inglês):
- Percebível
- Os utilizadores devem ser capazes de perceber a informação sendo apresentada
- Operável
- Formulários de interface, controlos, e navegação são operáveis
- Compreensível
- A informação e a operação da interface de utilizador devem ser compreensíveis para todos utilizadores.
- Robusta
- Os utilizadores devem ser capazes de acessar o conteúdo conforme o avanço das tecnologias
Iniciativa de Acessibilidade da Web - Aplicações de Internet Ricas em Acessibilidade (WAI-ARIA)
A WAI-ARIA do W3C fornece orientação sobre como construir conteúdo dinâmico e controlos de interface de utilizador avançados:
- Aplicações de Internet Ricas em Acessibilidade (WAI-ARIA, sigla em Inglês) 1.2
- Práticas de Autoria da WAI-ARIA 1.2
Recursos
Documentação
- WCAG 2.0
- WCAG 2.1
- Aplicações de Internet Ricas em Acessibilidade (WAI-ARIA) 1.2
- Práticas de Autoria da WAI-ARIA 1.2
Tecnologias Assistivas
- Leitores de Ecrã
- Ferramentas de Ampliação de Conteúdo
Testagem
- Ferramentas Automatizadas
- Ferramentas de Cores
- Outras Ferramentas Úteis
Utilizadores
A Organização Mundial da Saúde estima que 15% da população mundial tem alguma forma de deficiência, 2-4% deles com severidade. Isto é estimado em 1 bilhão de pessoas mundialmente; tornando as pessoas com deficiências o maior grupo minoritário no mundo.
Existem uma grande gama de deficiência, que podem ser divididas aproximadamente em quatro categorias:
- Visual - Estes utilizadores podem beneficiarem-se do uso de leitores de ecrã, ampliação de ecrã, controlo de contraste de ecrã, ou exibição de braille.
- Auditiva - Estes utilizadores podem beneficiarem-se do legendamento, transcrições ou vídeo de linguagem gestual.
- Motora - Estes utilizadores podem beneficiarem-se de uma gama de tecnologias assistivas para deficiências motoras: software de reconhecimento de voz, acompanhamento do olho, acesso de interruptor único, vara de mão, teclado adaptável ou outras tecnologias assistivas.
- Cognitiva - Estes utilizadores podem beneficiarem-se de media complementar, organização estrutural do conteúdo, escrita clara e simples.
Consulte as seguintes ligações da WebAim para entenderes as necessidades dos utilizadores: