Como fazer uma lista suspensa no HTML
Uma lista suspensa é um elemento <select> com um <option> para cada escolha. O value de cada opção é o que o formulário envia; o texto entre as tags é o que o usuário vê. Escolha uma e aperte Submit:
O formulário envia language=js: o name do select e o value da opção escolhida. selected define o padrão; sem ele, a primeira opção é a escolhida. Se uma opção não tem value, o texto dela é enviado no lugar.
Ligue o label ao select com for e id (ou envolvendo-o) para que clicar no label coloque o foco na lista e os leitores de tela a anunciem.
Atributos de select e option
| Elemento | Atributo | Faz |
|---|---|---|
<select> | name | A chave com que o valor é enviado |
<select> | required | Uma opção de verdade precisa ser escolhida, e não um primeiro placeholder vazio |
<select> | multiple | Várias opções podem ser escolhidas |
<select> | size | Quantas linhas ficam visíveis (vira uma caixa de lista) |
<select> | disabled | A lista inteira fica desligada e não é enviada |
<option> | value | O que é enviado quando ela é escolhida |
<option> | selected | Escolhida quando a página carrega |
<option> | disabled | Aparece, mas não pode ser escolhida |
<optgroup> | label | O título do grupo |
Uma opção de placeholder com required
Um select sempre tem um valor, então sem um placeholder a primeira opção de verdade é enviada mesmo que o usuário nunca tenha mexido na lista. Uma primeira opção vazia resolve isso, e required impede o envio até uma opção de verdade ser escolhida:
Aperte Continue antes de escolher: o navegador recusa e pede que você selecione um item. O placeholder tem value="", que é o que required considera vazio, e disabled para que não possa ser escolhido de novo depois que um país foi selecionado.
Agrupando opções com optgroup
<optgroup label="..."> coloca um título acima de um conjunto de opções. O título não é selecionável:
Grupos não podem ser aninhados: uma lista tem um nível de títulos, não mais. disabled num <optgroup> desativa todas as opções dele.
Seleção múltipla
multiple deixa o usuário escolher várias opções e transforma a lista suspensa numa caixa de lista. Segure Ctrl (Cmd no Mac) para adicionar opções uma a uma, ou Shift para selecionar um intervalo:
O formulário envia skills=html e skills=css: o mesmo nome uma vez por opção escolhida. Muita gente não conhece o Ctrl+clique, então, para poucas opções, um grupo de checkboxes é mais fácil de usar.
Lendo e definindo o valor no JavaScript
select.value lê e define o valor da opção escolhida, e o evento change dispara quando o usuário escolhe outra opção. Um uso comum é uma segunda lista cujas opções dependem da primeira:
new Option(text, value) cria uma opção. select.selectedIndex é a posição da opção escolhida, e select.selectedOptions lista as escolhidas, que é como se lê um select múltiplo.
Estilizando um select
A lista aberta é desenhada pelo navegador e pelo sistema operacional, e quase nada dela pode ser estilizado. A caixa fechada pode: appearance: none remove a seta nativa, e uma imagem de fundo coloca a sua no lugar:
O padding extra no fim deixa espaço para a seta, para que o texto de uma opção longa não passe por baixo dela. font: inherit importa tanto aqui quanto nos botões: por padrão os selects usam a fonte pequena de formulário do navegador. As opções da lista aberta mantêm a aparência nativa. O Chrome também consegue estilizar a lista aberta quando você ativa appearance: base-select; navegadores sem esse suporte mostram a lista nativa. Controle total em todo lugar exige um componente próprio feito com ARIA, o que dá muito mais trabalho para acertar do que parece.
select, radio buttons ou datalist?
| Use | Quando |
|---|---|
<select> | Uma escolha numa lista longa, ou onde falta espaço |
| Radio buttons | Uma escolha entre poucas opções que devem ficar todas visíveis (veja radio button no HTML) |
<input> com <datalist> | Sugestões, mas qualquer valor digitado é aceito |
Erros comuns
- Nenhum placeholder numa escolha obrigatória. A primeira opção de verdade é enviada mesmo que o usuário nunca a tenha escolhido.
- Um placeholder com um valor real, como
value="none".requiredo trata como uma escolha válida. Usevalue="". - Opções sem
valuequando o texto é longo ou traduzido. O servidor recebe o texto visível, que muda com o idioma. multiplepara poucas opções. Checkboxes são mais fáceis de usar.- Escutar
clicknas opções. Usechangeno<select>; ele também dispara em mudanças pelo teclado. - Nenhum label. Um select só com placeholder fica sem nome depois que uma opção é escolhida.
Perguntas frequentes
Como criar uma lista suspensa no HTML?
Use <select> com um <option> para cada escolha: <select name="color"><option value="red">Red</option><option value="blue">Blue</option></select>. Dê ao select um name e um <label>.
Como definir a opção padrão de um select?
Adicione selected a essa opção: <option value="blue" selected>Blue</option>. Sem isso, a primeira opção fica selecionada. No JavaScript, defina select.value = 'blue'.
Como colocar um placeholder num select?
Deixe a primeira opção vazia e não selecionável: <option value="" disabled selected>Choose a country</option>. Adicione required ao <select> para que o formulário não possa ser enviado até uma opção de verdade ser escolhida.
Como pegar o valor selecionado de um select no JavaScript?
select.value é o valor da opção selecionada. Para o texto visível, use select.selectedOptions[0].text, e escute o evento change para reagir quando a escolha mudar. Num select múltiplo, percorra select.selectedOptions.
Qual a diferença entre select e datalist?
Um <select> só permite as opções listadas. Um <input> com um <datalist> sugere opções enquanto o usuário digita, mas aceita qualquer texto. Use select quando a resposta precisa ser uma das suas.