Artigo original: CSS Naming Conventions that Will Save You Hours of Debugging

Já ouvi muitos desenvolvedores dizerem que odeiam CSS. Na minha experiência, isso é resultado de não terem tempo de aprender o CSS.

O CSS não é a "linguagem" mais bonita do mundo, mas tem impulsionado com sucesso o estilo da web há mais de 20 anos. Nada mal, hein?

Contudo, à medida que você escreve mais CSS, você vê rapidamente uma grande desvantagem.

É muito difícil manter o CSS.

CSS mal-escrito rapidamente se transforma em um pesadelo.

Veja aqui algumas convenções de nomenclatura que salvarão você do estresse e incontáveis horas mais tarde.

0Nm4l3DA3bWTbPc6C4ViWDqewokYYootpoqb
Você já passou por isso, confesse

Usar 'strings' delimitadas por hífen

Se você já escreve muito em JavaScript, então certamente usa variáveis em camel case, pois uma prática comum.

var redBox = document.getElementById('...')

Ótimo, certo?

O problema é que esta forma de nomenclatura não é adequada para o CSS.

Não faça isso:

.redBox {  border: 1px solid red;}

Ao invés disso, use:

.red-box {   border: 1px solid red;}

Esta é uma convenção de nomenclatura padrão do CSS. É indiscutivelmente mais legível.

Ela também é consistente com os nomes das propriedades do CSS,

// Correto
.some-class {   font-weight: 10em}
// Incorreto
.some-class {   fontWeight: 10em}

A convenção de nomenclatura BEM

As equipes têm abordagens diferentes para escrever os seletores de CSS. Algumas equipes usam delimitadores com hífen, enquanto outros preferem usar a convenção de nomenclatura mais estruturada, chamada BEM.

Geralmente, existem 3 problemas que as convenções de nomenclatura do CSS tentam resolver:

  1. Saber o que um seletor faz, apenas olhando seu nome
  2. Ter uma ideia sobre onde um seletor pode ser usado, apenas olhando para ele
  3. Conhecer as relações entre os nomes das classes, apenas olhando para eles.

Você já viu nomes de classes escritos assim:

.nav--secondary {  ...}
.nav__header {  ...}

Essa é a convenção de nomenclatura BEM.

Explicando BEM para uma criança de 5 anos

BEM tenta dividir a interface geral do usuário em pequenos componentes reutilizáveis.

Considere a imagem abaixo:

pIFVbUmRtKN8x6DvLHEvJeUSM9Oda8ClkY5f
Esta é uma imagem premiada de um bonequinho de palito :)

