O elemento <select> agora pode ser personalizado com CSS

Publicado em 24 de março de 2025

No Chrome 135, desenvolvedores e designers da Web podem finalmente se unir em um elemento <select> acessível, padronizado e estilizável com CSS na Web. Isso levou muitos anos, muitas horas de engenharia e trabalho de especificação colaborativa, e o resultado é um componente incrivelmente rico e poderoso que não falha em navegadores mais antigos.

Confira um vídeo de seleção personalizada usando esses novos recursos:

Com demonstrações de Una, Brecht e Adam.

Se você está acompanhando de perto, vai notar que alguns nomes e recursos de especificações mudaram desde a solicitação de feedback da comunidade da Una. Se você trabalhou com base nessa postagem e quer saber o que mudou, a Una também pode ajudar.

Também há uma nova documentação no MDN sobre seleção personalizável, cheia de detalhes.

Meet appearance: base-select

Uma nova propriedade CSS appearance: base-select que coloca o elemento <select> em um estado novo, configurável e estilizável, comumente chamado de estilos "base":

.custom-select {
  &, &::picker(select) {
    appearance: base-select;    
  }
}

O uso de base-select desbloqueia vários novos recursos e comportamentos:

O uso de base-select perde vários recursos e comportamentos:

  • O <select> não é renderizado fora do painel do navegador.
  • Ele não aciona componentes integrados do sistema operacional para dispositivos móveis.
  • O <select> deixa de usar a largura da <option> mais longa.

Um <select> agora pode incluir conteúdo HTML avançado

Antes de personalizar um <select>, se você colocasse coisas como uma imagem ou SVG no elemento <option>, o navegador as ignoraria.

Considere o seguinte HTML, que o navegador leria conforme você o criou:

<select class="custom-select">
  <option>
    <svg aria-hidden>…</svg>
    <span>HTML</span>
  </option>
  <option>
    <svg aria-hidden>…</svg>
    <span>CSS</span>
  </option>
  <option>
    <svg aria-hidden>…</svg>
    <span>JavaScript</span>
  </option>
  <option>
    <svg aria-hidden>…</svg>
    <span>WASM</span>
  </option>
</select>

No entanto, o DOM usado não inclui o <svg>:

<select class="custom-select">
  <option>
    <span>HTML</span>
  </option>
  <option>
    <span>CSS</span>
  </option>
  <option>
    <span>JavaScript</span>
  </option>
  <option>
    <span>WASM</span>
  </option>
</select>

Aqui estão (da esquerda para a direita) o Chrome, o Safari e o Firefox renderizando o HTML anterior. Se o navegador oferecer suporte a appearance: base-select, o SVG vai aparecer na opção. Caso contrário, ele não vai aparecer.

O Chrome, o Safari e o Firefox renderizando um seletor com SVG. O Chrome mostra as imagens, o Safari e o Firefox renderizam como se não houvesse imagens.
Teste neste Codepen.

Há o risco de quebrar sites existentes com seleção personalizável devido às mudanças no analisador. O Chrome tem os recursos por trás de um experimento do Finch caso seja necessário desativá-lo em uma emergência. Se tudo correr bem, o experimento será encerrado e o código será enviado permanentemente para a origem.

Totalmente personalizável

Todas as partes de um base-select podem ser trocadas, personalizadas e animadas. Confira uma demonstração que usa todos os novos recursos para criar experiências de seleção reconhecíveis e significativas.

Quatro apresentações diferentes de um elemento de seleção são mostradas. O primeiro tem um ponto indicador de status verde com o rótulo &quot;on&quot;. A próxima mostra avatares ao lado das opções. O terceiro é um seletor de espaço de cores com um rótulo personalizado integrado à seleção. A última opção permite escolher estados de rascunho ou publicados.
Teste neste Codepen.

Encontre muitos outros exemplos na seção de recursos no final desta postagem.

Interfaces JavaScript inalteradas

Não há riscos para suas interações atuais do JavaScript com um elemento <select>.

No entanto, se você começar a adicionar HTML rico aos elementos <option>, teste os valores selecionados, já que o navegador ainda analisa e ignora imagens e SVGs. A lógica mudou para determinar a string de conteúdo selecionada. Dependendo das opções disponíveis, talvez seja necessário fazer ajustes.

Se você estiver usando o atributo value em um <option>, não precisa se preocupar.

Recursos

O Chrome é o primeiro a implementar base-select, mas todos os navegadores participaram das especificações, e há mais elementos "base" a serem concluídos. Isso é só o começo.

Fique de olho, porque vamos continuar adicionando orientações, exemplos e recursos sobre a personalização de alguns elementos. Enquanto isso, confira os links abaixo para mais informações.

Agradecemos a todos que ajudaram a fazer isso acontecer!