O estilo dos controles de formulário, como o elemento <select>
, é um dos principais problemas dos desenvolvedores há anos, e estamos trabalhando em uma solução. Embora esse trabalho seja complexo e tenha demorado muito para ser concluído, estamos chegando perto de lançar esse recurso. Uma versão personalizável do elemento de seleção está oficialmente na etapa 2 do WHATWG, com forte interesse em vários navegadores e um protótipo para você testar no Chrome Canary 130.
Teste e envie seu feedback
Verifique se a instalação do Chrome Canary está atualizada para a versão 130 e se a flag de recursos experimentais da plataforma da Web está ativada. Para ativar essa flag, acesse chrome://flags na barra de endereço e ative #experimental-web-platform-features. Em seguida, você vai poder conferir as demonstrações do Codepen nesta postagem. Você também pode conferir esta coleção do CodePen para acessar todos eles em um só lugar.
Use este formulário para enviar feedback sobre o recurso. O processo leva apenas três minutos.
Vamos conhecer os recursos da API de seleção personalizável, que é baseada na tag de seleção HTML.
Ativação do novo <select>
Para ativar o novo comportamento, use a propriedade CSS appearance
no botão de seleção na página e no seletor de seleção. Para ativar, defina appearance: base-select
no elemento <select>
e no ::picker(select)
.
::picker(select)
é um novo pseudoelemento fornecido pelo user-agent que se aplica apenas a elementos <select>
que foram ativados para o novo comportamento usando appearance: base-select
. Esse pseudoelemento do seletor é o pop-up acionado pelo botão de seleção básico. Você pode ativar as duas, conforme mostrado no código abaixo:
select,
::picker(select) {
appearance: base-select;
}
Você pode ativar apenas o botão na página, mas não pode ativar apenas o popover do seletor sem ativar o botão na página. O ::picker(select)
só é criado quando o appearance: base-select
é aplicado ao <select>
.
Agora você pode personalizar o elemento de seleção. O novo elemento de seleção personalizável tem alguns estilos padrão que são iguais em todos os navegadores e sistemas operacionais. Confira como o seletor personalizado padrão se compara ao seletor existente no Chrome no macOS:
Como as partes se encaixam
Quando você estiver no novo modo de seleção personalizável, os novos elementos a que você tem acesso incluem:
- selectedoption
: reflete o HTML interno da opção selecionada no momento.
- option::before
: contém uma marca de seleção para indicar a opção selecionada como uma affordance de acessibilidade padrão (sujeito a alterações).
- ::picker(select)
: pop-up que contém todo o conteúdo fora do button
dentro de um seletor personalizável.
É possível estilizar qualquer parte da seleção. Por exemplo, é possível adicionar conteúdo não interativo arbitrário nos elementos <option>
, definir o estilo do botão na página que abre o menu suspenso de seleção e definir o estilo da lista suspensa de opções (::picker(select)
).
Também é possível estilizar o button
, o indicador de seta "traga sua própria seta" e adicionar conteúdo arbitrário dentro e ao redor de qualquer um dos elementos. Além de adicionar conteúdo, você pode ocultar qualquer um desses novos elementos e estilos padrão. Por exemplo, se você não quiser uma marca de seleção de indicador no pseudoelemento ::before da opção, use o CSS a seguir.
/* Remove the default checkmark from the selected option */
option::before {
display: none;
}
Embora possa haver um número ilimitado de elementos dentro da seleção, o navegador agrupa tudo fora de um elemento <button>
no pseudoelemento ::picker(select)
, que se comporta como um pop-up ancorado ao botão. Essa <button>
alterna o ::picker(select)
. As opções e outros elementos diretamente dentro do seletor serão elevados para o ::picker(select)
, ou você pode usar seu próprio wrapper para estilizar. Esse wrapper também será colocado dentro do pseudoelemento ::picker(select)
.
<select>
<button>
<selectedoption></selectedoption>
</button>
// Everything else that will go into the ::picker(select) popover
</select>
O novo <select>
personalizável usa a funcionalidade do pop-up e do posicionamento de âncora. Ele foi criado com essas duas tecnologias. Isso significa que a lista de opções suspensas em um elemento de seleção funciona como um pop-up ancorado ao botão acionador que abre o elemento.
É possível usar o posicionamento de âncora para estilizar esse pop-up ::picker(select)
, incluindo a ancoragem a outros elementos. Esse modelo de conteúdo também significa que os estilos de animação da camada superior funcionam com a lista de opções para animar os efeitos de entrada e saída.
Melhorar o elemento <select>
Antes, a equipe do Chrome estava trabalhando na ideia de um elemento <selectlist>
. O que é descrito nesta postagem é que o recurso foi redesenhado para reutilizar o elemento <select>
.
Um dos principais benefícios da reutilização do elemento <select>
é a capacidade de aprimorar progressivamente o elemento HTML básico. Em comparação com um elemento totalmente novo, a reutilização de <select>
ainda renderiza conteúdo significativo na página. O exemplo a seguir mostra a seleção personalizada em comparação com o que um usuário em um navegador sem suporte veria:
Estilo básico
As mudanças podem ser tão simples quanto o estilo visual do elemento de seleção. Por exemplo, para atualizar os estilos de botão, de passar o cursor e de foco ou o plano de fundo das opções de seleção. Depois de ativar a appearance: base-select
, aplique o CSS que quiser às partes da seleção.
Para personalizar o indicador de seta, adicione seu próprio botão e seta dentro do seletor.
<select>
<button>
<selectedoption></selectedoption>
<span>
// Arrow here
</span>
</button>
// Everything else that will go into the ::picker(select) popover
</select>
Em seguida, estilize a seta:
/* style the arrow */
button span {
/* arrow styles */
transition: rotate 0.2s;
}
/* adjust arrow styles when the picker is open */
select:open button span {
rotate: -180deg;
}
Conteúdo complexo nas opções
Vá além com a capacidade de adicionar e estilizar conteúdo além de strings nos elementos <option>
dentro de <select>
. Um exemplo básico é adicionar imagens de bandeiras ao lado dos nomes dos países em um menu suspenso. Para isso, adicione um elemento de imagem ao lado do texto da opção.
<option value="france">
<img src="img/flag_of_france.svg" alt="" />
<span>France</span>
</option>
Um exemplo mais complexo pode incluir fotos de perfil, nomes e informações alternativas para ajudar você a decidir qual item selecionar no menu suspenso.
<option value="eur">
<img src="euro-flag.png" alt="" />
<div class="currency">
<div class="currency-short">EUR</div>
<div class="currency-long">Euro</div>
</div>
<div class="symbol" aria-hidden="true">€</div>
</option>
Estilo da opção selecionada
Talvez você queira que a opção selecionada apareça de forma diferente no estado selecionado do que no menu suspenso. Um exemplo disso é a interface do Gmail, em que, para economizar espaço, o rótulo é removido quando a opção é selecionada. Para fazer isso, conecte-se ao elemento <selectedoption>
para estilizar. O <option>
contém toda a seguinte marcação:
<option value="reply-all">
<img class="material-symbol" src="material-symbol-reply.png">
<span class="text">Reply all</span>
</option>
Agora, aplique display: none
em .text
dentro de <selectedoption>
para ocultar o conteúdo de texto e mostrar apenas o ícone:
selectedoption .text {
display: none;
}
Opções interativas
Com controle total sobre o estilo do ::picker(select)
, crie a partir da demonstração anterior para torná-lo interativo ao passar o cursor e ao focar. Nesta demonstração, a nova função calc-size() é usada para animar a largura do seletor, passando da exibição dos ícones para a largura total das opções ao passar o cursor ou se o seletor tiver uma opção com foco visível.
/* base styles when picker is open but not interacted with */
::picker(select) {
width: var(--icon-width);
transition: width 0.5s;
}
/* animate the text in on hover & focus */
::picker(select):hover,
select:has(option:focus-visible)::picker(select) {
/* auto width! */
width: calc-size(auto, size + 0.5rem);
}
Limitações e observações sobre acessibilidade
Com grandes poderes, vêm grandes responsabilidades. Para manter a acessibilidade, há algumas limitações no recurso.
- Além dos elementos
<option>
, nenhum elemento interativo (focalizável) é permitido dentro do<select>
, como botões ou outros elementos. Por enquanto, o modelo de conteúdo proposto só permite elementos<div>
,<span>
,<option>
,<optgroup>
,<img>
,<svg>
e<hr>
. - Os botões divididos estão na fase de experimentação enquanto desenvolvemos uma solução acessível.
No futuro, o modelo de conteúdo deve se expandir para ser mais flexível, à medida que a história de acessibilidade dessas experiências se desenvolve.
Conclusão
Estamos animados para ver o progresso desse recurso nos grupos de trabalho e órgãos de padronização e compartilhar nosso progresso à medida que criamos ativamente o protótipo e avaliamos a forma desse recurso. Se algo não funcionar como esperado, informe-nos.
Como esse recurso ainda está em desenvolvimento, adoraríamos receber seu feedback neste formulário de feedback.
Agradecemos por ajudar a garantir que estamos fazendo isso direito e facilitar a criação de controles de formulário acessíveis e personalizáveis na Web.