Visão Geral — HTML - CSS - JS

0:00 / 0:00

HTML, CSS e JavaScript parecem três arquivos simples, mas no browser eles viram um sistema vivo. O HTML cria a árvore de elementos, o CSS calcula a apresentação, o JavaScript altera estado e comportamento, e o DOM é o contrato em memória onde tudo se encontra. Esta visão geral começa pelo encaixe básico e vai subindo até o pipeline real do browser, performance e arquitetura.

O encaixe básico — estrutura, apresentação e comportamento +

A separação clássica é simples e ainda é útil: HTML descreve o conteúdo, CSS descreve como esse conteúdo aparece, e JavaScript descreve o que acontece quando a página precisa reagir.

CamadaResponsabilidadeErro típico
HTMLSemântica, hierarquia, formulário, links, texto, mídiaBotão que deveria ser link, título fora de ordem, formulário sem label
CSSLayout, cor, tipografia, estados, responsividadeElemento desalinhado, quebra no mobile, regra sobrescrita sem querer
JavaScriptEventos, estado, DOM, rede, fluxo assíncronoClique sem efeito, estado inconsistente, requisição fora de ordem

Mas essa divisão não significa isolamento total. O CSS depende da estrutura do HTML. O JavaScript consulta e altera o DOM. Mudanças de classe feitas por JavaScript disparam novas regras CSS. Na prática, front-end é o estudo das fronteiras entre essas três camadas.

<button class="save-button" type="button">Salvar</button>
.save-button {
    background: #2563eb;
    color: #ffffff;
}
document.querySelector('.save-button')
    .addEventListener('click', saveChanges);
HTML além de tags — semântica, acessibilidade e contrato de dados +

HTML não é só marcação visual. Ele informa ao browser, leitores de tela, motores de busca e scripts o que cada parte da página significa. Um botão, um link e uma div clicável podem parecer iguais depois do CSS, mas não são equivalentes.

<article class="task-card" data-task-id="42">
    <h2>Revisar pedido</h2>
    <p>Pedido aguardando confirmação fiscal.</p>
    <button type="button" aria-label="Marcar pedido como revisado">
        Revisar
    </button>
</article>

Esse trecho carrega várias decisões:

  • <article> diz que o card é uma unidade de conteúdo.
  • <h2> preserva hierarquia navegável.
  • <button> comunica ação, recebe foco e responde ao teclado.
  • data-task-id cria um ponto de ligação entre DOM e lógica.
  • aria-label melhora a descrição quando o texto visual não basta.

Em páginas simples, semântica parece detalhe. Em aplicações grandes, ela vira contrato: testes automatizados encontram elementos, scripts ligam comportamento, acessibilidade funciona e o HTML continua legível mesmo antes do CSS carregar.

CSS além da aparência — cascade, especificidade e layout engine +

CSS parece uma lista de propriedades, mas o browser precisa resolver conflitos antes de desenhar qualquer coisa. A regra final aplicada a um elemento nasce da combinação de origem, importância, especificidade, ordem e herança.

