← Blog · · Equipe ConvertCaseHQ · 7 min de leitura

Nomes de classes CSS: kebab-case, BEM e além

A maioria dos nomes de classes CSS é escrita em kebab-case minúsculo (.site-header, .price-tag) porque é assim que o próprio CSS nomeia as coisas dele: background-color, font-size, flex-direction. O BEM parte daí e acrescenta uma estrutura fixa, block__element--modifier, de modo que uma classe como card__title--large diz a qual componente ela pertence, que parte dele ela é e qual variante está mostrando.

A seguir: o que no CSS diferencia maiúsculas de minúsculas e o que não diferencia, por que o kebab-case virou o padrão, o que as regras de nomenclatura do BEM dizem de fato e quando outra abordagem torna o BEM desnecessário.

O que diferencia maiúsculas de minúsculas no CSS, e o que não diferencia

A sintaxe do próprio CSS não diferencia maiúsculas de minúsculas dentro da faixa ASCII, então COLOR: RED funciona exatamente como color: red. Três coisas funcionam de outro jeito:

  • Nomes de classes diferenciam maiúsculas de minúsculas. .Card não corresponde a class="card". A única exceção é uma página em quirks mode, em que os navegadores comparam nomes de classes sem diferenciar maiúsculas, o que é mais um motivo para começar toda página com <!DOCTYPE html>.
  • Propriedades personalizadas diferenciam maiúsculas de minúsculas. --brand-color e --Brand-Color são duas variáveis diferentes.
  • Nomes de elementos e atributos HTML não diferenciam. Num documento HTML, DIV e div selecionam os mesmos elementos. Em XML, seriam diferentes.

O jeito mais simples de nunca mais pensar nisso é manter todos os nomes de classes e todas as propriedades personalizadas em minúsculas. Para saber como outras linguagens e sistemas de arquivos lidam com maiúsculas e minúsculas, veja nossa comparação sobre diferenciação de maiúsculas e minúsculas.

Por que o kebab-case venceu nos nomes de classes CSS

Nada no CSS obriga o uso de kebab-case em nomes de classes. .cardTitle e .card_title são ambos válidos. Os hífens fazem sentido porque tudo ao redor de um nome de classe já os usa: nomes de propriedades, valores como space-between e atributos HTML como aria-label e data-user-id. Uma classe em camelCase no meio de uma folha de estilo cheia de hífens parece erro de digitação.

É no JavaScript que o kebab-case fica desajeitado, porque hífens não são permitidos em identificadores. O navegador resolve os casos dele: data-user-id é lido como element.dataset.userId, e background-color vira element.style.backgroundColor. Nomes de classes costumam continuar como strings (classList.add("is-open")), então para eles tanto faz.

A exceção são os CSS Modules. Um CSS Module exporta os seus nomes de classes para o JavaScript como um objeto, então .card-title precisa ser escrito styles["card-title"], enquanto .cardTitle vira o mais limpo styles.cardTitle. Essa é a única configuração em que trocaríamos os nomes de classes para camelCase.

Nomenclatura BEM: bloco, elemento, modificador

O BEM (Block, Element, Modifier, ou bloco, elemento, modificador) nasceu na Yandex. A página de história da metodologia remonta o trabalho a 2005, marca o lançamento do framework Lego 2.0 da Yandex, em março de 2009, como o início do BEM e situa a abertura do código em 2010. As regras de nomenclatura são curtas:

  • Bloco: um componente independente, que faz sentido sozinho, como .card, .search-form ou .menu.
  • Elemento: uma parte de um bloco sem significado fora dele, nomeada com o bloco, dois sublinhados e o elemento: .card__title, .menu__item.
  • Modificador: um sinalizador que muda a aparência, o comportamento ou o estado, nomeado com o bloco ou o elemento, dois hífens e o modificador: .card--featured, .card__button--disabled. Um modificador também pode ser um par de chave e valor: .form--theme-xmas.

As palavras dentro de cada parte são separadas por um único hífen, como em .search-form__submit-button. Aqui está um componente completo:

<article class="card card--featured">
  <h2 class="card__title">Spring sale</h2>
  <p class="card__body">Everything 20% off this week.</p>
  <a class="card__button card__button--disabled" href="/sale">Shop now</a>
