Microframework CSS
Framework leve baseado em BEM com suporte a temas dia · tarde · noite. Mais rápido que o limite mágico de 14KB.
Introdução
O Microframework CSS é um framework ultraleve baseado na metodologia BEM. Ele entrega componentes profissionais, sistema de temas em CSS puro, grid responsivo e integração com VS Code — tudo em menos de 14KB, abaixo do número mágico da janela de congestionamento inicial do TCP.
Abaixo dos 14KB críticos
Dia · Tarde · Noite
Prontos para produção
Quick Start
Três passos para sair do zero ao primeiro componente.
1. Adicione o CSS
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="microframework.css">
</head>
<body>
<div class="bem-card">
<div class="bem-card__body">
<h3 class="bem-card__title">Olá mundo!</h3>
</div>
</div>
</body>
</html>
2. Adicione o toggle de tema (opcional)
<!-- HTML: botões de tema -->
<div class="bem-theme-toggle">
<button class="bem-theme-toggle__btn" data-theme=""></button>
<button class="bem-theme-toggle__btn" data-theme="dia"></button>
<button class="bem-theme-toggle__btn" data-theme="tarde"></button>
<button class="bem-theme-toggle__btn" data-theme="noite"></button>
</div>
<!-- JS: 8 linhas -->
<script>
var t = localStorage.getItem('bem-theme') || '';
document.documentElement.setAttribute('data-theme', t);
document.querySelectorAll('.bem-theme-toggle__btn').forEach(function(b) {
if (b.dataset.theme === t) b.classList.add('bem-theme-toggle__btn--active');
b.addEventListener('click', function() {
var theme = this.dataset.theme;
document.documentElement.setAttribute('data-theme', theme);
localStorage.setItem('bem-theme', theme);
document.querySelectorAll('.bem-theme-toggle__btn')
.forEach(function(x) { x.classList.remove('bem-theme-toggle__btn--active'); });
this.classList.add('bem-theme-toggle__btn--active');
});
});
</script>
3. Instale a extensão VS Code
# Windows
xcopy /E /I vscode-extension "%USERPROFILE%\.vscode\extensions\microframework__pense-bem--intellisense-1.0.0"
# macOS / Linux
cp -r vscode-extension ~/.vscode/extensions/microframework__pense-bem--intellisense-1.0.0
Instalação
O framework oferece duas rotas de uso independentes — e elas funcionam perfeitamente juntas.
Ideal para projetos simples, protótipos e quando você quer zero dependências de build.
- Baixe o
microframework.css - Coloque na pasta do seu projeto
- Adicione o
<link>no<head>
Para fluxo de desenvolvimento ativo: IntelliSense BEM, snippets e hover docs direto no editor.
- Instale a extensão (veja abaixo)
- Abra um arquivo HTML
- Digite
bem-e pressione Tab
microframework.css localmente e instale a extensão VS Code. Você ganha velocidade de desenvolvimento máxima e total controle sobre o arquivo CSS.
Opção A — Download direto
<!-- Cole no <head> do seu HTML -->
<link rel="stylesheet" href="microframework.css">
<!-- Opcionalmente, download via curl -->
Opção B — Instalar extensão VS Code
# Windows (PowerShell)
xcopy /E /I vscode-extension "%USERPROFILE%\.vscode\extensions\microframework__pense-bem--intellisense-1.0.0"
# macOS / Linux
cp -r vscode-extension ~/.vscode/extensions/microframework__pense-bem--intellisense-1.0.0
# Após instalar: reinicie o VS Code
.html e comece a digitar bem-.
O IntelliSense contextual sugere apenas elementos e modificadores válidos para o bloco atual.
Container
Wrapper centralizado com largura máxima configurável.
| Classe | Largura máx. | Uso |
|---|---|---|
bem-container | 1200px | Padrão |
bem-container--fluid | 100% | Full width |
bem-container--narrow | 800px | Conteúdo focado |
<div class="bem-container">...</div>
<div class="bem-container bem-container--fluid">...</div>
<div class="bem-container bem-container--narrow">...</div>
Grid
Sistema de grid CSS com 2, 3 e 4 colunas. Colapsa para 1 coluna em mobile.
Preview
<div class="bem-grid bem-grid-auto">
<div>...</div>
<div>...</div>
</div>
<div class="bem-grid bem-grid-auto bem-grid--gap-lg">
<div>...</div>
<div>...</div>
<div>...</div>
</div>
| Modificador | Efeito |
|---|---|
bem-grid-auto | 2 colunas iguais |
bem-grid-auto | 3 colunas iguais |
bem-grid-auto | 4 colunas iguais |
bem-grid--gap-sm | Gap pequeno (0.5rem) |
bem-grid--gap-lg | Gap grande (1.5rem) |
Card
Container versátil com header, body, footer, imagem e ações.
Preview
Card Completo
Com header, body e footer
Conteúdo do card com todas as seções disponíveis.
Card Flat
Sem sombra, borda sutil.
<!-- Card completo -->
<div class="bem-card">
<div class="bem-card__header">
<h3 class="bem-card__title">Título</h3>
<p class="bem-card__subtitle">Subtítulo</p>
</div>
<div class="bem-card__body">
Conteúdo
</div>
<div class="bem-card__footer">
<div class="bem-card__actions">
<button class="bem-btn bem-btn--primary bem-btn--sm">Ação</button>
</div>
</div>
</div>
<!-- Card flat (sem sombra) -->
<div class="bem-card bem-card--flat">
<div class="bem-card__body">...</div>
</div>
<!-- Card com imagem -->
<div class="bem-card">
<img class="bem-card__image" src="foto.jpg" alt="...">
<div class="bem-card__body">
<h3 class="bem-card__title">Título</h3>
</div>
</div>
Form
Formulários com validação visual, estados de erro/sucesso e suporte a todos os tipos de input.
Preview
<form class="bem-form">
<!-- Campo obrigatório -->
<div class="bem-form__group">
<label class="bem-form__label bem-form__label--required">Nome</label>
<input type="text" class="bem-form__input" placeholder="...">
</div>
<!-- Campo com erro -->
<div class="bem-form__group">
<label class="bem-form__label">Senha</label>
<input type="password" class="bem-form__input bem-form__input--error">
<span class="bem-form__error">Mínimo 8 caracteres</span>
</div>
<!-- Campo com sucesso -->
<div class="bem-form__group">
<label class="bem-form__label">Email</label>
<input type="email" class="bem-form__input bem-form__input--success">
</div>
<!-- Select -->
<div class="bem-form__group">
<label class="bem-form__label">Opção</label>
<select class="bem-form__select">
<option>Escolha...</option>
</select>
</div>
<!-- Checkbox -->
<div class="bem-form__checkbox">
<input type="checkbox" id="terms">
<label for="terms">Aceito os termos</label>
</div>
<button type="submit" class="bem-btn bem-btn--primary bem-btn--block">Enviar</button>
</form>
Alert
Mensagens contextuais com 4 variantes semânticas.
<div class="bem-alert bem-alert--info">
<span class="bem-alert__icon"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"></circle><line x1="12" y1="16" x2="12" y2="12"></line><line x1="12" y1="8" x2="12.01" y2="8"></line></svg></span>
<div class="bem-alert__content">
<div class="bem-alert__title">Título</div>
<div class="bem-alert__message">Mensagem...</div>
</div>
<button class="bem-alert__close">×</button>
</div>
<!-- Variantes: bem-alert--info | --success | --warning | --danger -->
Modal
Diálogo modal com overlay escuro. Oculte com bem-modal--hidden.
<!-- Botão -->
<button class="bem-btn bem-btn--primary" onclick="openModal()">Abrir</button>
<!-- Modal -->
<div class="bem-modal bem-modal--hidden" id="meu-modal">
<div class="bem-modal__dialog">
<div class="bem-modal__header">
<h3 class="bem-modal__title">Título</h3>
<button class="bem-modal__close" onclick="closeModal()">×</button>
</div>
<div class="bem-modal__body">
Conteúdo do modal.
</div>
<div class="bem-modal__footer">
<button class="bem-btn bem-btn--outline" onclick="closeModal()">Cancelar</button>
<button class="bem-btn bem-btn--primary">Confirmar</button>
</div>
</div>
</div>
<script>
function openModal() { document.getElementById('meu-modal').classList.remove('bem-modal--hidden'); }
function closeModal() { document.getElementById('meu-modal').classList.add('bem-modal--hidden'); }
</script>
Temas
Aplique um tema adicionando data-theme na tag <html>.
Todos os componentes atualizam automaticamente via CSS Variables.
Implementação HTML
<!-- Padrão (azul, fundo branco) -->
<html>
<!-- Dia (roxo, fundo cinza claro) -->
<html data-theme="dia">
<!-- Tarde (laranja, fundo creme) -->
<html data-theme="tarde">
<!-- Noite (teal, fundo escuro) -->
<html data-theme="noite">
Tokens por tema
| Token | Padrão | Dia | Tarde | Noite |
|---|---|---|---|---|
--bem-primary | #3b82f6 | #8b5cf6 | #f97316 | #2dd4bf |
--bem-bg | #ffffff | #f5f5f7 | #fdf5ee | #0f172a |
--bem-surface | #ffffff | — | #fffaf7 | #1e293b |
--bem-text | #1f2937 | — | — | #f1f5f9 |
--bem-text-muted | #6b7280 | — | #78716c | #94a3b8 |
--bem-border | #e5e7eb | — | #e7d5c4 | #334155 |
Tema personalizado
/* Crie seu próprio tema */
[data-theme="minha-marca"] {
--bem-primary: #6366f1;
--bem-secondary: #ec4899;
--bem-bg: #fafafa;
--bem-surface: #ffffff;
--bem-text: #111827;
--bem-text-muted: #6b7280;
--bem-border: #e5e7eb;
--bem-light: #f9fafb;
}
Utilitários
| Classe | Propriedade |
|---|---|
| Texto | |
bem-text-center | text-align: center |
bem-text-left | text-align: left |
bem-text-right | text-align: right |
| Margin Top | |
bem-mt-sm | margin-top: 0.5rem |
bem-mt-md | margin-top: 1rem |
bem-mt-lg | margin-top: 1.5rem |
| Margin Bottom | |
bem-mb-sm | margin-bottom: 0.5rem |
bem-mb-md | margin-bottom: 1rem |
bem-mb-lg | margin-bottom: 1.5rem |
| Padding | |
bem-p-sm | padding: 0.5rem |
bem-p-md | padding: 1rem |
bem-p-lg | padding: 1.5rem |
| Flexbox | |
bem-flex | display: flex |
bem-flex-col | flex-direction: column |
bem-items-center | align-items: center |
bem-justify-center | justify-content: center |
bem-justify-between | justify-content: space-between |
bem-gap-sm | gap: 0.5rem |
bem-gap-md | gap: 1rem |
| Dimensões | |
bem-w-full | width: 100% |
bem-h-full | height: 100% |
| Bordas & Sombras | |
bem-rounded | border-radius: 0.5rem |
bem-rounded-full | border-radius: 9999px |
bem-shadow | box-shadow: md |
bem-shadow-lg | box-shadow: lg |
CSS Variables A11Y
Todas as variáveis definidas em :root. Sobrescreva no seu CSS para personalizar.
Ao sobrescrever as variáveis de cor (
--bem-primary, --bem-secondary, etc), garanta sempre que elas obedeçam a regra de Contraste de Cor (Axe 4.11 / WCAG 2.1 AA).
O texto normal requer uma proporção de contraste de pelo menos 4.5:1 com o fundo, e textos grandes ou componentes de interface exigem 3:1.
Evite mesclar fundos translúcidos (bem-bg-glass) com textos claros sem testar rigorosamente o contraste, garantindo que o seu site permanceça acessível a todos os usuários.
/* Sobrescreva no seu CSS (depois do import) */
:root {
/* Paleta de cores */
--bem-primary: #3b82f6; /* Cor principal */
--bem-secondary: #8b5cf6; /* Cor secundária */
--bem-success: #10b981; /* Verde */
--bem-danger: #ef4444; /* Vermelho */
--bem-warning: #f59e0b; /* Amarelo */
--bem-dark: #1f2937; /* Escuro */
--bem-light: #f3f4f6; /* Claro */
/* Tokens semânticos (afetados pelos temas) */
--bem-bg: #ffffff; /* Fundo da página */
--bem-surface: #ffffff; /* Fundo dos cards/modais */
--bem-text: #1f2937; /* Texto principal */
--bem-text-muted: #6b7280; /* Texto secundário */
--bem-border: #e5e7eb; /* Bordas */
/* Espaçamento */
--bem-spacing-xs: .25rem;
--bem-spacing-sm: .5rem;
--bem-spacing-md: 1rem;
--bem-spacing-lg: 1.5rem;
--bem-spacing-xl: 2rem;
/* Tipografia */
--bem-font-base: -apple-system, BlinkMacSystemFont, 'Segoe UI', ...;
--bem-font-mono: 'Courier New', monospace;
/* Border-radius */
--bem-radius-sm: .25rem;
--bem-radius-md: .5rem;
--bem-radius-lg: 1rem;
/* Sombras */
--bem-shadow-sm: 0 1px 2px rgba(0,0,0,.05);
--bem-shadow-md: 0 4px 6px -1px rgba(0,0,0,.1);
--bem-shadow-lg: 0 10px 15px -3px rgba(0,0,0,.1);
}
Metodologia BEM
BEM (Block, Element, Modifier) é uma convenção de nomenclatura que torna o CSS
previsível e reutilizável. Este framework usa o prefixo bem- para
isolar do CSS do projeto.
Componente independente e reutilizável.
.bem-card { }Parte do bloco, sem significado independente.
.bem-card__title { }Varia aparência ou comportamento.
.bem-btn--primary { }Exemplo completo
<!-- BLOCO: bem-card -->
<div class="bem-card">
<!-- ELEMENTO: bem-card__header -->
<div class="bem-card__header">
<h3 class="bem-card__title">Título</h3>
<p class="bem-card__subtitle">Subtítulo</p>
</div>
<div class="bem-card__body">
<!-- BLOCO aninhado com MODIFICADOR -->
<button class="bem-btn bem-btn--primary bem-btn--lg">
Botão Primário Grande
</button>
</div>
</div>
<!-- MODIFICADOR no bloco: bem-card--flat -->
<div class="bem-card bem-card--flat">
<div class="bem-card__body">Card sem sombra</div>
</div>
Ícones SVG
Embutir um conjunto de ícones no CSS adicionaria ~20–80 KB ao bundle, destruindo o objetivo de permanecer abaixo dos 14 KB críticos. A abordagem recomendada é SVG inline, que é grátis, acessível e suporta tematização automática via
currentColor.
Por que SVG inline?
| Técnica | Tamanho | A11y | Tematização | Recomendação |
|---|---|---|---|---|
SVG inline | 0 KB extra | ✅ aria-label | ✅ currentColor | ✅ Recomendado |
| Icon Font (FontAwesome) | ~70 KB | ⚠️ Complexo | ✅ color | ❌ Pesado |
CSS content: url() | Variável | ❌ Invisível | ❌ Não | ❌ Evitar |
| Imagem PNG/WebP | Variável | ⚠️ Precisa alt | ❌ Não | ❌ Evitar |
Padrão de uso com acessibilidade
<!-- Ícone decorativo (oculto de leitores de tela) -->
<svg aria-hidden="true" focusable="false" width="20" height="20"
viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M12 2L2 7l10 5 10-5-10-5z"/>
</svg>
<!-- Ícone com significado (botão apenas de ícone) -->
<button aria-label="Fechar menu">
<svg aria-hidden="true" focusable="false" width="20" height="20"
viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/>
</svg>
</button>
<!-- stroke="currentColor" herda a cor do elemento pai -->
<!-- Funciona automaticamente com qualquer tema! -->
Galeria de Ícones por Categoria
Clique em qualquer ícone para copiar o SVG. Todos usam stroke="currentColor" — mudam de cor automaticamente com o tema.
Passe o mouse e clique para copiar o SVG completo com atributos de acessibilidade incluídos.
Performance & Acessibilidade
Decisões de design que tornam este framework rápido por padrão e acessível por construção.
O limite mágico dos 14 KB
microframework.css (12.7 KB) cabe inteiro nessa janela, o que significa que o navegador recebe o CSS completo no primeiro pacote de rede.
| Framework | Tamanho minificado | Cabe em 1 RTT? | Parse JS obrigatório? |
|---|---|---|---|
| Microframework BEM | 12.7 KB | ✅ Sim | ✅ Não (apenas CSS) |
| Bootstrap 5 | ~150 KB | ❌ ~10 RTTs | ❌ bundle.js 80KB+ |
| Tailwind (built) | ~15–30 KB | ⚠️ Depende do build | ✅ Não |
| Foundation 6 | ~200 KB | ❌ ~14 RTTs | ❌ JS obrigatório |
Zero JavaScript no core
O framework não carrega nenhum JavaScript obrigatório. Isso elimina:
- Bloqueio do Critical Rendering Path por parse de JS
- Hidratação de componentes (sem framework de UI necessário)
- Erros de JS que quebram a interface inteira
- Conflitos de versão entre bibliotecas
localStorage e data-theme. Não é obrigatório — sem ele, o tema padrão é aplicado normalmente.
CSS Custom Properties vs Pré-processadores
/* Com Sass: rebuild necessário para trocar tema */
$primary: #3b82f6;
.btn { background: $primary; } /* Compila em CSS estático */
/* Com CSS Variables: troca em tempo real, zero rebuild */
:root { --bem-primary: #3b82f6; }
[data-theme="noite"] { --bem-primary: #60a5fa; }
.bem-btn { background: var(--bem-primary); } /* Atualiza live! */
Acessibilidade embutida
Os snippets gerados pelo VS Code já incluem os atributos corretos de acessibilidade:
| Prática | Onde é aplicada | WCAG |
|---|---|---|
| Contraste mínimo 4.5:1 | Todas as cores de texto vs. fundo | AA 1.4.3 |
for/id em formulários | Snippets bem-form-group | 1.3.1 |
aria-label em ícones | Snippets bem-btn-icon | 4.1.2 |
role="main" | Snippets de página completa | 1.3.6 |
:focus-visible | Todos os elementos interativos | 2.4.7 |
aria-hidden="true" em SVGs decorativos | Documentado na seção de Ícones | 1.1.1 |
VS Code Extension
A extensão adiciona IntelliSense contextual BEM, snippets e documentação inline ao VS Code — sem configuração extra.
IntelliSense Contextual
Sugere apenas elementos e modificadores válidos para o bloco atual.
<div class="bem-card__">
<!-- Sugere: header title subtitle
body footer image actions -->Snippets (Tab)
Digite o prefixo e pressione Tab para expandir estruturas completas.
bem-card → card completo
bem-form → formulário
bem-modal → modal
bem-navbar → navbarTodos os snippets
| Prefixo | Expande para |
|---|---|
bem-btn | Botão básico |
bem-btn-icon | Botão com ícone |
bem-card | Card completo (header+body+footer) |
bem-card-simple | Card só com body |
bem-card-image | Card com imagem |
bem-form | Formulário completo |
bem-form-group | Grupo de input |
bem-form-textarea | Grupo de textarea |
bem-form-select | Grupo de select |
bem-form-checkbox | Checkbox |
bem-alert | Alert com ícone e fechar |
bem-navbar | Navbar responsiva |
bem-modal | Modal completo |
bem-grid | Grid layout |
bem-container | Container |
React / JSX
Use className no lugar de class. Todo o resto é idêntico.
import './microframework.css';
// Toggle de tema em React
import { useState, useEffect } from 'react';
function ThemeToggle() {
const [theme, setTheme] = useState(
() => localStorage.getItem('bem-theme') || ''
);
useEffect(() => {
document.documentElement.setAttribute('data-theme', theme);
localStorage.setItem('bem-theme', theme);
}, [theme]);
return (
<div className="bem-theme-toggle">
{[['', '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="5"/><line x1="12" y1="1" x2="12" y2="3"/><line x1="12" y1="21" x2="12" y2="23"/></svg>'], ['dia', '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="5"/><line x1="12" y1="1" x2="12" y2="3"/><line x1="12" y1="21" x2="12" y2="23"/></svg>'], ['tarde', '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M17 18a5 5 0 0 0-10 0"></path><line x1="12" y1="2" x2="12" y2="9"></line></svg>'], ['noite', '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path></svg>']].map(([t, icon]) => (
<button
key={t}
className={`bem-theme-toggle__btn${theme === t ? ' bem-theme-toggle__btn--active' : ''}`}
onClick={() => setTheme(t)}
>{icon}</button>
))}
</div>
);
}
// Card component
function Card({ title, subtitle, children }) {
return (
<div className="bem-card">
<div className="bem-card__header">
<h3 className="bem-card__title">{title}</h3>
{subtitle && <p className="bem-card__subtitle">{subtitle}</p>}
</div>
<div className="bem-card__body">{children}</div>
</div>
);
}
vs Bootstrap
| Feature | Microframework | Bootstrap 5 |
|---|---|---|
| Metodologia | ✅ BEM semântico | Classes utilitárias |
| Tamanho CSS | ✅ 12.7 KB | ❌ ~150 KB |
| Temas nativos | ✅ 3 prontos + custom | Dark só |
| IntelliSense | ✅ Contextual BEM | ❌ Genérico |
| Snippets VS Code | ✅ Estruturas completas | Básicos |
| Personalização | ✅ CSS Variables | ✅ Sass + CSS Vars |
| JavaScript | ✅ Zero (opcional) | ❌ Bundle obrigatório |
| Componentes | 9 core | ✅ 30+ |
| Curva de aprendizado | ✅ Baixa (BEM intuitivo) | Média |