button { color: #111827; }
.save-button { color: #2563eb; }
main .save-button { color: #16a34a; }

As três regras miram o mesmo botão. A última vence por ser mais específica. Esse é o tipo de decisão que explica por que "mudei o CSS e nada aconteceu" quase sempre é problema de cascade, seletor, ordem de carregamento ou estado.

Do CSS até pixels

  1. O browser parseia CSS e monta a CSSOM.
  2. Combina DOM + CSSOM para formar a render tree.
  3. Calcula layout: posição e tamanho de cada caixa.
  4. Pinta camadas: texto, fundo, borda, sombra, imagem.
  5. Compõe na tela, muitas vezes usando GPU.

Nem toda mudança visual custa a mesma coisa. Alterar width pode recalcular layout. Alterar color tende a repintar. Alterar transform ou opacity costuma ser mais barato porque pode ficar na etapa de composição.

MudançaCusto comumExemplo
LayoutMais carowidth, height, display, font-size
PaintMédiocolor, background, box-shadow
CompositeMais baratotransform, opacity
JavaScript no browser — estado, eventos, módulos e assincronia +

JavaScript entra quando a página precisa decidir algo em runtime: responder a eventos, buscar dados, validar entrada, alterar estado e refletir esse estado no DOM. O ponto central é que o browser é orientado a eventos.

const state = {
    selectedId: null,
    loading: false
};

document.addEventListener('click', async function(event) {
    const button = event.target.closest('[data-load-user]');
    if (!button) return;

    state.loading = true;
    const response = await fetch(`/api/users/${button.dataset.loadUser}`);
    const user = await response.json();

    state.selectedId = user.id;
    state.loading = false;
    renderUser(user);
});

Esse exemplo mistura quatro coisas importantes: delegação de evento, atributo data-*, requisição assíncrona e renderização. Parece simples, mas em escala isso vira arquitetura.

Event loop em uma frase

JavaScript executa em uma thread principal, mas agenda trabalhos. Cliques, timers, promises e respostas de rede entram em filas. O event loop decide quando cada callback roda, intercalando código JS com renderização do browser.

console.log('A');

setTimeout(() => console.log('B'), 0);
Promise.resolve().then(() => console.log('C'));

console.log('D');

// Ordem: A, D, C, B

Promises rodam antes de timers porque entram na fila de microtasks. Esse detalhe importa quando uma tela atualiza em ordem inesperada ou quando um loading pisca rápido demais.

Módulos

Em código moderno, JavaScript tende a ser dividido em módulos. Isso evita variáveis globais e deixa dependências explícitas.

import { formatCurrency } from './money.js';

export function renderPrice(value) {
    return formatCurrency(value, 'BRL');
}
DOM como ponto de encontro — árvore, mutação e custo +

O DOM é a representação viva do documento. O HTML inicial cria a primeira árvore, mas JavaScript pode consultar, criar, mover e remover nós. CSS observa essa árvore por seletores. O usuário interage com essa árvore por foco, clique, rolagem, seleção e teclado.

<ul id="tasks">
    <li data-id="1">Compilar notas</li>
    <li data-id="2">Revisar CSS</li>
</ul>
const list = document.querySelector('#tasks');

const item = document.createElement('li');
item.dataset.id = '3';
item.textContent = 'Publicar página';

list.appendChild(item);

Cada mutação pode ter custo. Em listas grandes, alterar o DOM item por item pode gerar trabalho repetido. Uma estratégia comum é montar um fragmento em memória e anexar tudo de uma vez.

const fragment = document.createDocumentFragment();

for (const task of tasks) {
    const li = document.createElement('li');
    li.textContent = task.title;
    fragment.appendChild(li);
}

list.replaceChildren(fragment);

Frameworks como React, Vue e Svelte existem, em parte, para organizar esse problema: como transformar estado em DOM sem deixar a aplicação cheia de mutações manuais difíceis de rastrear.

Pipeline completo — parse, CSSOM, render tree, layout, paint e composite +

Quando a página cresce, o modelo mental mais útil é o pipeline do browser. Ele mostra por que certas escolhas deixam a interface fluida e outras criam travamentos.

  1. Parse HTML — bytes viram tokens, tokens viram nós, nós viram DOM.
  2. Parse CSS — folhas de estilo viram CSSOM.
  3. Execução de scripts — JavaScript pode bloquear ou alterar o parse dependendo de como é carregado.
  4. Style calculation — o browser decide quais regras CSS valem para cada nó.
  5. Layout — calcula geometria das caixas.
  6. Paint — desenha texto, borda, fundo, imagem, sombra.
  7. Composite — combina camadas e entrega o frame final.

Por isso <script defer>, CSS crítico, imagens com tamanho definido e manipulação cuidadosa do DOM não são "otimização prematura"; são formas de não atrapalhar o pipeline.

<link rel="stylesheet" href="app.css">
<script src="app.js" defer></script>
ProblemaCausa comumCorreção típica
Tela pisca sem estiloCSS tarde ou carregamento mal ordenadoCarregar CSS principal cedo
Layout saltaImagem sem dimensão, fonte trocando, conteúdo tardioReservar espaço e definir dimensões
Interface travaJS longo na main threadQuebrar tarefa, adiar trabalho, reduzir DOM
Animação engasgaAnimar propriedades que recalculam layoutPreferir transform e opacity
O que vem nessa trilha — de fundamento para arquitetura +

Os próximos sub-hubs separam a tríade para estudar com profundidade, mas a leitura deve continuar conectada. HTML ruim força CSS frágil. CSS sem arquitetura vira guerra de especificidade. JavaScript sem modelo de estado vira sequência de remendos no DOM.

Sub-hubPrimeira camadaCamada avançada
HTMLTags, atributos, formuláriosSemântica, acessibilidade, SEO técnico, contrato com JS
CSSSeletores, box model, flex/gridCascade layers, arquitetura, tokens, performance de layout
JavaScriptVariáveis, funções, eventosEvent loop, módulos, async, estado, renderização

A ordem pedagógica continua: primeiro entender a estrutura, depois controlar a apresentação, depois adicionar comportamento. Mas o objetivo final é enxergar a página como sistema: dados entram, estado muda, DOM reflete, CSS apresenta e o browser renderiza em frames.