</article>
.card { border: 1px solid #ddd; padding: 1rem; }
.card--featured { border-color: gold; }
.card__title { font-size: 1.25rem; }
.card__button--disabled { opacity: 0.5; pointer-events: none; }

BEM clássico vs. o estilo de dois hífens

Se você ler o site oficial da metodologia, o bem.info, vai ver que os modificadores são diferentes. O esquema clássico de lá separa os modificadores com um único sublinhado: menu_hidden, menu__item_visible, menu__item_type_radio. A versão com -- aparece ali como alternativa, o "Two Dashes style", e é a que o getbem.com documenta. As duas são BEM legítimo; só não misture as duas na mesma base de código. O bem.info também aponta um pequeno porém dos hífens: um hífen duplo dentro de um comentário HTML pode não passar na validação.

Regras do BEM em que é fácil errar

  1. Nada de elementos de elementos. Um título dentro do cabeçalho de um card continua sendo card__title, e não card__header__title. Você pode aninhar elementos no HTML o quanto quiser; os nomes continuam planos. O raciocínio do bem.info: com nomes encadeados, não dá para mover, adicionar ou remover um elemento sem alterar código existente.
  2. Modificadores nunca aparecem sozinhos. Escreva class="button button--primary", e não class="button--primary". O modificador só acrescenta algo à classe base.
  3. Use seletores de uma única classe. .card__title, e não .card .card__title nem h2.card__title. A exceção aceita é um modificador de bloco que muda os seus elementos: .card--featured .card__title.
  4. Dê nome aos modificadores pela finalidade. Esta é uma opinião nossa, não uma regra do BEM: --featured ou --error sobrevivem a um redesign, enquanto --yellow vira mentira no dia em que a cor da marca mudar.
  5. Mantenha os ganchos de JavaScript fora das classes de estilo. Também é opinião nossa: selecione os elementos nos scripts com um atributo data, como data-action="close", em vez de .card__button, para que renomear uma classe por motivos de estilo não quebre o comportamento.

Renomear um bloco depois é, quase sempre, uma questão de localizar e substituir. Cole um template na nossa ferramenta Localizar e substituir, ative o modo regex e substitua card(__|--) por product-card$1: todas as classes de elemento e de modificador passam para o novo nome do bloco, e a contagem de correspondências mostra quantas mudaram. Renomeie a classe card sozinha separadamente, para não pegar palavras sem relação.

Escrevendo BEM com Sass e com o aninhamento nativo do CSS

O seletor pai do Sass pode acrescentar um sufixo ao seletor externo, e a documentação do Sass usa justamente o BEM como exemplo. O aninhamento nativo do CSS não faz isso, e a MDN chama a atenção para esse ponto de forma explícita: um &__title aninhado é lido como seletor de tipo, então não produz .card__title.

// Sass: works
.card {
  &__title { font-size: 1.25rem; }    // compiles to .card__title
  &--featured { border-color: gold; } // compiles to .card--featured
}
/* Native CSS nesting: write the full class names */
.card {
  border: 1px solid #ddd;
  &.card--featured { border-color: gold; } /* .card.card--featured */
}
.card__title { font-size: 1.25rem; }

Além do BEM: quando você não precisa dele

O BEM existe para impedir que nomes de classes colidam e para deixar a estrutura visível numa folha de estilo global. Se outra coisa resolve o problema das colisões, os nomes longos dele rendem menos:

  • CSS Modules restringem o escopo dos nomes de classes ao próprio arquivo por padrão, então um simples .title num componente não colide com o .title de outro.
  • CSS utility-first, como o Tailwind, substitui em grande parte os nomes de classes personalizados por utilitários predefinidos como font-bold, então a nomenclatura passa para os seus componentes.
  • Sites pequenos, com poucos componentes, muitas vezes se viram bem com kebab-case simples e um prefixo por componente.

Mesmo assim, o kebab-case continua sendo o padrão seguro para qualquer nome de classe que você escrever.

Regras práticas

  • kebab-case minúsculo para nomes de classes e propriedades personalizadas, sempre.
  • BEM quando muitas pessoas compartilham uma única folha de estilo global: block__element--modifier, nomes de elementos planos, modificadores ao lado da classe base.
  • Nomes de classes em camelCase só quando uma ferramenta como os CSS Modules os expõe ao JavaScript.

Vai transformar o nome de um componente numa classe? Digite "Product Card" no nosso conversor de maiúsculas e minúsculas e o botão kebab-case devolve product-card. Para as convenções de todas as outras camadas de um projeto, das variáveis de ambiente às URLs, veja nosso guia rápido de estilos de nomenclatura para desenvolvedores.

© 2026 ConvertCaseHQ. Todos os direitos reservados.