Brincadeira. Não é  premiada, infelizmente. :(

O bonequinho de palito, aqui, representa um componente, como um bloco de design.

Você já deve ter adivinhado que o B em "BEM" significa "Bloco".

No mundo real, esse 'bloco' poderia representar um site de navegação, cabeçalho, rodapé, ou qualquer outro bloco de design.

Seguindo a prática explicada acima, um nome de classe ideal para este componente poderia ser stick-man.

O componente deveria ser estilizado assim:

.stick-man {   }

Usamos strings delimitadas aqui. Isso é bom!

ThMVqj-sv26pjpzLJU3MIF2TCdn-S4CjlEZk

E para elementos

O E em, "BEM" significa "Elementos".

Geralmente, blocos de design raramente vivem isolados.

Por exemplo, o stick-man tem uma head (cabeça), e dois arms e feet (braços e pés, respectivamente) maravilhosos.

bf2jyOzcZ8wgd95I3qR9IS3Cf6pRlQ2hHuGM

head, feet e arms são todos elementos dentro do componente. Eles podem ser visto como componentes filhos, ou seja, filhos do componente pai geral.

Usando a convenção de nomenclatura BEM, os nomes das classes de elementos derivados são colocados adicionando duas sublinhas, seguidas do nome do elemento.

Por exemplo:

.stick-man__head {
}
.stick-man__arms {
}
.stick-man__feet {
}

M para Modificadores

O M em "BEM" significa "Modificadores".

E se o boneco fosse modificado e pudéssemos ter um blue ou um red?

Q-aWWnpw1UuoXxp5NGHxsjP5689VQBT0oGdQ
Boneco de palitinho azul e boneco de palitinho vermelho

No mundo real, isso pode ser um botão red ou um botão blue. Estes são modificações dos componentes em questão.

Usando BEM, os nomes das classes modificadoras são obtidos adicionando dois hifens, seguidos do nome do elemento.

Por exemplo:

.stick-man--blue {
}
.stick-man--red {
}

O último exemplo mostrou o componente pai sendo modificado. Esse não é sempre o caso.

E se tivéssemos dois stick-man com diferentes tamanhos de cabeça?

ZK-riYJhmFfBVEof6xO8yGGR3O10g2dW7Xqn
Bonecos de palitinho com a cabeça pequena e a cabeça grande, respectivamente

Desta vez, o elemento foi modificado. Lembre-se de que o elemento é um componente filho dentro do bloco que o contém.

.stick-man representa o bloco, enquanto .stick-man__head representa o elemento.

Como visto no exemplo acima, o hífen duplo também pode ser usado assim:

.stick-man__head--small {
}
.stick-man__head--big {
}

Novamente , observe o uso do hífen duplo no exemplo acima. Ele é usado para denotar um modificador.

Agora você entendeu.

Basicamente, é assim que a convenção de nomenclatura BEM trabalha.

Pessoalmente, eu costumo usar apenas nomes de classes com delimitadores de hífen para projetos simples e uso a BEM para interfaces mais envolvidas.

Você pode ler mais sobre a BEM.

BEM - Modificador de elemento em bloco

BEM - O modificador de elemento de bloco é uma metodologia que ajuda você a obter componentes reutilizáveis e compartilhamento de código no (Fonte: getbem.com, em inglês)

Por que usar convenções de nomenclatura?

Existem só dois problemas difíceis na ciência da computação: invalidação de cache e nomeação de objetos — Phil Karlton.

Nomear objetos é difícil. Tentamos tornar as coisas mais fáceis, economizando tempo no futuro com códigos mais sustentáveis.

Nomear corretamente em CSS torna seu código fácil de ler e sustentável.

Se você optar por usar a convenção de nomenclatura BEM, será mais fácil de ver o relação entre seus componentes/blocos de design apenas olhando para a marcação.

Está se sentindo confiante?

Nome CSS com 'hooks' do JavaScript

Hoje é o primeiro dia de trabalho do John.

Ele recebe um código em HTML com essa aparência:

<div class="siteNavigation">
</div>

John está lendo este artigo e percebe que esta pode não ser a melhor maneira de nomear as coisas em  CSS. Então, ele vai em frente e refatora a base de código assim:

<div class="site-navigation">
</div>

Parece bom, não?

Mal sabe John que ele quebrou a base de código!

Como?

Em algum lugar no código JavaScript, havia uma relação com o nome da classe anterior, siteNavigation:

//Código em JavaScript
const nav = document.querySelector('.siteNavigation')

Então, com a mudança no nome da classe, a variável nav ficou null.

Que triste.

Para evitar casos como estes, os desenvolvedores criaram estratégias diferentes.

1. Usar nome de classes 'js-'

Uma maneira de reduzir esses bugs é usar um nome de classe js-* para denotar um relacionamento com o elemento do DOM em questão

Por exemplo:

<div class="site-navigation js-site-navigation">
</div>

E, no código, JavaScript:

//Código em JavaScript
const nav = document.querySelector('.js-site-navigation')

Por convenção, qualquer pessoa que veja o nome da classe js-site-navigation entenderá que existe um relacionamento com esse elemento do DOM no código em JavaScript.

2. Usar o atributo 'Rel'

Eu não uso essa técnica, mas já vi outras pessoas usando.

Você reconhece isso?

<link rel="stylesheet" type="text/css" href="main.css">

Basicamente, o atributo define o relacionamento que o recurso vinculado tem com o documento onde é referenciado.  

No exemplo anterior com John, os defensores dessa técnica fariam isso:

<div class="site-navigation" rel="js-site-navigation">
</div>

No JavaScript:

const nav = document.querySelector("[rel='js-site-navigation']")

Eu tenho minha dúvidas sobre esta técnica, mas é provável que você a encontre em algumas bases de códigos.  A defesa aqui é: bem, há uma relação com o JavaScript, então eu uso o atributo 'Rel' para denotar isso.

A web é um lugar imenso, com diferentes “métodos”  para solucionar o mesmo problema.

3. Não usar atributos de dados

Alguns desenvolvedores usam atributos de dados como uma conexão com o JavaScript. Isso não está correto. Por definição, os atributos de dados são usados para armazenar dados personalizados.

08r5ESO6cpzZvcZz-KczJEGXtPBtCLorryI6
Uso correto de atributos de dados, como vemos no Twitter

Edição nº 1: conforme mencionado por algumas pessoas incríveis na seção de comentários original deste texto, se as pessoas usarem o atributo 'Rel', talvez não haja problema em usar atributos de dados em certos casos. No final, a decisão é sua.

Dica de bônus: escrever mais comentários no CSS

Isso não tem a ver com convenções de nomenclatura, mas também poupará algum tempo.

Embora muitos desenvolvedores da Web tentem NÃO escrever comentários em JavaScript ou se ater a alguns, penso que você deveria escrever mais comentários em CSS..

Como CSS não é a “linguagem” mais elegante, comentários bem estruturados podem economizar tempo quando você está tentando entender seu código.

Não dói.

Veja como o código-fonte do Bootstrap é bem-comentado.

Você não precisa escrever comentários para dizer que color: red dará uma cor vermelha. No entanto, se estiver usando um truque de CSS menos óbvio, sinta-se à vontade para escrever um comentário.

Pronto para se tornar profissional?

O autor criou um guia grátis de CSS para que suas habilidades de CSS se destaquem imediatamente. Obtenha o e-book gratuito aqui (em inglês).

4AqtYrYGSx6s9Mwmzji1vj8RqwvarVns4y7V
Tradução do título: "Sete segredos sobre o CSS que você não conhecia"