O elemento <select> agora pode ser personalizado com CSS

Publicado em: 24 de março de 2025

A partir do Chrome 135, desenvolvedores e designers da Web podem finalmente se unir em um elemento <select> acessível, padronizado e com estilo CSS na Web. Foram muitos anos de trabalho, muitas horas de engenharia e colaboração para chegar a um componente incrivelmente rico e poderoso que não vai quebrar em navegadores mais antigos.

Confira um vídeo de seleções personalizadas usando esses novos recursos:

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

Se você acompanhou de perto, vai notar que alguns nomes de especificações e recursos mudaram desde o pedido de feedback da comunidade da Una. Felizmente, se você trabalhou com base nessa postagem e quer saber o que mudou, a Una também tem uma solução para você.

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

Conheça o appearance: base-select

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

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

Usar o base-select desbloqueia vários novos recursos e comportamentos:

Usar 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 móvel.
  • O <select> para de usar a largura do <option> mais longo.

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

Antes de ser possível personalizar um <select>, se você colocasse itens como uma imagem ou um SVG no elemento <option>, o navegador os ignoraria.

Considere o seguinte HTML. O navegador o leria da forma como 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 incluiria 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 for compatível com appearance: base-select, o SVG vai aparecer na opção. Caso contrário, não.

Chrome, Safari e Firefox renderizando uma seleção com SVG dentro. O Chrome mostra as imagens, enquanto o Safari e o Firefox renderizam como se não houvesse imagens.
Teste neste Codepen.

Há risco de quebrar sites atuais com a seleção personalizável devido às mudanças no analisador. O Chrome tem os recursos por trás de um experimento do Finch caso haja uma necessidade emergencial de desativá-lo. Se tudo correr bem, o experimento vai terminar e o código será enviado permanentemente para a fonte.

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;. O próximo 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 permite escolher estados de rascunho ou publicados.
Teste neste Codepen.

Encontre muito mais 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 avançado aos elementos <option>, teste os valores selecionados, já que o navegador ainda analisa e ignora imagens e SVG. No entanto, a lógica para determinar a string de conteúdo selecionado mudou. Dependendo do que você tem nas opções, 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 ainda há mais elementos "básicos" a serem concluídos. Isso é só o começo.

Vamos continuar adicionando orientações, exemplos e recursos sobre como personalizar elementos selecionados. Até lá, confira os links a seguir para mais informações.

Agradecemos a todos que participaram desse processo!