Pular para o conteúdo
~/.primo-academy.sh
☰ Aulas · CSS · 0/36
Recomendado: essencial

Arquitetura CSS: BEM e Organização de Estilos

3 min de leitura

fonte

Quando o CSS tem 200 linhas, qualquer organização serve. Quando tem 5.000, uma linha solta pode quebrar um botão em 20 lugares. Arquitetura CSS é o conjunto de convenções que mantém o código manutenível à medida que cresce.

O problema que BEM resolve

<div class="card">
  <h3 class="card-title">Título</h3>
  <p class="card-text">Texto</p>
  <button class="card-button">OK</button>
</div>

CSS correspondente:

.card { ... }
.card .card-title { ... }   /* o seletor fica específico demais */
.card .card-text { ... }
.card .card-button { ... }

Funciona. Mas:

  • Specificidade alta (dois níveis) - difícil de sobrescrever.
  • "card" vira prefixo em tudo - verboso.
  • E se for um card de "usuário" e um card de "produto"? Conflitos de nome.

BEM resolve com uma convenção de nomenclatura rigorosa: Block, Element, Modifier.

BEM: a convenção

<div class="card card--destaque">
  <h3 class="card__titulo">Título</h3>
  <p class="card__texto">Texto</p>
  <button class="card__botao card__botao--ativo">OK</button>
</div>
  • Block (bloco): o componente independente. card.
  • Element (elemento): uma parte do bloco, sem sentido fora dele. card__titulo, card__texto, card__botao (note os dois underscores __).
  • Modifier (modificador): uma variação do bloco ou elemento. card--destaque, card__botao--ativo (note os dois traços --).

CSS correspondente:

.card { /* bloco */ }
.card--destaque { /* variação do bloco: card destacado */ }

.card__titulo { /* elemento do bloco */ }
.card__texto  { /* elemento do bloco */ }

.card__botao { /* elemento */ }
.card__botao--ativo { /* variação: botão ativo */ }

Vantagens:

  • Specificidade controlada (sempre uma classe).
  • Auto-documentado: o nome diz o que é.
  • Sem conflito entre blocos diferentes (não tem .titulo solto
    • tem .card__titulo ou .post__titulo).
  • Reutilizável: o bloco pode ser movido pra qualquer lugar sem quebrar.

BEM tem críticas (justas)

  • Classes longas: .navbar__menu-item--ativo é verboso.
  • Não resolve tudo: variantes complexas ainda exigem CSS custom.
  • Acoplamento ao HTML: a classe .card__titulo é inútil fora do .card.

A maioria dos projetos grandes usa BEM, ITCSS, SMACSS, Atomic CSS ou alguma mistura. BEM é o mais comum e didático. Vale conhecer o nome e a ideia, mesmo se você não usar exatamente assim.

Outras convenções comuns

utilities-first (estilo Tailwind):

<button class="bg-blue-500 text-white px-4 py-2 rounded">
  OK
</button>

Classes de utilidade que fazem uma coisa só (bg-blue-500 aplica o fundo azul, text-white aplica texto branco). HTML fica verboso mas o CSS de produção fica minúsculo. Veremos mais no próximo nó - a ideia é não ensinar a usar, mas deixar claro que existe.

CSS-in-JS (estilo styled-components, Emotion):

const Botao = styled.button`
  background: #1a73e8;
  color: white;
  padding: 8px 16px;
`;

CSS escrito dentro de JavaScript, escopado automaticamente por componente. Comum em React. Tem trade-offs (runtime, performance, DX). Vale conhecer para não estranhar quando aparecer.

CSS Modules:

/* Botao.module.css */
.botao { background: blue; }
import styles from "./Botao.module.css";
<button className={styles.botao}>OK</button>

Cada arquivo vira um módulo com nomes "escopados" (Botao_botao__a3f2 em vez de só .botao). Sem colisão de nomes. Padrão em projetos React modernos.

Organização de arquivos

Não existe regra única, mas um padrão comum é o 7-1 (7 pastas, 1 arquivo de entrada):

styles/
├── abstracts/      # variáveis, mixins, funções
│   ├── _variables.css
│   └── _mixins.css
├── base/           # reset, tipografia, elementos HTML crus
│   ├── _reset.css
│   └── _typography.css
├── components/     # blocos BEM ou componentes
│   ├── _button.css
│   ├── _card.css
│   └── _navbar.css
├── layout/         # header, footer, grid, sidebar
├── pages/          # estilos específicos de uma página
├── themes/         # variações de tema
├── vendors/        # CSS de bibliotecas externas
└── main.css        # importa tudo

A ideia é que o arquivo main.css importa os outros com @import (em tempo de build, não em runtime), e o resultado final é um único arquivo CSS minificado entregue ao usuário.

Reset / Normalize: zerando o default

Cada navegador tem um CSS default diferente. Para ter previsibilidade, comece com um reset:

/* Reset moderno, opinião pessoal */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; padding: 0; }
body { line-height: 1.5; -webkit-font-smoothing: antialiased; }
img, picture, video, canvas, svg { display: block; max-width: 100%; }
input, button, textarea, select { font: inherit; color: inherit; }
p, h1, h2, h3, h4, h5, h6 { overflow-wrap: break-word; }

box-sizing: border-box no universal selector (visto no nível iniciante) é o item mais importante. O resto é gosto pessoal.

Ordem de declaração de propriedades

Convenção muito usada (e que ajuda na leitura):

.card {
  /* Posicionamento */
  position: relative;
  top: 0;

  /* Display & box model */
  display: block;
  width: 100%;
  padding: 16px;
  margin: 0;

  /* Cores */
  background: white;
  color: #333;
  border: 1px solid #ccc;

  /* Texto */
  font-size: 16px;
  line-height: 1.5;

  /* Outros */
  cursor: pointer;
  transition: background 0.2s;
}

A ordem não muda a cascata, mas padronizar facilita achar coisas e revisar PRs.

  • BEM é a convenção de nomenclatura mais usada (Block__Element--Modifier).
  • Specificidade controlada = CSS mais fácil de manter.
  • Reset no início: box-sizing: border-box + alguns ajustes essenciais.
  • Organização por pastas: components, layout, base, abstracts.
  • Um único arquivo final entregue ao usuário (build concatena tudo).

Dica: a melhor arquitetura é a que o time entende e segue. BEM é o padrão didático, mas se o time usa outro padrão com consistência, isso é melhor do que BEM aplicado pela metade. Consistência > dogma.

No próximo nó, vamos ver performance - o que o CSS faz (e deixa de fazer) que torna a página rápida ou lenta.

// recursos

// avaliação da trilha

ainda sem avaliações