Trecho do Livro de Padrões de Design de Formulário: Um Formulário de Registro
Publicados: 2022-03-10Vamos começar com um formulário de inscrição. A maioria das empresas deseja relacionamentos de longo prazo com seus usuários. Para fazer isso, eles precisam que os usuários se inscrevam. E para fazer isso , eles precisam dar valor aos usuários em troca. Ninguém quer se inscrever no seu serviço – eles só querem acessar o que você oferece ou a promessa de uma experiência mais rápida na próxima vez que o visitarem.
Apesar da aparência básica do formulário de registro, há muitas coisas a serem consideradas: os elementos primitivos que compõem um formulário (rótulos, botões e entradas), formas de reduzir o esforço (mesmo em formulários pequenos como este), até o formulário validação.
Ao escolher uma forma tão simples, podemos ampliar as qualidades fundamentais encontradas em formas bem projetadas.
## Como pode parecerO formulário é composto por quatro campos e um botão de envio. Cada campo é composto por um controle (a entrada) e seu rótulo associado.
Aqui está o HTML:
<form> <label for="firstName">First name</label> <input type="text" name="firstName"> <label for="lastName">Last name</label> <input type="text" name="lastName"> <label for="email">Email address</label> <input type="email" name="email"> <label for="password">Create password</label> <input type="password" name="password" placeholder="Must be at least 8 characters"> <input type="submit" value="Register"> </form>
Os rótulos são onde nossa discussão começa.
## EtiquetasEm Acessibilidade para todos , Laura Kalbag estabelece quatro parâmetros amplos que melhoram a experiência do usuário para todos:
- Visual : facilite a visualização.
- Auditivo : facilite a audição.
- Motor : facilite a interação.
- Cognitivo : facilite a compreensão.
Ao olhar para os rótulos de cada um desses pontos de vista, podemos ver o quão importantes são os rótulos. Usuários com visão podem lê-los, usuários com deficiência visual podem ouvi-los usando um leitor de tela e usuários com deficiência motora podem definir o foco mais facilmente para o campo graças à maior área de acerto. Isso porque clicar em um rótulo define o foco para o elemento de formulário associado.
Por esses motivos, todo controle que aceita entrada deve ter um <label>
auxiliar. Os botões de envio não aceitam entrada, portanto, não precisam de um rótulo auxiliar — o atributo value
, que renderiza o texto dentro do botão, atua como o rótulo acessível.
Para conectar uma entrada a um rótulo, o id
da entrada e o atributo for
do rótulo devem corresponder e ser exclusivos da página. No caso do campo email, o valor é “email”:
html < label for = "email" > Email address </ label > < input id = "email" >
Deixar de incluir um rótulo significa ignorar as necessidades de muitos usuários, incluindo aqueles com deficiências físicas e cognitivas. Ao focar nas barreiras reconhecidas para pessoas com deficiência, podemos tornar nossos formulários mais fáceis e robustos para todos.
Por exemplo, uma área de acerto maior é crucial para usuários com deficiência motora, mas também é mais fácil de acertar para aqueles sem deficiência.
## Marcadores O atributo placeholder
destina-se a armazenar uma dica. Ele fornece aos usuários orientação extra ao preencher um campo — particularmente útil para campos que possuem regras complexas, como um campo de senha.
Como o texto do espaço reservado não é um valor real, ele fica acinzentado para que possa ser diferenciado dos valores inseridos pelo usuário.
Ao contrário dos rótulos, as dicas são opcionais e não devem ser usadas naturalmente. Só porque o atributo placeholder
existe não significa que temos que usá-lo. Você não precisa de um espaço reservado de “Digite seu primeiro nome” quando o rótulo é “Primeiro nome” – isso é duplicação desnecessária.
Os espaços reservados são atraentes por causa de sua estética mínima e de economia de espaço. Isso ocorre porque o texto do espaço reservado é colocado dentro do campo. Mas essa é uma maneira problemática de dar uma dica aos usuários.
Primeiro, eles desaparecem quando o usuário digita. O desaparecimento do texto é difícil de lembrar, o que pode causar erros se, por exemplo, o usuário esquecer de cumprir uma das regras de senha. Os usuários geralmente confundem o texto do espaço reservado com um valor, fazendo com que o campo seja ignorado, o que novamente causaria erros mais tarde. O texto cinza sobre branco não tem contraste suficiente, tornando-o geralmente difícil de ler. E ainda por cima, alguns navegadores não suportam espaços reservados, alguns leitores de tela não os anunciam e o texto de dica longo pode ser cortado.
Isso é um monte de problemas para o que é essencialmente apenas texto. Todo o conteúdo, especialmente uma dica de formulário, não deve ser considerado bom de se ter. Então, em vez de usar espaços reservados, é melhor posicionar o texto da dica acima do controle assim:
<div class="field"> <label for="password"> <span class="field-label">Password</span> <span class="field-hint">Must contain 8+ characters with at least 1 number and 1 uppercase letter.</span> </label> <input type="password" name="password"> </div>
A dica é colocada dentro do rótulo e dentro de um <span>
para que possa ter um estilo diferente. Ao colocá-lo dentro do rótulo, ele será lido pelos leitores de tela e amplia ainda mais a área de acerto.
Como acontece com a maioria das coisas no design, essa não é a única maneira de obter essa funcionalidade. Poderíamos usar atributos ARIA para associar a dica com a entrada:
<div class="field"> <label for="password">Password</label> <p class="field-hint">Must contain 8+ characters with at least 1 number and 1 uppercase letter.</p> <input type="password" name="password"> </div>
O atributo aria-describedby
é usado para conectar a dica por seu id
— assim como o atributo for para rótulos, mas ao contrário. Ele é anexado ao rótulo do controle e lido após uma pequena pausa. Neste exemplo, “a senha [pausa] deve conter oito caracteres positivos com pelo menos um número e uma letra maiúscula”.
Existem outras diferenças também. Primeiro, clicar na dica (um <p>
neste caso) não focará o controle, o que reduz a área de acerto. Segundo, apesar do suporte crescente do ARIA, ele nunca será tão bem suportado quanto os elementos nativos. Nesse caso específico, o Internet Explorer 11 não oferece suporte aria-describedby
. É por isso que a primeira regra de ARIA é não usar ARIA:
“Se você puder usar um elemento ou atributo HTML nativo com a semântica e o comportamento necessários já incorporados, em vez de redirecionar um elemento e adicionar uma função, estado ou propriedade ARIA para torná-lo acessível, faça isso .”
Etiquetas flutuantes
O padrão de rótulo flutuante de Matt Smith é uma técnica que usa o rótulo como um espaço reservado. O rótulo começa dentro do controle, mas flutua acima do controle conforme o usuário digita, daí o nome. Essa técnica é frequentemente elogiada por suas qualidades peculiares, minimalistas e de economia de espaço.
Infelizmente, existem vários problemas com essa abordagem. Primeiro, não há espaço para uma dica porque o rótulo e a dica são a mesma coisa. Em segundo lugar, eles são difíceis de ler, devido ao baixo contraste e ao texto pequeno, pois são normalmente projetados. (Um contraste menor é necessário para que os usuários tenham a chance de diferenciar entre um valor real e um espaço reservado.) Terceiro, como os espaços reservados, eles podem ser confundidos com um valor e podem ser cortados.
E os rótulos flutuantes não economizam espaço. O rótulo precisa de espaço para se mover em primeiro lugar. Mesmo que tenham economizado espaço, isso dificilmente é uma boa razão para diminuir a usabilidade dos formulários.
“Parece muito esforço quando você pode simplesmente colocar rótulos acima das entradas e obter todos os benefícios / nenhum dos problemas.”
— Luke Wroblewski em rótulos flutuantes
Interfaces peculiares e minimalistas não fazem os usuários se sentirem incríveis – interfaces óbvias, inclusivas e robustas sim. Reduzir artificialmente a altura de formulários como esse é pouco atraente e problemático.
Em vez disso, você deve priorizar a criação de espaço para um rótulo sempre presente e prontamente disponível (e dica, se necessário) no início do processo de design. Dessa forma, você não terá que espremer o conteúdo em um espaço pequeno.
Discutiremos várias técnicas menos artificiais para reduzir o tamanho dos formulários em breve.
## O protocolo de perguntasUma maneira poderosa e natural de reduzir o tamanho de um formulário é usar um protocolo de perguntas. Isso ajuda a garantir que você saiba por que está fazendo todas as perguntas ou incluindo um campo de formulário.
O formulário de inscrição precisa coletar nome, sobrenome, endereço de e-mail e senha? Existem maneiras melhores ou alternativas de solicitar essas informações que simplifiquem a experiência?
Muito provavelmente, você não precisa pedir o nome e sobrenome do usuário para que ele se registre. Se você precisar dessa informação mais tarde, por qualquer motivo, peça-a então. Ao remover esses campos, podemos reduzir pela metade o tamanho do formulário. Tudo sem recorrer a padrões novos e problemáticos.
### Sem senha de loginUma maneira de evitar pedir uma senha aos usuários é usar o padrão de login sem senha . Funciona fazendo uso da segurança do e-mail (que já precisa de senha). Os usuários inserem apenas seu endereço de e-mail e o serviço envia um link especial para sua caixa de entrada. Depois disso, o usuário entra no serviço imediatamente.
Isso não apenas reduz o tamanho do formulário para apenas um campo, mas também evita que os usuários precisem se lembrar de outra senha. Embora isso simplifique o formulário isoladamente, de outras maneiras adiciona alguma complexidade extra para o usuário.
Primeiro, os usuários podem estar menos familiarizados com essa abordagem e muitas pessoas estão preocupadas com a segurança online. Em segundo lugar, ter que mudar do aplicativo para sua conta de e-mail é demorado, especialmente para usuários que sabem sua senha ou usam um gerenciador de senhas.
Não é que uma técnica seja sempre melhor que a outra. É que um protocolo de perguntas nos incita a pensar sobre isso como parte do processo de design. Caso contrário, você adicionaria sem pensar um campo de senha no formulário e terminaria com ele.
### SenhasAs senhas são geralmente curtas, difíceis de lembrar e fáceis de decifrar. Os usuários geralmente precisam criar uma senha com mais de oito caracteres, composta por pelo menos uma letra maiúscula e uma letra minúscula e um número. Essa micro-interação dificilmente é ideal.
“Desculpe, mas sua senha deve conter uma letra maiúscula, um número, um haiku, um sinal de gangue, um hieróglifo e o sangue de uma virgem.”
— Meme anônimo da internet
Em vez de uma senha, poderíamos pedir aos usuários uma senha. Uma senha é uma série de palavras como “monkeysinmygarden” (desculpe, essa é a primeira coisa que vem à mente). Eles geralmente são mais fáceis de lembrar do que as senhas e são mais seguros devido ao seu tamanho – as senhas devem ter pelo menos 16 caracteres.
A desvantagem é que as senhas são menos usadas e, portanto, desconhecidas. Isso pode causar ansiedade para usuários que já estão preocupados com a segurança online.
Seja o padrão de login sem senha ou as senhas, só devemos nos afastar da convenção depois de realizar uma pesquisa de usuário completa e diversificada. Você não quer trocar um conjunto de problemas por outro sem saber.
## Estilo de campoA maneira como você estiliza seus componentes de formulário será, pelo menos em parte, determinada pela marca do seu produto ou empresa. Ainda assim, a posição do rótulo e os estilos de foco são considerações importantes.
### Posição do rótuloOs testes de rastreamento ocular de Matteo Penzo mostraram que posicionar o rótulo acima (em vez de ao lado) do controle de formulário funciona melhor.
“Colocar um rótulo logo acima de seu campo de entrada permitiu que os usuários capturassem os dois elementos com um único movimento dos olhos.”
Mas há outras razões para colocar o rótulo acima do campo. Em pequenas janelas não há espaço ao lado do controle. E em grandes viewports, aumentar o zoom aumenta a chance de o texto desaparecer da tela.
Além disso, alguns rótulos contêm muito texto, o que faz com que ele seja dividido em várias linhas, o que interromperia o ritmo visual se colocado próximo ao controle.
Embora você deva manter os rótulos concisos, nem sempre é possível. Usar um padrão que acomoda conteúdo variado – posicionando rótulos acima do controle – é uma boa estratégia.
### Aparência, tamanho e espaçoOs campos de formulário devem se parecer com campos de formulário. Mas o que isso significa exatamente?
Isso significa que uma caixa de texto deve se parecer com uma caixa de texto. Caixas vazias significam “preencha-me” em virtude de estarem vazias, como um livro de colorir. Isso é parte do motivo pelo qual os espaços reservados são inúteis. Eles removem a affordance percebida que uma caixa de texto vazia forneceria.
Isso também significa que o espaço vazio deve ser encaixotado (limitado). Remover a borda, ou ter apenas uma borda inferior, por exemplo, remove as affordances percebidas. Uma borda inferior pode parecer à primeira vista um separador. Mesmo que você saiba que precisa preencher algo, o valor fica acima ou abaixo da linha?
Espacialmente, o rótulo deve estar mais próximo de seu controle de formulário, não do controle do campo anterior. Coisas que parecem próximas sugerem que elas pertencem umas às outras. Ter espaçamento igual pode melhorar a estética, mas seria ao custo da usabilidade.
Por fim, o rótulo e a caixa de texto em si devem ser grandes o suficiente para serem lidos e tocados. Isso provavelmente significa um tamanho de fonte de pelo menos 16 pixels e, idealmente, um alvo de toque geral de pelo menos 44 pixels.
### Estilos de focoEstilos de foco são uma perspectiva mais simples. Por padrão, os navegadores colocam um contorno ao redor do elemento em foco para que os usuários, especialmente aqueles que usam um teclado, saibam onde estão. O problema com o estilo padrão é que geralmente é fraco e difícil de ver, e um pouco feio.
Enquanto este for o caso, não fique tentado a removê-lo, porque isso diminuirá muito a experiência do usuário para aqueles que atravessam a tela pelo teclado. Podemos substituir o estilo padrão para torná-lo mais claro e esteticamente mais agradável.
input:focus { outline: 4px solid #ffbf47; }
## O campo de e-mailApesar de sua aparência simples, existem alguns detalhes importantes que entraram na construção do campo que afetam a experiência.
Conforme observado anteriormente, alguns campos têm uma dica além do rótulo, razão pela qual o rótulo está dentro de um período filho. A classe field-label
nos permite estilizá-lo por meio de CSS.
<div class="field"> <label for="email"> <span class="field-label">Email address</span> </label> <input type="email" name="email"> </div>
O rótulo em si é “endereço de e-mail” e usa maiúsculas e minúsculas. Em “Making a case for letter case”, John Saito explica que maiúsculas e minúsculas (em oposição a maiúsculas) geralmente são mais fáceis de ler, mais amigáveis e facilitam a identificação de substantivos. Se você seguir este conselho é com você, mas qualquer que seja o estilo que você escolher, certifique-se de usá-lo de forma consistente.
O atributo type
da entrada é definido como email
, que aciona um teclado na tela específico para email em dispositivos móveis. Isso dá aos usuários acesso fácil aos @
e .
(ponto) símbolos que todo endereço de e-mail deve conter.
As pessoas que usam um navegador não compatível verão uma entrada de texto padrão ( <input type="text">
). Esta é uma forma de aprimoramento progressivo, que é a pedra angular do design de experiências inclusivas.
O aprimoramento progressivo é sobre os usuários. Isso também facilita nossas vidas como designers e desenvolvedores. Em vez de acompanhar um conjunto de navegadores e dispositivos (o que é impossível!), podemos nos concentrar apenas nos recursos.
Em primeiro lugar, o aprimoramento progressivo é sempre oferecer aos usuários uma experiência razoável, independentemente do navegador, dispositivo ou qualidade da conexão. Quando as coisas derem errado – e elas darão – os usuários não sofrerão porque ainda podem fazer as coisas.
Há muitas maneiras pelas quais uma experiência pode dar errado. Talvez a folha de estilo ou script não seja carregado. Talvez tudo carregue, mas o navegador do usuário não reconhece HTML, CSS ou JavaScript. Aconteça o que acontecer, o uso de aprimoramento progressivo ao projetar experiências impede que os usuários tenham um tempo especialmente ruim.
Ele começa com HTML para estrutura e conteúdo. Se CSS ou JavaScript não carregar, tudo bem porque o conteúdo está lá.
Se tudo carregar bem, talvez vários elementos HTML não sejam reconhecidos. Por exemplo, alguns navegadores não entendem <input type="email">
. Tudo bem, porém, porque os usuários receberão uma caixa de texto ( <input type="text">
) em vez disso. Os usuários ainda podem inserir um endereço de e-mail; eles simplesmente não recebem um teclado específico para e-mail no celular.
Talvez o navegador não entenda algum CSS sofisticado e simplesmente o ignore. Na maioria dos casos, isso não é um problema. Digamos que você tenha um botão com border-radius: 10px
. Os navegadores que não reconhecem esta regra mostrarão um botão com cantos em ângulo. Indiscutivelmente, a affordance percebida do botão é reduzida, mas os usuários ficam ilesos. Em outros casos, pode ser útil usar consultas de recursos.
Depois, há o JavaScript, que é mais complicado. Quando o navegador tenta analisar métodos que ele não reconhece, ele vai dar um chilique. Isso pode fazer com que seus outros scripts (válidos e com suporte) falhem. Se o seu script não verificar primeiro se os métodos existem (detecção de recursos) e funcionam (teste de recursos) antes de usá-los, os usuários podem obter uma interface quebrada. Por exemplo, se o manipulador de cliques de um botão chamar um método que não é reconhecido, o botão não funcionará. Isso é ruim.
É assim que você melhora. Mas o melhor é não precisar de nenhum aprimoramento. HTML com um pouco de CSS pode dar aos usuários uma excelente experiência. É o conteúdo que conta e você não precisa de JavaScript para isso. Quanto mais você puder confiar no conteúdo (HTML) e no estilo (CSS), melhor. Eu não posso enfatizar isso o suficiente: muitas vezes, a experiência básica é a melhor e mais eficiente. Não adianta melhorar algo se não agregar valor (ver princípio de design inclusivo 7).
Claro, há momentos em que a experiência básica não é tão boa quanto poderia ser - é quando é hora de aprimorar. Mas se seguirmos a abordagem acima, quando um pedaço de CSS ou JavaScript não for reconhecido ou executado, as coisas ainda funcionarão.
O aprimoramento progressivo nos faz pensar sobre o que acontece quando as coisas falham. Ela nos permite construir experiências com resiliência incorporada. Mas, igualmente, nos faz pensar se uma melhoria é realmente necessária; e se for, qual a melhor forma de fazê-lo.
## O campo de senhaEstamos usando a mesma marcação do campo de email discutido anteriormente. Se você estiver usando uma linguagem de modelo, poderá criar um componente que acomode os dois tipos de campo. Isso ajuda a aplicar o princípio de design inclusivo 3, seja consistente .
<div class="field"> <label for="password"> <span class="field-label">Choose password</span> <span class="field-hint">Must contain 8+ characters with at least 1 number and 1 uppercase letter.</span> </label> <input type="password" name="password"> </div>
O campo de senha contém uma dica. Sem um, os usuários não entenderão os requisitos, o que provavelmente causará um erro quando tentarem prosseguir.
O atributo type="password"
mascara o valor da entrada substituindo o que o usuário digita por pequenos pontos pretos. Esta é uma medida de segurança que impede que as pessoas vejam o que você digitou se estiverem por perto.
Ocultar o valor enquanto o usuário digita dificulta a correção de erros de digitação. Então, quando um é feito, geralmente é mais fácil excluir toda a entrada e começar de novo. Isso é frustrante, pois a maioria dos usuários não está usando um computador com uma pessoa olhando por cima do ombro.
Devido ao aumento do risco de erros de digitação, alguns formulários de registro incluem um campo adicional “Confirmar senha”. Essa é uma medida de precaução que exige que o usuário digite a mesma senha duas vezes, dobrando o esforço e degradando a experiência do usuário. Em vez disso, é melhor permitir que os usuários revelem suas senhas, que atendem aos princípios 4 e 5, dão controle e oferecem opções , respectivamente. Dessa forma, os usuários podem optar por revelar sua senha quando souberem que ninguém está olhando, reduzindo o risco de erros de digitação.
Versões recentes do Internet Explorer e do Microsoft Edge fornecem esse comportamento nativamente. Como estaremos criando nossa própria solução, devemos suprimir esse recurso usando CSS assim:
input[type=password]::-ms-reveal { display: none; }
Primeiro, precisamos injetar um botão ao lado da entrada. O elemento <button>
deve ser seu elemento principal para alterar qualquer coisa com JavaScript — exceto, isto é, para alterar a localização, que é para que servem os links. Quando clicado, deve alternar o atributo type entre password
e text
; e o rótulo do botão entre "Mostrar" e "Ocultar".
function PasswordReveal(input) { // store input as a property of the instance // so that it can be referenced in methods // on the prototype this.input = input; this.createButton(); }; PasswordReveal.prototype.createButton = function() { // create a button this.button = $('<button type="button">Show password</button>'); // inject button $(this.input).parent().append(this.button); // listen to the button's click event this.button.on('click', $.proxy(this, 'onButtonClick')); }; PasswordReveal.prototype.onButtonClick = function(e) { // Toggle input type and button text if(this.input.type === 'password') { this.input.type = 'text'; this.button.text('Hide password'); } else { this.input.type = 'password'; this.button.text('Show password'); } };
#### Sintaxe JavaScript e notas arquitetônicasComo há muitos tipos de JavaScript e diferentes maneiras de arquitetar componentes, vamos percorrer as opções usadas para construir o componente de revelação de senha e todos os componentes futuros do livro.
Primeiro, estamos usando um construtor. Um construtor é uma função convencionalmente escrita em maiúsculas — PasswordReveal
, não passwordReveal
. Ele é inicializado usando a palavra-chave new
, que nos permite usar o mesmo código para criar várias instâncias do componente:
var passwordReveal1 = new PasswordReveal(document.getElementById('input1')); var passwordReveal2 = new PasswordReveal(document.getElementById('input2'));
Segundo, os métodos do componente são definidos no protótipo — por exemplo, PasswordReveal.prototype.onButtonClick
. O protótipo é a maneira mais eficiente de compartilhar métodos em várias instâncias do mesmo componente.
Terceiro, o jQuery está sendo usado para criar e recuperar elementos e ouvir eventos. Embora o jQuery possa não ser necessário ou preferido, usá-lo significa que este livro pode se concentrar em formulários e não nas complexidades dos componentes entre navegadores.
Se você é um designer que codifica um pouco, a onipresença do jQuery e a baixa barreira à entrada devem ser úteis. Da mesma forma, se você preferir não usar o jQuery, não terá problemas para refatorar os componentes de acordo com sua preferência.
Você também deve ter notado o uso da função $.proxy
. Esta é a implementação de Function.prototype.bind
do jQuery. Se não usássemos essa função para ouvir eventos, o manipulador de eventos seria chamado no contexto do elemento ( this
). No exemplo acima, this.button
seria indefinido. Mas queremos que this
seja o objeto de revelação de senha, para que possamos acessar suas propriedades e métodos.
A interface de revelação de senha que construímos acima alterna o rótulo do botão entre "Mostrar senha" e "Ocultar senha". Alguns usuários de leitores de tela podem ficar confusos quando o rótulo do botão é alterado; uma vez que um usuário encontra um botão, ele espera que esse botão persista. Mesmo que o botão seja persistente, alterar o rótulo faz com que pareça não ser.
Se sua pesquisa mostrar que isso é um problema, você pode tentar duas abordagens alternativas.
Primeiro, use uma caixa de seleção com um rótulo persistente de “Mostrar senha”. O estado será sinalizado pelo atributo checked
. Os usuários do leitor de tela ouvirão “Mostrar senha, caixa de seleção, marcada” (ou similar). Os usuários que enxergam verão a marca de seleção da caixa de seleção. O problema com essa abordagem é que as caixas de seleção são para inserir dados, não para controlar a interface. Alguns usuários podem pensar que sua senha será revelada ao sistema.
Ou, segundo, altere o state
do botão – não o rótulo. Para transmitir o estado aos usuários do leitor de tela, você pode alternar o atributo aria-pressed
entre true
(pressionado) e false
(não pressionado).
<button type="button" aria-pressed="true"> Show password </button>
Ao focar o botão, os leitores de tela anunciarão: “Mostrar senha, botão de alternância, pressionado” (ou similar). Para usuários com visão, você pode estilizar o botão para parecer pressionado ou não pressionado de acordo usando o seletor de atributo assim:
[aria-pressed="true"] { box-shadow: inset 0 0 0 0.15rem #000, inset 0.25em 0.25em 0 #fff; }
Apenas certifique-se de que os estilos não prensados e prensados sejam óbvios e diferenciados, caso contrário, os usuários com visão podem ter dificuldade em dizer a diferença entre eles.
### MicrocópiaO rótulo é definido como "Escolher senha" em vez de "Senha". O último é um pouco confuso e pode levar o usuário a digitar uma senha que já possui, o que pode ser um problema de segurança. Mais sutilmente, pode sugerir que o usuário já está registrado, fazendo com que os usuários com deficiências cognitivas pensem que estão fazendo login.
Onde "Senha" é ambígua, "Escolher senha" fornece clareza.
## Estilos de botãoO que é um botão? Nos referimos a muitos tipos diferentes de componentes em uma página da Web como um botão. Na verdade, eu já abordei dois tipos diferentes de botão sem chamá-los. Vamos fazer isso agora.
Os botões que enviam formulários são “botões de envio” e normalmente são codificados como <input type="submit">
ou <button type="submit">
. O elemento <button>
é mais maleável, pois você pode aninhar outros elementos dentro dele. Mas raramente há necessidade disso. A maioria dos botões de envio contém apenas texto.
Observação: em versões mais antigas do Internet Explorer, se você tiver vários <button type="submit">
s, o formulário enviará o valor de todos os botões para o servidor, independentemente de qual foi clicado. Você precisará saber qual botão foi clicado para poder determinar a ação correta a ser tomada, e é por isso que esse elemento deve ser evitado.
Outros botões são injetados na interface para aprimorar a experiência com JavaScript — assim como fizemos com o componente de revelação de senha discutido anteriormente. Esse também era um <button>
mas seu type
foi definido como button
(não submit
).
Em ambos os casos, a primeira coisa a saber sobre botões é que eles não são links. Os links geralmente são sublinhados (por estilos de agente do usuário) ou posicionados especialmente (em uma barra de navegação) para que sejam distinguíveis do texto normal. Ao passar o mouse sobre um link, o cursor se transformará em um ponteiro. Isso ocorre porque, diferentemente dos botões, os links têm uma fraca percepção de affordance.
Em Resilient Web Design , Jeremy Keith discute a ideia de honestidade material. Ele diz: “Um material não deve ser usado como substituto de outro. Caso contrário, o resultado final é enganoso.” Fazer um link parecer um botão é materialmente desonesto. Ele informa aos usuários que links e botões são os mesmos quando não são.
Os links podem fazer coisas que os botões não podem fazer. Os links podem ser abertos em uma nova guia ou marcados para mais tarde, por exemplo. Portanto, os botões não devem se parecer com links, nem devem ter um cursor de ponteiro. Em vez disso, devemos fazer os botões parecerem botões, que têm uma percepção naturalmente forte. Se eles têm cantos arredondados, sombras e bordas é com você, mas eles devem se parecer com botões independentemente.
Os botões ainda podem dar feedback ao passar o mouse (e ao focar) alterando a cor do plano de fundo, por exemplo.
### ColocaçãoOs botões de envio geralmente são colocados na parte inferior do formulário: na maioria dos formulários, os usuários preenchem os campos de cima para baixo e depois enviam. Mas o botão deve ser alinhado à esquerda, à direita ou ao centro? Para responder a essa pergunta, precisamos pensar em onde os usuários naturalmente a procurarão.
Rótulos de campo e controles de formulário são alinhados à esquerda (em idiomas de leitura da esquerda para a direita) e executados de cima para baixo. Os usuários vão procurar o próximo campo abaixo do último. Naturalmente, então, o botão enviar também deve ser posicionado nesse local: à esquerda e diretamente abaixo do último campo. Isso também ajuda os usuários que aumentam o zoom, pois um botão alinhado à direita pode desaparecer mais facilmente da tela.
### TextoO texto do botão é tão importante quanto seu estilo. O texto deve descrever explicitamente a ação que está sendo tomada. E porque é uma ação, deve ser um verbo. Devemos procurar usar o mínimo de palavras possível porque é mais rápido de ler. Mas não devemos remover palavras à custa da clareza.
As palavras exatas podem corresponder ao tom de voz da sua marca, mas não troque clareza por estranheza.
A linguagem simples e simples é fácil para todos entenderem. As palavras exatas dependerão do tipo de serviço. Para o nosso formulário de registro “Registrar” é bom, mas dependendo do seu serviço “Join” ou “Cadastre-se” pode ser mais apropriado.
## ValidaçãoApesar de nossos esforços para criar uma experiência de registro inclusiva, simples e sem atritos, não podemos eliminar o erro humano. As pessoas cometem erros e, quando o fazem, devemos corrigi-los o mais fácil possível.
Quando se trata de validação de formulários, há vários detalhes importantes a serem considerados. Desde a escolha de quando dar feedback, passando por como exibir esse feedback, até a formulação de uma boa mensagem de erro – todas essas coisas precisam ser levadas em consideração.
### Validação HTML5A validação HTML5 já existe há algum tempo. Ao adicionar apenas alguns atributos HTML, os navegadores de suporte marcarão campos incorretos quando o formulário for enviado. Os navegadores não compatíveis retornam à validação do lado do servidor.
Normalmente, eu recomendaria usar a funcionalidade que o navegador fornece gratuitamente porque geralmente é mais eficiente, robusta e acessível. Sem mencionar, torna-se mais familiar para os usuários à medida que mais sites começam a usar a funcionalidade padrão.
Embora o suporte à validação HTML5 seja muito bom, ele não é implementado de maneira uniforme. Por exemplo, o atributo obrigatório pode marcar campos como inválidos desde o início, o que não é desejável. Alguns navegadores, como o Firefox 45.7, mostrarão um erro de “Digite um endereço de e-mail” mesmo que o usuário tenha digitado algo na caixa, enquanto o Chrome, por exemplo, diz “Por favor, inclua um '@' no endereço de e-mail”. o que é mais útil.
Também queremos fornecer aos usuários a mesma interface, independentemente de os erros serem detectados no servidor ou no cliente. Por esses motivos, projetaremos nossa própria solução. A primeira coisa a fazer é desativar a validação HTML5: <form novalidate>
Quando o usuário envia o formulário, precisamos verificar se há erros. Se houver, precisamos impedir que o formulário envie os detalhes para o servidor.
function FormValidator(form) { form.on('submit', $.proxy(this, 'onSubmit')); } FormValidator.prototype.onSubmit = function(e) { if(!this.validate()) { e.preventDefault(); // show errors } };
Observe que estamos ouvindo o evento submit do formulário, não o evento click do botão. O último impedirá que os usuários possam enviar o formulário pressionando Enter quando o foco estiver em um dos campos. Isso também é conhecido como envio de formulário implícito .
### Exibindo comentáriosEstá tudo muito bem em detectar a presença de erros, mas neste ponto os usuários não estão mais avisados. Há três partes diferentes da interface que precisam ser atualizadas. Vamos falar sobre cada um deles agora.
#### Título do documento O <title>
do documento é a primeira parte de uma página da Web a ser lida pelos leitores de tela. Como tal, podemos usá-lo para informar rapidamente aos usuários que algo deu errado com seu envio. Isso é especialmente útil quando a página é recarregada após uma solicitação do servidor.
Embora estejamos aprimorando a experiência do usuário ao detectar erros no cliente com JavaScript, nem todos os erros podem ser detectados dessa maneira. Por exemplo, verificar se um endereço de e-mail ainda não foi usado só pode ser verificado no servidor. E, em qualquer caso, o JavaScript é propenso a falhas, então não podemos confiar apenas em sua disponibilidade.
Onde o título da página original pode ser "Register for [service]", em caso de erro, deve ser "(2 errors) Register for [service]" (ou similar). A redação exata depende um pouco da opinião.
O seguinte JavaScript atualiza o título:
document.title = "(" + this.errors.length + ")" + document.title;
Conforme observado acima, isso é principalmente para usuários de leitores de tela, mas, como costuma ser o caso do design inclusivo, o que ajuda um conjunto de usuários também ajuda todos os outros. Desta vez, o título atualizado atua como uma notificação na guia.
Resumo do erro
Em comparação com o elemento de título, o resumo do erro é mais proeminente, o que informa aos usuários com visão que algo deu errado. Mas também é responsável por permitir que os usuários entendam o que deu errado e como corrigi-lo.
Ele está posicionado na parte superior da página para que os usuários não precisem rolar para baixo para vê-lo após a atualização da página (caso um erro seja detectado no servidor). Convencionalmente, os erros são coloridos em vermelho. No entanto, confiar apenas na cor pode excluir usuários daltônicos. Para chamar a atenção para o resumo, considere também usar posição, tamanho, texto e iconografia.
O painel inclui um título, “Há um problema”, para indicar o problema. Observe que não diz a palavra “Erro”, o que não é muito amigável. Imagine que você estava preenchendo seus dados para comprar um carro em um showroom e cometeu um erro. O vendedor não diria “Erro” – na verdade, seria estranho se ele dissesse isso.
<div class="errorSummary" role="group" tabindex="-1" aria-labelledby="errorSummary-heading"> <h2>There's a problem</h2> <ul> <li><a href="#emailaddress">Enter an email address</a></li> <li><a href="#password">The password must contain an uppercase letter</a></li> </ul> </div>
O container tem um role
de group
, que é usado para agrupar um conjunto de elementos de interface: neste caso, o cabeçalho e os links de erro. O atributo tabindex
é definido como -1
, para que possa ser focado programaticamente com JavaScript (quando o formulário for enviado com erros). Isso garante que o painel de resumo de erros seja exibido. Caso contrário, a interface pareceria sem resposta e quebrada quando enviada.
Nota: Usar tabindex="0"
significa que será permanentemente focalizável por meio da tecla Tab , que é uma falha 2.4.3 Focus Order WCAG. Se os usuários podem guiar para algo, eles esperam que realmente faça algo.
FormValidator.prototype.showSummary = function () { // ... this.summary.focus(); };
Abaixo, há uma lista de links de erro. Clicar em um link definirá o foco para o campo incorreto, o que permite que os usuários entrem no formulário rapidamente. O atributo href
do link é definido para o id do controle, o que em alguns navegadores é suficiente para definir o foco para ele. No entanto, em outros navegadores, clicar no link apenas rolará a entrada para a visualização, sem focalizá-la. Para corrigir isso, podemos focar a entrada explicitamente.
FormValidator.prototype.onErrorClick = function(e) { e.preventDefault(); var href = e.target.href; var id = href.substring(href.indexOf("#"), href.length); $(id).focus(); };
Quando não houver erros, o painel de resumo deve ficar oculto. Isso garante que haja apenas um painel de resumo na página e que ele apareça consistentemente no mesmo local, independentemente de os erros serem renderizados pelo cliente ou pelo servidor. Para ocultar o painel, precisamos adicionar uma classe de hidden
.
<div class="errorSummary hidden" ...></div>
.hidden { display: none; }
Observação: você pode usar o atributo/propriedade hidden
para alternar a visibilidade de um elemento, mas há menos suporte para isso. O design inclusivo é sobre tomar decisões que você sabe que provavelmente não excluirão as pessoas. O uso de uma classe está alinhado com essa filosofia.
Precisamos colocar a mensagem de erro relevante logo acima do campo. Isso evita que os usuários rolem a página para cima e para baixo para verificar a mensagem de erro e os mantém movendo para baixo no formulário. Se a mensagem for colocada abaixo do campo, aumentaremos a chance de ela ser obscurecida pelo painel de preenchimento automático do navegador ou pelo teclado na tela.
<div class="field"> <label for="blah"> <span class="field-error"> <svg width="1.5em" height="1.5em"><use xmlns:xlink="https://www.w3.org/1999/xlink" xlink:href="#warning-icon"></use></svg> Enter your email address. </span> <span class="field-error">Enter an email address</span> </label> </div>
Como o padrão de dica mencionado anteriormente, a mensagem de erro é injetada dentro do rótulo. Quando o campo estiver focado, os usuários do leitor de tela ouvirão a mensagem no contexto, para que possam se mover livremente pelo formulário sem precisar consultar o resumo.
A mensagem de erro é vermelha e usa um ícone de aviso SVG para chamar a atenção dos usuários. Se tivéssemos usado apenas uma mudança de cor para indicar um erro, isso excluiria usuários daltônicos. Portanto, isso funciona muito bem para usuários com visão – mas e os usuários de leitores de tela?
Para dar aos usuários com visão e sem visão uma experiência equivalente, podemos usar o atributo aria-invalid
bem suportado. Quando o usuário focar a entrada, ele agora anunciará “Inválido” (ou similar) nos leitores de tela.
<input aria-inval>
Nota: O formulário de inscrição consiste apenas em entradas de texto. No capítulo 3, “Um formulário de reserva de voo”, veremos como injetar erros de forma acessível para grupos de campos, como botões de opção.
### Enviando o formulário novamenteAo enviar o formulário pela segunda vez, precisamos limpar os erros existentes da visualização. Caso contrário, os usuários poderão ver erros duplicados.
FormValidator.prototype.onSubmit = function(e) { this.resetPageTitle(); this.resetSummaryPanel(); this.removeInlineErrors(); if(!this.validate()) { e.preventDefault(); this.updatePageTitle(); this.showSummaryPanel(); this.showInlineErrors(); } };
### Inicialização Tendo terminado de definir o componente FormValidator
, agora estamos prontos para inicializá-lo. Para criar uma instância de FormValidator
, você precisa passar o elemento form como o primeiro parâmetro.
var validator = new FormValidator(document.getElementById('registration'));
Para validar o campo de email, por exemplo, chame o método addValidator()
:
validator.addValidator('email', [{ method: function(field) { return field.value.trim().length > 0; }, message: 'Enter your email address.' },{ method: function(field) { return (field.value.indexOf('@') > -1); }, message: 'Enter the 'at' symbol in the email address.' }]);
O primeiro parâmetro é o name
do controle e o segundo é uma matriz de objetos de regra. Cada regra contém duas propriedades: method
e message
. O method
é uma função que testa várias condições para retornar true
ou false
. False coloca o campo em um estado de erro, que é usado para preencher a interface com erros, conforme discutido anteriormente.
Em The Design of Everyday Things , Don Norman fala sobre projetar para o erro. Ele fala sobre a forma como as pessoas conversam:
“Se uma pessoa diz algo que acreditamos ser falso, questionamos e debatemos. Não emitimos um sinal de alerta. Nós não apitamos. Não damos mensagens de erro. […] Em conversas normais entre dois amigos, as distorções são tidas como normais, como aproximações do que realmente se quis dizer.”
Ao contrário dos humanos, as máquinas não são inteligentes o suficiente para determinar o significado da maioria das ações, mas geralmente perdoam muito menos os erros do que precisam. Jared Spool faz uma piada sobre isso em “Is Design Is Metrically Opposed?” (cerca de 42 minutos em):
“É preciso uma linha de código para pegar um número de telefone e remover todos os traços, parênteses e espaços, e são necessárias dez linhas de código para escrever uma mensagem de erro que você os deixou”.
O método addValidator
(mostrado acima) demonstra como projetar regras de validação para que elas perdoem erros triviais. A primeira regra, por exemplo, apara o valor antes de verificar seu comprimento, reduzindo a carga do usuário.
A validação em linha ao vivo fornece feedback aos usuários enquanto eles digitam ou quando saem do campo ( onblur
). Há algumas evidências para mostrar que a validação em linha ao vivo melhora a precisão e diminui os tempos de conclusão em formulários longos. Isso tem a ver parcialmente com dar feedback aos usuários quando os requisitos do campo estão frescos nas mentes dos usuários. Mas a validação em linha ao vivo (ou validação ao vivo para abreviar) apresenta vários problemas.
Para entradas que requerem um certo número de caracteres, o primeiro toque de tecla sempre constituirá uma entrada inválida. Isso significa que os usuários serão interrompidos precocemente, o que pode fazer com que eles mudem de contexto mental, desde a inserção de informações até a correção.
Alternativamente, podemos esperar até que o usuário insira caracteres suficientes antes de mostrar um erro. Mas isso significa que os usuários só recebem feedback depois de inserirem um valor correto, o que é um pouco inútil.
Poderíamos esperar até que o usuário deixasse o campo ( onblur
), mas isso é tarde demais, pois o usuário se preparou mentalmente (e muitas vezes começou a digitar) o próximo campo. Além disso, alguns usuários trocam de janela ou usam um gerenciador de senhas ao usar um formulário. Isso acionará o evento de desfoque, fazendo com que um erro seja exibido antes que o usuário termine. Tudo muito frustrante.
Lembre-se, não há problema em dar feedback aos usuários sem atualizar a página. Também não há problema em colocar as mensagens de erro em linha (ao lado dos campos) — já fizemos isso. O problema com o feedback ao vivo é que ele interrompe os usuários cedo ou tarde demais, o que geralmente resulta em uma experiência chocante.
Se os usuários estão vendo erros com frequência, provavelmente há algo errado em outro lugar. Concentre-se em encurtar seu formulário e fornecer uma melhor orientação (boa rotulagem e texto de dica). Dessa forma, os usuários não devem ver mais do que o erro estranho. Veremos formas mais longas no próximo capítulo.
### Padrão de afirmação da lista de verificaçãoUma variação da validação ao vivo envolve marcar as regras (marcando-as como completas) conforme o usuário digita. Isso é menos invasivo do que a validação ao vivo, mas não é adequado para todos os tipos de campo. Aqui está um exemplo do formulário de inscrição do MailChimp, que emprega essa técnica para o campo de senha.
Você deve colocar as regras acima do campo. Caso contrário, o teclado na tela pode obscurecer o feedback. Como resultado, os usuários podem parar de digitar e ocultar o teclado para verificar o feedback.
### Uma observação sobre como desabilitar os botões de envioAlguns formulários são projetados para desabilitar o botão de envio até que todos os campos se tornem válidos. Existem vários problemas com isso.
Primeiro, os usuários ficam imaginando o que realmente está errado com suas entradas. Em segundo lugar, os botões desabilitados não são focalizáveis, o que dificulta a descoberta do botão por usuários cegos que navegam usando a tecla Tab . Terceiro, os botões desativados são difíceis de ler, pois estão acinzentados.
Como estamos fornecendo aos usuários um feedback claro, quando o usuário espera, não há uma boa razão para tirar o controle do usuário desabilitando o botão de qualquer maneira.
### Criando uma boa mensagem de erroNão há nada mais importante do que o conteúdo. Os usuários não acessam seu site para apreciar o design. Eles vêm para aproveitar o conteúdo ou o resultado do uso de um serviço.
Mesmo a experiência mais pensada, inclusiva e lindamente projetada não conta para nada se ignorarmos as palavras usadas para criar mensagens de erro. Um estudo mostrou que a exibição de mensagens de erro personalizadas aumentou as conversões em 0,5%, o que equivale a mais de £ 250.000 em receita anual.
“O conteúdo é a experiência do usuário.”
- Gina Redish
Como rótulos, dicas e qualquer outro conteúdo, uma boa mensagem de erro fornece clareza com o mínimo de palavras possível. Normalmente, devemos direcionar o design de uma interface com base no conteúdo – e não o contrário. Mas, neste caso, entender como e por que você mostra mensagens de erro influencia o design das palavras. É por isso que Jared Spool diz que “conteúdo e design são parceiros de trabalho inseparáveis”.
Estamos mostrando mensagens no resumo na parte superior da tela e ao lado dos campos. Manter duas versões da mesma mensagem é difícil de vender por um ganho pouco convincente. Em vez disso, crie uma mensagem de erro que funcione em ambos os locais. “Digite um símbolo 'arroba'” precisa do contexto do rótulo do campo para fazer sentido. “Seu endereço de e-mail precisa de um símbolo 'arroba'” funciona bem em ambos os lugares.
Evite gentilezas, como iniciar cada mensagem de erro com “Por favor”. Por um lado, isso parece educado; por outro, atrapalha e implica uma escolha.
Qualquer que seja a abordagem adotada, haverá alguma repetição devido à natureza do conteúdo. E o teste geralmente envolve o envio do formulário sem inserir nenhuma informação. Isso torna a repetição muito óbvia, o que pode nos levar a enlouquecer. Mas com que frequência isso acontece? A maioria dos usuários não está tentando quebrar a interface.
Erros diferentes requerem formatação diferente. Instruções como “Digite seu primeiro nome” são naturais. Mas “Digite um nome com 35 caracteres ou menos” é mais longo, mais extenso e menos natural do que uma descrição como “O nome deve ter 35 caracteres ou menos”.
Aqui está uma lista de verificação:
- Ser conciso. Não use mais palavras do que o necessário, mas não omita palavras à custa da clareza.
- Ser consistente. Use o mesmo tom, as mesmas palavras e a mesma pontuação.
- Seja específico. Se você sabe por que algo deu errado, diga. “O e-mail é inválido.” é ambíguo e sobrecarrega o usuário. “O e-mail precisa de um símbolo 'arroba'” é claro.
- Seja humano, evite jargões. Não use palavras como inválido, proibido e obrigatório.
- Use linguagem simples. As mensagens de erro não são uma oportunidade para promover o tom de voz bem-humorado da sua marca.
- Use a voz ativa. Quando um erro é uma instrução e você diz ao usuário o que fazer. Por exemplo, "Digite seu nome", não "Primeiro nome deve ser inserido".
- Não culpe o usuário. Deixe-os saber o que está errado e como corrigi-lo.
Neste capítulo, resolvemos vários desafios fundamentais de design de formulários que são aplicáveis muito além de um simples formulário de registro. Em muitos aspectos, este capítulo foi tanto sobre o que não fazer, quanto sobre o que devemos. Ao evitar padrões de economia de espaço novos e artificiais para focar na redução do número de campos que incluímos, evitamos várias falhas de usabilidade ao mesmo tempo em que tornamos os formulários mais agradáveis.
### Coisas a evitar- Usando o atributo
placeholder
como um mecanismo para armazenar rótulo e texto de dica. - Usando tipos de entrada incorretos.
- Botões de estilo e links da mesma forma.
- Validando campos conforme os usuários digitam.
- Desativando botões de envio.
- Usando jargão complexo e microcópia influenciada pela marca.
E é isso. Se você gostou deste primeiro capítulo dos Padrões de Design de Formulários , você pode obter o livro imediatamente. Leitura feliz!
e-book
$ 19 Adquira o e-bookPDF, ePUB, Kindle. Gratuito para Membros Smashing.
Capa dura
$ 39 Obter a impressão (incl. e-book)Impresso, capa dura de qualidade. Envio gratuito de correio aéreo para todo o mundo.