# Semântica

# Formulários

Quando se cria um formulário, você pode usar os seguintes elementos: <form>, <label>, <input>, <textarea>, e <button>

Labels são tipicamente posicionadas no topo ou à esquerda dos campos do formulário:

<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">Enviar</button>
</form>
1
2
3
4
5
6
7
8
9
10
11
12

Veja o exemplo Simples formulário por Emanuel Gonçalves (@emanuelgsouza) no CodePen.

Observe como você pode incluir o atributo autocomplete='on' no elemento formulário e ele irá aplicar a todos os inputs do seu formulário. Você também pode definir diferentes valores para o atributo autocomplete (opens new window) para cada input.

# Labels

Forneça labels para descrever o propósito de todos os controles do formulário; ligando for a id:

<label for="name">Nome</label>
<input type="text" name="name" id="name" v-model="name" />
1
2

Veja o exemplo Form com Label por Emanuel Gonçalves (@emanuelgsouza) no CodePen.

Se você inspecionar este elemento em suas ferramentas de desenvolvedor do Chrome e abrir a guia Acessibilidade dentro da guia Elementos, verá como o input obtém seu nome a partir da label:

Ferramentas de Desenvolvedor do Chrome mostrando um nome acessível para o input usando a label

Aviso:

Embora você possa ter visto labels envolvendo os campos input como este:

<label>
  Nome:
  <input type="text" name="name" id="name" v-model="name" />
</label>
1
2
3
4

Definir explicitamente as labels com um id correspondente é melhor suportado por tecnologias assistivas.

# aria-label

Você também pode dar ao input um nome acessível com aria-label (opens new window).

<label for="name">Nome</label>
<input
  type="text"
  name="name"
  id="name"
  v-model="name"
  :aria-label="nameLabel"
/>
1
2
3
4
5
6
7
8

Veja o exemplo Form com ARIA label por Emanuel Gonçalves (@emanuelgsouza) no CodePen.

Sinta-se à vontade para inspecionar este elemento nas ferramentas de desenvolvedor do Chrome para ver como o nome acessível mudou:

Ferramentas de Desenvolvedor do Chrome mostrando um nome acessível para o input usando aria-label

# aria-labelledby

Usar aria-labelledby (opens new window) é semelhante a aria-label, mas será usado se o texto da label estiver visível na tela. Ele é emparelhado com outros elementos por seu id e você pode vincular vários ids:

<form
  class="demo"
  action="/dataCollectionLocation"
  method="post"
  autocomplete="on"
>
  <h1 id="billing">Fatura</h1>
  <div class="form-item">
    <label for="name">Nome:</label>
    <input
      type="text"
      name="name"
      id="name"
      v-model="name"
      aria-labelledby="billing name"
    />
  </div>
  <button type="submit">Enviar</button>
</form>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

Veja o exemplo Form com ARIA labelledby por Emanuel Gonçalves (@emanuelgsouza) no CodePen.

Ferramentas de Desenvolvedor do Chrome mostrando um nome acessível para o input usando aria-labelledby

# aria-describedby

aria-describedby (opens new window) é usado da mesma maneira que aria-labelledby, exceto que fornece uma descrição com informações adicionais que o usuário pode precisar. Pode ser usado para descrever os critérios para qualquer input:

<form
  class="demo"
  action="/dataCollectionLocation"
  method="post"
  autocomplete="on"
>
  <h1 id="billing">Fatura</h1>
  <div class="form-item">
    <label for="name">Nome completo:</label>
    <input
      type="text"
      name="name"
      id="name"
      v-model="name"
      aria-labelledby="billing name"
      aria-describedby="nameDescription"
    />
    <p id="nameDescription">Por favor, forneça seu nome e sobrenome.</p>
  </div>
  <button type="submit">Submit</button>
</form>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

Veja o exemplo Form com ARIA describedby por Emanuel Gonçalves (@emanuelgsouza) no CodePen.

Você pode ver a descrição inspecionando nas ferramentas de desenvolvedor do Chrome:

Ferramentas de Desenvolvedor do Chrome mostrando um nome acessível para o input usando aria-labelledby e descrição com aria-describedby

# Placeholder

Evite usar placeholders, pois eles podem confundir muitos usuários.

