A API de seleção personalizável oferece uma maneira declarativa e baseada em CSS de estilizar elementos <select> para que correspondam perfeitamente ao sistema de design da sua marca. Ao ativar o appearance: base-select, você tem acesso ao DOM de sombra interno do elemento select, o que permite estilizar o botão, a lista de seleção de opções, o ícone de seta e o indicador de marca de seleção usando propriedades CSS padrão.
Antes, para ter um elemento select totalmente personalizado, era necessário recriar o controle do zero com JavaScript, o que geralmente prejudicava a acessibilidade, a navegação pelo teclado e a integração nativa com formulários. Com appearance: base-select, você tem um visual personalizado enquanto o navegador lida com o gerenciamento de foco, a renderização da camada superior e as vinculações de acessibilidade.
Como implementar
Para implementar o estilo de seleção de marca:
- Ativar a personalização: aplique
appearance: base-selectao elemento<select>e ao pseudoelemento::picker(select)(que segmenta a lista suspensa de opções). - Estruturar o botão personalizado (opcional): defina um elemento
<button>diretamente dentro de<select>para substituir o acionador padrão. Use o elemento<selectedcontent>dentro desse botão para representar o texto ou o conteúdo da opção selecionada. - Estilizar a lista do seletor: use o pseudoelemento
::picker(select)para aplicar tipografia, cores de fundo, bordas e sombras à lista suspensa. O navegador renderiza isso na camada superior, tornando os conflitos dez-indexuma coisa do passado. - Ícones internos de estilo:
- Use
select::picker-iconpara estilizar ou substituir o ícone de seta. - Use
option::checkmarkpara estilizar o indicador de marca de seleção ao lado da opção ativa.
- Use
- Opções de estilo: aplique estilos aos elementos
<option>para estados de passagem do cursor, preenchimento e layout.
Exemplo de código: Branded Courier Select
O exemplo a seguir demonstra uma seleção personalizada estilizada com uma fonte monoespaçada e bordas tracejadas para combinar com a estética de uma marca de "encomendas".
/* Enable customization for the select and its picker */
.brand-select,
.brand-select::picker(select) {
appearance: base-select;
}
/* Style the visible trigger button */
.brand-select {
font-family: 'Courier New', monospace;
background-color: #fffaf0;
color: #8b4513;
border: 2px dashed #8b4513;
border-radius: 4px;
padding: 0.75rem;
font-size: 1rem;
cursor: pointer;
}
/* Style the dropdown options list */
.brand-select::picker(select) {
font-family: 'Courier New', monospace;
background-color: #fffaf0;
border: 2px dashed #8b4513;
border-radius: 4px;
padding: 0.5rem;
}
/* Customize internal part colors to match text */
.brand-select::picker-icon {
color: #8b4513;
}
.brand-select option::checkmark {
color: #8b4513;
}
/* Style individual options and hover effects */
.brand-select option {
padding: 0.5rem;
border-radius: 4px;
color: #8b4513;
cursor: pointer;
}
.brand-select option:hover {
background-color: #fdf5e6;
}
<label for="preferences">Select shipping preference</label>
<select class="brand-select" id="preferences" name="preferences">
<button>
<selectedcontent></selectedcontent>
</button>
<option value="standard">Standard Shipping</option>
<option value="express" selected>Express Shipping</option>
<option value="overnight">Overnight Delivery</option>
</select>
Implementação estratégica e práticas recomendadas
- RECOMENDADO: use
appearance: base-selectquando seu sistema de design exigir consistência visual de alta fidelidade em todos os controles de formulário que não pode ser alcançada com substituições de seleção padrão entre navegadores. - NÃO use essa opção se você depende da experiência de seletor nativa do sistema operacional (por exemplo, o seletor de roda de rolagem padrão em dispositivos iOS). Ativar
base-selectdesativa os controles de interface nativos para dispositivos móveis em favor de menus de camada superior renderizados na Web. - VERIFIQUE se o contraste de cores atende aos padrões das WCAG. O seletor personalizável permite definir cores ad hoc, mas você é responsável por garantir que o texto permaneça legível em planos de fundo personalizados.
- Teste o comportamento do layout. Definir
appearance: base-selectremove o comportamento padrão do navegador de dimensionar a seleção com base na largura da opção mais longa. Talvez seja necessário definir uma largura fixa ou usar restrições de flex/grid para evitar mudanças de layout. - Verifique se o
<select>tem um atributonamee um<label>associado. Isso garante que, mesmo com uma interface personalizada, o componente permaneça acessível para leitores de tela e funcione corretamente com envios de formulários padrão. - Use atributos
valuepadrão nas opções para garantir que o envio do formulário funcione exatamente como antes.
Estratégias de fallback
Alternativas e suporte do navegador para <select> personalizável
Para navegadores que ainda não são compatíveis com appearance: base-select, o elemento <select> é degradado de forma otimizada para um menu suspenso padrão do sistema operacional.
- Conteúdo não textual ignorado: navegadores mais antigos removem tags HTML (como
<svg>ou<div>) dentro de tags<option>e renderizam apenas os nós de texto. Verifique se o conteúdo de texto do<option>é legível e significativo por si só. - Processamento da estrutura HTML: os analisadores padrão podem ignorar as tags
<button>e<selectedcontent>dentro de<select>ou tratá-las como inválidas. Não é necessário usar polyfills pesados de JavaScript para o aprimoramento progressivo se você considerar o texto padrão como um substituto legível.
document.addEventListener("DOMContentLoaded", () => {
// Check if browser supports base-select value
if (!CSS.supports("appearance", "base-select")) {
// Custom select overrides are not supported natively.
}
});