Naming

O nome de um id (identificador) ou de uma class (classe) diz qual papel o elemento cumpre na tela: order-summary, alert--error, product-card. Um nome escolhido pela aparência tem prazo de validade curto. blue-card descreve o card enquanto ele for azul; no redesenho que o deixa verde, alguém precisa trocar a classe em todos os arquivos, ou conviver com uma classe chamada blue-card num card verde.

Duas coisas diferentes leem a marcação, e cada uma tem o seu atributo. O CSS lê a classe para colorir o elemento. O JavaScript lê o data attribute (atributo de dados), o data-*, para saber o que fazer quando alguém clica.

Manter essa divisão evita um acidente comum. Se o JavaScript procura o botão pela classe .open-modal, quem renomear essa classe numa faxina de CSS desliga o clique, e nada acusa o erro: a página continua carregando, o botão continua na tela e o modal deixa de abrir.

Conceitos fundamentais

ConceitoO que é
id (identificador)Aparece uma vez só na página. Serve de alvo para link, para <label for> e para o JavaScript
class (classe)Reutilizável em vários elementos. O nome descreve o papel que o elemento cumpre
data attribute (atributo de dados)data-*, lido pelo JavaScript através de dataset. É o canal de comportamento
kebab-case (palavras separadas por hífen)Forma dos nomes em HTML e CSS: product-card
BEM (Block Element Modifier · Bloco-Elemento-Modificador)Convenção block__element--modifier, que amarra a classe ao papel dela dentro do componente
semantic class (classe semântica)O nome vem do papel, como alert--danger. Continua valendo depois de um redesenho
presentational class (classe de aparência)O nome vem do visual, como red-text. Deixa de descrever o elemento assim que a cor muda

Um id aparece uma vez, uma classe se repete

O id é o endereço de um elemento dentro da página. Um link com #checkout-summary salta para ele, um <label for> se conecta ao campo por ele, e o JavaScript o encontra por ele. Repetir o mesmo id em dois elementos cria dois destinos para um endereço só, e o navegador entrega sempre o primeiro que achar.

A classe existe para se repetir, e é ela que carrega o nome do papel: order-summary, alert--error. Escreva em kebab-case, seguindo o mesmo BEM que o CSS usa.

Evite escolher o id como seletor de CSS. Ele tem prioridade alta demais na cascata, e sobrescrever essa regra depois custa caro.

❌ Ruim: o mesmo id em dois elementos, e a classe descreve a cor
<div id="box" class="blue-card big-text">
  <span class="red">Error</span>
</div>
<div id="box" class="blue-card small-text">
  <span class="red">Warning</span>
</div>
✅ Bom: cada id aparece uma vez, e a classe diz o papel do elemento
<div id="checkout-summary" class="order-summary">
  <span class="alert alert--error">Error</span>
</div>

<div id="cart-sidebar" class="order-summary order-summary--compact">
  <span class="alert alert--warning">Warning</span>
</div>

data-* guarda o dado que o JavaScript vai ler

Um data-* carrega estado e configuração, e o nome dele descreve o dado guardado: data-modal-target, data-user-id, data-status. O JavaScript chega até ele por dataset ou por um seletor de atributo, como [data-modal-target].

Com o gancho do JavaScript num data-*, a classe fica livre para ser renomeada, dividida ou apagada durante um redesenho, e o comportamento do botão continua de pé.

❌ Ruim: o JavaScript procura pela classe de estilo, e nenhum data-* existe
<button class="btn btn-primary open-modal">Open</button>

<div class="modal-container" data-id="1">...</div>
document.querySelectorAll('.open-modal').forEach((btn) => { ... });
✅ Bom: o JavaScript procura pelo data-*, e a classe fica só com o estilo
<button class="button button--primary" data-modal-target="product-details">Open</button>

<div class="modal" data-modal-id="product-details">...</div>
document.querySelectorAll('[data-modal-target]').forEach((btn) => { ... });

Como nomear um data-*

Escreva em kebab-case e diga o que o valor guarda: data-user-id, data-status, data-page.

Duas coisas engordam o nome sem informar nada. Repetir o elemento pai (data-row-data-id dentro de um <tr>) só devolve a informação que a marcação já dá. E abreviar até virar data-x deixa o leitor procurando no JavaScript o que o valor significa.

❌ Ruim: o nome repete o elemento pai, e data-x não diz nada
<tr data-row-data-id="42" data-row-data-status="active" data-x="1">
✅ Bom: cada nome diz o que guarda, em kebab-case
<tr data-user-id="42" data-status="active" data-page="1">

Referência rápida

UsoConvençãoExemplo
IDkebab-caseid="checkout-summary"
ClasseBEM kebab-caseclass="card card--featured"
data-*kebab-casedata-modal-target="dialog-1"
aria-labelTexto naturalaria-label="Close dialog"

DoDocs v3.7.0 · Desenvolvido por @thiagocajadev · Baseado no trabalho de pmndrs/docs · Poimandres.