Não use IDs como seletores CSS

À primeira vista, pode parecer estranho não usar IDs como seletores em CSS, mas, através argumentos bem embasados, entenda porque isso é verdade.

Não use IDs como seletores CSS

Não use IDs como seletores em CSS: imagem ilustrativa

Quando estamos aprendendo a trabalhar com HTML e CSS, é comum aprendermos logo de cara as diferenças entre IDs e classes e quais vantagens tirar disso, como e quando usar um ou outro e assim por diante. Mas, após a realização de alguns testes de performance, pode ser que esse nosso aprendizado “de raiz” precise de uma pequena revisão.

Quando se é desenvolvedor web, fazer com que nossos códigos e/ou marcações, seja lá em que linguagem form, sejam cada vez melhores, é praticamente inerente ao ofício. E, com isso em mente, após fazer alguns testes com performance em folhas de estilo, algumas considerações interessantes podem ser encontradas, principalmente em relação a usar seletores de ID em CSS.

Mas existem alguns pontos que merecem ser levados em consideração:

  1. Performance
  2. Fragmentação
  3. Tradição

Performance

Pode perguntar para qualquer codificador CSS e ele vai responder que os seletores de ID são os mais rápidos. Mas isso vem com uma grande limitação: IDs são os seletores mais rápidos somente se eles forem os seletores-chave. O que é isso? Bem, nós lemos os seletores da esquerda para a direita, mas, caso não saiba, os navegadores leem da direita para a esquerda! Dê uma olhadinha nas explicações do SelectORacle que você vai ver.

Para um seletor #home a chega ser até normal supor que o browser vai localizar o elemento de ID “home” e aplicar os valores das propriedades em todos seus links. Super rápido, não é? Agora, veja o que realmente acontece: o browser pega todos os elementos a, então, verifica se são descendentes imediatos de #home e, caso não seja, vai checando os ascendentes até chegar em <html>.

Então, será, mesmo, que a diferença de performance é tão grande? Para ter certeza, foram feitos 3 testes usando o Criador de Testes CSS de Steve Souders, cada um deles utilizando 1000 elementos a que foram selecionados a partir de IDs individuais, classes ou IDs com os seletores a. Então, as páginas foram recarregadas diversas vezes para pegar a média dos resultados (números em ms).

Resultado do teste CSS (números em ms)

Então, para as 1000 regras testadas, os IDs se mostraram cerca de 1 milésimo de segundo mais rápido do que as classes como um seletor-chave, ou seja, a diferença de desempenho entre IDs e classes é irrelevante!

O cenário mais comum de se usar um ID como  “namespace” de um elemento (onde o elemento é o seletor-chave) é realmente mais lento do que usando uma classe, mas, novamente, somente com  13 milissegundos de diferença. Isso também é válido para os poucos bytes extras para adicionar uma classe num elemento que já tenha um ID, por exemplo, mudando <div id="search"> para <div id="search" class="search">.

Mas isso não quer dizer que todos os seletores são iguais. O seletor universal * e alguns seletores CSS3 têm desempenho relativamente fraco quando usado como seletor-chave.

Tabela com a performance dos seletores CSS

No entanto, não se torna um problema caso o uso seja para 1 a 2 seletores (elementos e/ou classes), usando seletores CSS3. O impacto na performance de seletores é pequeno se comparado a outras coisas como otimização de imagens ou redução de requisições HTTP. Esse tipo de coisa é o que realmente importa quando se tem a performance do site como fator preponderante.

Fragmentação

Além de serem “anzóis de estilo”, IDs são utilizados como identificadores de fragmentos específicos da página (um href que termina em #ancora leva ao elemento de ID “ancora”) e para uso de JavaScript. Se já existem IDs na página por outras razões, por que não reutilizá-los para estilizar? O problema é que isso torna o código fragmentado: há dependências entre CSS e JavaScript e/ou um identificador de fragmento. Usando classes, é possível decidir mudar para um (novo) esquema de nomeação a qualquer momento e tudo o que é preciso se preocupar é alterar alguns nomes no CSS e HTML.

Existem muito poucos casos em que estilos baseados em ID nunca serão reutilizados. Um exemplo é usar #search para a caixa de busca do site. Pode-se decidir mais tarde que uma nova caixa de busca será adicionada em outro local (abaixo dos resultados de busca, por exemplo). Mesmo #search sendo único nesse projeto, talvez você queira um pouco de CSS rápido para copiar e colar em um projeto futuro – que também pode ter uma caixa de pesquisa no rodapé da página. Mesmo para um grupo complexo de folhas de estilo, é possível dividir esses padrões em vários trechos reutilizáveis ​​de CSS. Usar classes ao invés de IDs impede que esses potenciais problemas venham à tona.

E, ao contrário de IDs, não há nenhuma restrição em usar várias classes, tanto em mais de uma vez na página, quanto várias classes em um mesmo elemento. Navegadores ainda estilizarão IDs, mesmo se, por engano, houver duplicação em um página. Mas se aventurar fora do HTML válido o torna propenso a problemas…

Tradição

Estilizar com IDs e classes são uma das primeiras coisas que aprendemos sobre CSS, por isso, pode ser um desafio ouvir “não use IDs em seletores CSS”. No entanto, o ramo do desenvolvimento web está sempre mudando. Ocasionalmente, precisamos reavaliar o que funciona e o que não funciona ao invés de apenas ficar com o que está nos servido bem, sem questionamentos.

No momento, estamos passando por um renascimento maciço com HTML5, CSS3, desempenho de JavaScript incrível e lançamentos de navegadores rápidos, por isso é um grande momento para esse repensar. No entanto, é importante examinar as razões de forma racional e decidir se as questões apresentadas são, realmente, válidas, ao invés de rejeitá-las de antemão.

Conclusão

Como pôde ser constatado no artigo, parece que não há razões convincentes para usar IDs em seletores CSS – a não ser para “namespaces”, uso de widgets e plugins específicos em CMSs e casos similares. Em CSS, classes podem fazer tudo o que IDs podem! Pense nisso na próxima vez em que iniciar um projeto e, ao invés de um IDs, tente trabalhar com classes, deixando os IDs para identificadores de fragmentos ou hooks para JavaScript.