Um dos problemas com os placeholders é que eles não atendem aos critérios de contraste de cor (opens new window) por padrão; corrigir o contraste da cor faz com que o placeholder se pareça com dados pré-preenchidos nos inputs. Olhando para o exemplo a seguir, você pode ver que o placeholder para Sobrenome que atende aos critérios de contraste de cor, parece um dado pré-preenchido:

Veja o exemplo Form com placeholder por Emanuel Gonçalves (@emanuelgsouza) no CodePen.

É melhor fornecer todas as informações que o usuário precisa para preencher formulários fora de qualquer input.

# Instruções

Ao adicionar instruções para seus inputs, certifique-se de vinculá-los corretamente. Você pode fornecer instruções adicionais e vincular vários ids dentro de um aria-labelledby (opens new window). Isso permite um design mais flexível.

<fieldset>
  <legend>Usando aria-labelledby</legend>
  <label id="date-label" for="date">Data atual:</label>
  <input
    type="date"
    name="date"
    id="date"
    aria-labelledby="date-label date-instructions"
  />
  <p id="date-instructions">MM/DD/YYYY</p>
</fieldset>
1
2
3
4
5
6
7
8
9
10
11

Alternativamente, você pode anexar intruções ao input com aria-describedby (opens new window):

<fieldset>
  <legend>Usando aria-describedby</legend>
  <label id="dob" for="dob">Data de nascimento:</label>
  <input type="date" name="dob" id="dob" aria-describedby="dob-instructions" />
  <p id="dob-instructions">MM/DD/YYYY</p>
</fieldset>
1
2
3
4
5
6

Veja o exemplo Form com instruções por Emanuel Gonçalves (@emanuelgsouza) no CodePen.

# Escondendo Conteúdo

Normalmente não é recomendado ocultar visualmente as labels, mesmo se o input tiver um nome acessível. No entanto, se a funcionalidade do input pode ser compreendida com o conteúdo ao redor, podemos ocultar a label visual.

Veja este campo de pesquisa:

<form role="search">
  <label for="search" class="hidden-visually">Pesquisar: </label>
  <input type="text" name="search" id="search" v-model="search" />
  <button type="submit">Pesquisar</button>
</form>
1
2
3
4
5

Podemos fazer isso porque o botão de pesquisa ajudará os usuários visuais a identificar a finalidade do input.

Podemos usar CSS para ocultar elementos visualmente, mas mantê-los disponíveis para tecnologias assistivas:

.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%);
}
1
2
3
4
5
6
7
8
9
10
11

Veja o exemplo Form de pesquisa por Emanuel Gonçalves (@emanuelgsouza) no CodePen.

# aria-hidden="true"

Adicionar aria-hidden="true" ocultará o elemento de tecnologias assistivas, mas o deixará visualmente disponível para outros usuários. Não use em elementos focáveis, puramente em conteúdo decorativo, duplicados ou fora da tela.

<p>Este não está escondido de leitores de tela.</p>
<p aria-hidden="true">Este está escondido de leitores de tela.</p>
1
2

# Botões

Ao usar botões dentro de um formulário, você deve definir o tipo para evitar o envio do formulário. Você também pode usar inputs para criar botões:

<form action="/dataCollectionLocation" method="post" autocomplete="on">
  <!-- Botões -->
  <button type="button">Cancelar</button>
  <button type="submit">Enviar</button>

  <!-- Botões usando input -->
  <input type="button" value="Cancelar" />
  <input type="submit" value="Enviar" />
</form>
1
2
3
4
5
6
7
8
9

Veja o exemplo Form com botões por Emanuel Gonçalves (@emanuelgsouza) no CodePen.

# Imagens Funcionais

Você pode usar esta técnica para criar imagens funcionais.

  • Campo de input

    • Estas imagens irão agir como um botão de enviar em formulários
    <form role="search">
      <label for="search" class="hidden-visually">Pesquisar: </label>
      <input type="text" name="search" id="search" v-model="search" />
      <input
        type="image"
        class="btnImg"
        src="https://img.icons8.com/search"
        alt="Pesquisar"
      />
    </form>
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
  • Ícones

<form role="search">
  <label for="searchIcon" class="hidden-visually">Pesquisar: </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">Pesquisar</span>
  </button>
</form>
1
2
3
4
5
6
7
8

Veja o exemplo Imagens funcionais por Emanuel Gonçalves (@emanuelgsouza) no CodePen.