Convenções de
nomenclatura CSS
Eu já ouvi muitos desenvolvedores dizerem que
eles odeiam CSS. Em minha experiência, isso vem
como um resultado de não ter tempo para
aprender CSS.
CSS não é a “linguagem” mais bonita, mais tem
alimentado com sucesso o estilo na web por mais
de 20 anos. Não está indo muito mal, né?
Entretanto, enquanto você escreve mais CSS, você
rapidamente vê uma grande desvantagem.
É difícil de arrumar e manter o CSS.
CSS mal escrito rapidamente vai virar um
pesadelo.
Aqui estão algumas convenções de nomenclatura
que vão poupar um pouco de estresse e inúmeras
horas a menos de linha.
Use sequências delimitadas por
hífen
Se você escreve muito javascript, então escrever
variável em camelcase é uma prática comum
var redBox = document.getElementById('...')
Ótimo, certo?
O problema é que esse formato de nomenclatura
não é bem adequado para o CSS.
Não faça isso:
.redBox {
border: 1px solid red;
Em vez disso, faça isso:
.red-box {
border: 1px solid red;
Isso é um padrão bonito de convenções de
nomenclatura CSS. Isto é indiscutivelmente mais
agradável.
Também, é consistente com os nomes das
propriedades CSS.
// Correto
.some-class {
font-weight: 10em
}
// Errado
.some-class {
fontWeight: 10em
A convenção de nomenclatura
BEM
As equipes têm diferentes maneiras de escrever
seletores CSS. Alguns times usam hífen como
delimitadores, enquanto outros preferem usar
convenções de nomenclatura mais estruturadas
chamada BEM.
Geralmente, existem 3 problemas que a
convenção de nomenclatura CSS tentam resolver.
1 — Sabendo o que um seletor faz, simplesmente
olhando o nome dele.
2 — Ter uma ideia de onde um seletor pode ser
usado, simplesmente olhando ele.
3 — Conhecer as relações entre nomes de classe,
simplesmente olhando para eles.
Você já viu nomes de classes escritos assim:
.nav--secondary {
...
.nav__header {
...
Isso é a convenção de nomenclatura do BEM
Explicando BEM a uma criança de
5 anos
BEM tenta dividir a interface geral do usuário em
pequenos componentes reutilizáveis.
Considere a imagem abaixo:
É uma imagem premiada de um homem :)
Não, não é premiado :(
O desenho representa um componente, tal como
um bloco de design.
Você já deve ter adivinhado que o B do BEM
significa ‘Bloco’.
No mundo real, esse ‘Bloco’ poderia representar
uma navegação no site, cabeçalho, rodapé, ou
qualquer outro bloco de design.
Seguindo a prática explicada acima, um nome de
classe ideal para esse componente seria stick-
man.
O componente deve ser estilizado assim:
.stick-man {
Nós usamos strings delimitado aqui. Boa!
E para os elementos
O E no ‘BEM’ significa elementos.
Em geral os blocos de design raramente vivem
isolados.
Por exemplo, o desenho tem uma cabeça, dois
lindos braços, e pés.
A cabeça, pés, e braços, são todos os elementos
dentro do componente.
Eles pode ser visto como filhos do componentes.
isto é, filhos do componente pai.
Usando a convenções de nomenclatura do BEM,
nomes de classe de elementos são derivados e
adicionados dois underscores, seguidos pelo
nome do elemento.
Por exemplo:
.stick-man__head {
.stick-man__arms {
.stick-man__feet {
M para modificadores
O M no ‘BEM’ significa modificadores.
E se o desenho pudesse ser modificado e
pudéssemos ter um stick man azul ou um
vermelho.
No mundo real, isso poderia ser um botão
vermelho, ou um botão azul.
Essas são as modificações do componente em
questão.
Usando BEM, os nomes de classes modificadoras
são derivados e adicionados hífens seguidos pelo
nome do elemento.
Por exemplo:
.stick-man--blue {
.stick-man--red {
O último exemplo mostrou o componente pai
sendo modificado. Isto nem sempre é o caso.
E se tivéssemos um desenho diferente com uma
cabeça maior?
Dessa vez o elemento foi modificado,
relembrando, o elemento é um componente filho
dentro de um bloco geral.
O .stick-man representa o Bloco, .stick-
man__head o elemento.
Como Visto no exemplo acima, hífens duplo
também podem ser usados assim:
.stick-man__head--small {
}
.stick-man__head--big {
Novamente, note que usamos hífens duplo no
exemplo acima. Isto é usado para marcar um
modificador.
Agora você conseguiu.
Isso é basicamente como convenção de
nomenclatura no BEM funciona.
Pessoalmente, eu tenho utilizado um hífen
delimitando nomes de classe para projetos
simples e BEM para interfaces de usuários mais
envolvidas.
Você pode ler mais sobre BEM.
Por que usar convenções de
nomenclatura?
Existem apenas dois problemas difíceis em Ciência
da Computação: invalidação de cache e nomeação de
coisas — Phil Karlton
É difícil nomear as coisas. Estamos tentando
tornar as coisas fáceis e poupar horas no futuro
com um código mais sustentável.
Nomear corretamente as coisas no CSS fará seu
código mais fácil de ler e manter.
Se você escolher utilizar a convenção de
nomenclatura BEM, isto tornará fácil ver o
relacionamento entre seu componente/bloco de
design apenas olhando a marcação.
Sentindo-se confiante?
Nomes CSS com ganchos
Javascripts
Hoje é o primeiro dia de trabalho do Jhon.
Ele entregou um código HTML que se parece com
isso:
<div class="siteNavigation">
</div>
John leu o artigo e percebeu que isso não é a
melhor maneira de nomear as coisas em CSS.
Então ele vai em frente e refaz o código da
seguinte forma:
<div class="site-navigation">
</div>
Parece bom, né?
Sem saber, John quebra o código.
Como?
Em algum lugar no código Javascript, havia um
relacionamento anterior com o nome da classe
siteNavigation:
//O código Javascript
const nav =
document.querySelector('.siteNavigation')
Então, com a mudança do nome da classe, a
variável nav torna-se null.
Que triste.
Para prevenir casos como esse, desenvolvedores
criaram diferentes estratégias.
1. Use js- class names
Use js- para nomear classe
Uma maneira de suavizar esses bugs é usar um js-
* para nomear classe que representa um
relacionamento com o elemento DOM em
questão.
Por exemplo:
<div class="site-navigation js-site-navigation">
</div>
E no código javaScript:
//O código Javasript
const nav = document.querySelector('.js-site-
navigation')
Como uma convenção, qualquer um que veja o
nome da classe js-site-navigation entenderia que
ele é relacionado ao elemento DOM no código
javaScript.
2. Use o atributo Rel.
Eu não uso essa técnica, mas já vi pessoas usando.
Você reconhece isso?
<link rel="stylesheet" type="text/css"
href="main.css">
Basicamente, o atributo rel define o
relacionamento que o recurso vinculado tem com
o documento do qual é referenciado.
No exemplo anterior com John, o atributo dessa
técnica faria assim:
<div class="site-navigation" rel="js-site-
navigation">
</div>
E no JavaScript:
const nav = document.querySelector("[rel='js-
site-navigation']")
Eu tenho minhas dúvidas sobre essa técnica, mas
é provável que a tenha no seu código. A alegação
aqui é “bem, há uma relacao com o Javascript,
então eu uso o atributo rel para denotar isso”.
A web é um grande lugar com um monte de
métodos diferentes para solucionar o mesmo
problema.
3. Não use atributos de dados
Alguns desenvolvedores usam atributos de dados
como ganchos no javascript. Isto não está certo.
Por definição, os atributos de dados são usados
para armazenar dados customizados.
Edição #1: Como mencionado por algumas
pessoas incríveis na sessão de comentários, se as
pessoas usa o atributo ‘rel’, talvez seja aceitável
usar atributos de dados em certos casos. É sua
chamada depois de tudo.
Dica de bónus: Escreva mais
comentários CSS
Isso não tem nada a ver com convenções de
nomenclatura, mas também economiza algum
tempo.
Enquanto muitos desenvolvedores web tentam
não escrever comentários no JavaScript ou ficar
com alguns, eu acho que você deveria escrever
mais comentários CSS.
Como o CSS não é a “linguagem” mais elegante, os
comentários bem estruturados podem economizar
tempo quando você está tentando entender seu
código.
Não faz mal.
Olhe como o código-fonte do Bootstrap foi bem
comentado.
Você não precisa escrever comentários para dizer
cor: vermelha dará uma cor vermelha.
Créditos
CSS Naming Conventions that Will Save You
Hours of Debugging, escrito originalmente por
Ohans Emmanuel