Skip to content
Fase 5O Frontend

Web Básico

Progresso da fase0%

A carregar…

Até agora o teu código só falava com o terminal. Nesta fase ele ganha uma cara: vais aprender a estrutura de uma página web (HTML), a estilizá-la (CSS), a entender como o navegador pede e recebe informação de um servidor (HTTP), e a fazer o teu JavaScript reagir a cliques e outros eventos diretamente numa página.

Prompt recomendado para esta fase

Estou na Fase 5 a aprender HTML, CSS, o protocolo HTTP e manipulação do DOM com JavaScript. Quando eu tiver um problema de layout em CSS, pergunta-me primeiro o que eu esperava ver vs o que estou a ver, e ajuda-me a inspecionar com as ferramentas de developer do navegador antes de me dares a correção direta.

Conteúdos teóricos

4 temas

1. HTML: a estrutura de uma página

As "peças de lego" com que se constrói o conteúdo de qualquer página web.

HTML (HyperText Markup Language) não é uma linguagem de programação — é uma linguagem de marcação, que descreve a estrutura e o conteúdo de uma página, usando etiquetas (tags).

html
<!DOCTYPE html>
<html lang="pt">
  <head>
    <meta charset="UTF-8" />
    <title>A minha primeira página</title>
  </head>
  <body>
    <h1>Olá, mundo!</h1>
    <p>Este é o meu primeiro parágrafo em HTML.</p>
  </body>
</html>

Anatomia de um ficheiro HTML

  • <!DOCTYPE html> — diz ao navegador que versão de HTML estás a usar (sempre esta linha, em todos os ficheiros modernos).
  • <html> — o elemento raiz, que envolve toda a página.
  • <head> — informação sobre a página, que não aparece diretamente no ecrã (título do separador, ligações a ficheiros CSS, etc.).
  • <body> — todo o conteúdo visível da página.

As tags mais comuns

  • <h1> a <h6> — títulos, do maior (h1) ao mais pequeno (h6). Usa só um <h1> por página, como o título principal.
  • <p> — um parágrafo de texto.
  • <a href="..."> — uma ligação (link) para outra página.
  • <img src="..." alt="..."> — uma imagem. O alt é obrigatório para acessibilidade — descreve a imagem para quem usa leitores de ecrã.
  • <div> e <span> — contentores genéricos sem significado próprio, usados para agrupar e estilizar outros elementos.
  • <ul>/<ol> com <li> — listas não numeradas / numeradas, com os seus itens.

Tags abrem e fecham — quase sempre

A maioria das tags tem uma abertura (<p>) e um fecho (</p>), com o conteúdo entre as duas. Algumas, como <img src="..." alt="...">, não têm conteúdo interno e não precisam de fecho. Esquecer de fechar uma tag é o erro mais comum em quem começa — o navegador tenta "adivinhar" onde deverias ter fechado, e o resultado raramente é o que esperavas.

2. CSS: dar estilo ao HTML

Cores, espaçamentos, tamanhos e layout — tudo o que o HTML sozinho não consegue fazer.

CSS (Cascading Style Sheets) descreve como os elementos HTML devem aparecer: cor, tamanho, espaçamento, posição. Sem CSS, uma página é só texto preto sobre fundo branco, na ordem em que foi escrita.

css
h1 {
  color: #4f46e5;
  font-size: 32px;
  text-align: center;
}

p {
  color: #333;
  line-height: 1.6;
}

Cada regra CSS tem um seletor (o que estás a estilizar — aqui, h1 e p) e um bloco de propriedades: valor, entre chavetas.

As três formas de ligar CSS a HTML

  1. Ficheiro externo (a forma recomendada): um ficheiro .css separado, ligado com <link rel="stylesheet" href="estilos.css"> dentro do <head>.
  2. Interno: CSS dentro de uma tag <style> no próprio <head> do HTML.
  3. Inline: CSS diretamente num atributo style="" de um elemento específico — evita isto, exceto para testes rápidos, porque mistura estrutura com estilo e é difícil de manter.

O modelo de caixa (box model)

Todo o elemento HTML é, para o CSS, uma caixa retangular com quatro camadas, de dentro para fora:

  • content — o conteúdo em si (texto, imagem).
  • padding — espaço entre o conteúdo e o limite da caixa.
  • border — a linha à volta da caixa.
  • margin — espaço entre esta caixa e as caixas vizinhas.

Perceber isto resolve a maioria das confusões de "porque é que este elemento não fica onde eu quero" — quase sempre é padding ou margin a empurrar as coisas.

Seletores mais usados

  • h1, p, div — por tipo de elemento.
  • .classe — por classe (um elemento pode ter várias classes; várias tags podem partilhar a mesma classe). É o mais usado na prática.
  • #id — por identificador único (só um elemento por página pode ter cada id).
estilos.css
.cartao {
  padding: 16px;
  border: 1px solid #e2e2e2;
  margin: 12px;
  border-radius: 8px;
  background-color: #f9fafb;
}
Box model em ação: padding, border e margin

3. O protocolo HTTP: como a web comunica

O "idioma" que o navegador e o servidor usam para trocar informação.

Sempre que abres uma página web, o teu navegador (o cliente) envia um pedido (request) a um servidor, e o servidor devolve uma resposta (response). Esse diálogo segue um conjunto de regras chamado HTTP (HyperText Transfer Protocol).

Os métodos HTTP mais comuns

  • GET — pedir dados (ex: carregar uma página, ou pedir a lista de produtos de uma loja). Não deve alterar nada no servidor.
  • POST — enviar dados novos para o servidor (ex: submeter um formulário de registo, criar uma nova nota).
  • PUT / PATCH — atualizar dados existentes.
  • DELETE — apagar dados existentes.

Vais usar estes quatro verbos constantemente a partir da Fase 6 e da Fase 7, quando começares a construir aplicações com base de dados.

Códigos de estado (status codes)

Toda a resposta HTTP vem acompanhada de um número de três dígitos que resume o que aconteceu:

  • 200 — sucesso (OK).
  • 201 — sucesso, e algo novo foi criado (comum depois de um POST).
  • 400 — o pedido do cliente estava mal formado (ex: faltam dados obrigatórios).
  • 401 / 403 — não autorizado / proibido (falta de permissões).
  • 404 — não encontrado (o recurso pedido não existe).
  • 500 — erro interno do servidor (algo correu mal do lado do servidor, não é culpa do cliente).

Quando começares a fazer pedidos a partir do teu próprio código, o primeiro número que vais olhar num erro é sempre este — ele diz-te imediatamente se o problema é do teu pedido (4xx) ou do servidor (5xx).

Um pedido real, visto de perto

javascript
GET /produtos HTTP/1.1
Host: minhaloja.com

→ Resposta:
HTTP/1.1 200 OK
Content-Type: application/json

[{"id": 1, "nome": "Teclado"}, {"id": 2, "nome": "Rato"}]

Isto é, em essência, tudo o que acontece por trás de qualquer aplicação web: pedidos e respostas, um de cada vez.

4. JavaScript no navegador: o DOM

Usar código para ler e modificar uma página HTML depois de já estar carregada.

Até agora usaste o Node.js para correr JavaScript no terminal. Mas o JavaScript nasceu para correr dentro do navegador, onde tem acesso a algo que o Node.js não tem: o DOM (Document Object Model) — uma representação da página HTML em forma de objetos que o teu código pode ler e alterar.

Selecionar elementos

javascript
const titulo = document.querySelector("h1");
console.log(titulo.textContent); // lê o texto atual do h1

titulo.textContent = "Novo título!"; // muda o texto na página, ao vivo

document.querySelector(seletor) aceita o mesmo tipo de seletores que já usaste em CSS ("h1", ".classe", "#id") e devolve o primeiro elemento que encontrar. document.querySelectorAll(seletor) devolve todos os que corresponderem, como uma lista percorrível com forEach.

Reagir a eventos

A parte que torna uma página verdadeiramente interativa é ouvir eventos — cliques, submissões de formulário, teclas premidas — e reagir a eles com uma função:

javascript
const botao = document.querySelector("#botao-somar");

botao.addEventListener("click", function () {
  console.log("O botão foi clicado!");
});

addEventListener recebe o nome do evento ("click", "submit", "input", entre muitos outros) e uma função a correr sempre que esse evento acontecer. Repara que esta função não é chamada por ti — é o navegador que a chama, sempre que o clique acontecer. Chama-se a isto uma função de callback.

Onde isto se encaixa no que já sabes

Tudo o resto que aprendeste — variáveis, condições, loops, funções, arrays, objetos — continua a funcionar exatamente da mesma forma dentro do navegador. O DOM é só uma nova fonte de dados (o que está no ecrã) e um novo destino para as tuas ações (mudar o que está no ecrã).

Exercícios práticos

4 exercícios
Fácil

Exercício Fácil — A Tua Página Pessoal

Cria uma página HTML simples sobre ti, e estiliza-a com um ficheiro CSS separado.

FerramentasVS CodeNavegador

Objetivo: praticar a estrutura básica de HTML e a ligação a um ficheiro CSS externo.

Passos a realizar

  1. Cria uma pasta pagina-pessoal dentro de fase5, com dois ficheiros: index.html e estilos.css.
  2. No index.html, escreve a estrutura completa (DOCTYPE, html, head, body).
  3. Dentro do body, adiciona: um h1 com o teu nome, um parágrafo com uma frase sobre ti, e uma lista (ul/li) com três coisas que estás a aprender.
  4. Liga o ficheiro CSS no head com a tag link.
  5. No estilos.css, estiliza o h1 com uma cor à tua escolha, e o body com uma fonte e um espaçamento (padding) confortáveis.
  6. Abre o ficheiro index.html diretamente no navegador (duplo clique) e confirma que os estilos são aplicados.

Dicas úteis

  • Se o CSS não parecer aplicado, confirma o caminho no href do link — um erro de nome de ficheiro é a causa mais comum.
  • Usa as ferramentas de developer do navegador (F12) para inspecionares os elementos e confirmares que classes/estilos estão realmente a chegar.

Erros comuns

  • Esquecer de fechar alguma tag, o que pode desalinhar o resto da página.
  • Escrever CSS dentro de um atributo style="" em vez de usar o ficheiro externo, perdendo a prática pedida no exercício.

As minhas dúvidas

Médio

Exercício Médio — Formulário com Manipulação do DOM

Cria um formulário HTML e usa JavaScript para capturar o valor digitado e mostrá-lo na página, sem recarregar.

FerramentasVS CodeNavegador

Objetivo: praticar seleção de elementos, eventos e alteração do conteúdo da página em tempo real.

Passos a realizar

  1. Cria uma pasta formulario-nomes dentro de fase5, com index.html e script.js.
  2. No HTML, cria um input de texto, um botão, e um elemento vazio (ex: um p com um id) onde o resultado vai aparecer.
  3. Liga o script.js no fim do body com uma tag script.
  4. No script.js, seleciona os três elementos com querySelector.
  5. Adiciona um addEventListener de "click" ao botão que lê o valor do input (propriedade .value) e o escreve dentro do elemento de resultado (propriedade .textContent).
  6. Depois de escrever o resultado, limpa o input (define .value como string vazia) para o próximo nome.

Fluxo de funcionamento

  1. 1Utilizador escreve no input
  2. 2Clica no botão
  3. 3JS lê input.value
  4. 4Atualiza o texto na página

Código de exemplo

script.js
const input = document.querySelector("#nome-input");
const botao = document.querySelector("#botao-mostrar");
const resultado = document.querySelector("#resultado");

botao.addEventListener("click", function () {
  const nome = input.value;
  resultado.textContent = "Olá, " + nome + "!";
  input.value = "";
});
Estrutura de partida

Dicas úteis

  • Confirma sempre no console do navegador (F12) se o querySelector encontrou mesmo o elemento — se devolver null, o seletor está errado ou o script correu antes do HTML existir.
  • Um script colocado no fim do body corre depois do HTML já estar todo carregado, o que evita o problema de "elemento não encontrado" logo à partida.

Erros comuns

  • Usar .innerHTML em vez de .textContent sem necessidade — para texto simples, .textContent é mais seguro.
  • Esquecer que .value do input é sempre uma string, mesmo que o utilizador escreva números.

As minhas dúvidas

Médio

Exercício Médio — O Teu Primeiro Pedido HTTP com fetch

Usa fetch para pedir dados a uma API pública gratuita e mostrar o resultado na página.

FerramentasVS CodeNavegador

Objetivo: ver, na prática, o pedido/resposta HTTP que estudaste no tema 3 — desta vez feito pelo teu próprio código.

Passos a realizar

  1. Cria uma pasta pedido-http dentro de fase5, com index.html e script.js.
  2. No HTML, cria um botão "Nova frase" e um parágrafo vazio para mostrar o resultado.
  3. No script.js, escreve uma função que usa fetch("https://api.adviceslip.com/advice") para pedir uma frase de conselho aleatória a uma API pública gratuita.
  4. fetch devolve uma Promise — usa .then() para tratar a resposta, converte-a para JSON com .json(), e depois usa outro .then() para escrever o texto da frase no parágrafo.
  5. Liga a função ao evento de clique do botão, para pedires uma nova frase sempre que clicares.
  6. Abre o console do navegador (F12) e observa o separador "Network" enquanto clicas — confirma que vês o pedido GET real a sair e a resposta a chegar.

Fluxo de funcionamento

  1. 1Clique no botão
  2. 2fetch(url) — pedido GET
  3. 3Resposta chega como JSON
  4. 4Mostrar na página

Código de exemplo

script.js
const botao = document.querySelector("#botao-frase");
const resultado = document.querySelector("#resultado");

botao.addEventListener("click", function () {
  fetch("https://api.adviceslip.com/advice")
    .then((resposta) => resposta.json())
    .then((dados) => {
      resultado.textContent = dados.slip.advice;
    });
});
Estrutura de partida

Dicas úteis

  • fetch é assíncrono — o resto do teu código continua a correr antes da resposta chegar, por isso o resultado só aparece dentro do .then().
  • Se nada acontecer ao clicar, confirma no separador Network do DevTools se o pedido saiu mesmo e que código de estado voltou.

Erros comuns

  • Tentar usar o resultado do fetch fora do .then(), antes de a resposta ter chegado.
  • Esquecer o .json() intermédio — a primeira resposta do fetch ainda não é o conteúdo em si, é só o "envelope" da resposta HTTP.

As minhas dúvidas

Difícil

Exercício Difícil — Lista de Tarefas Completa (HTML + CSS + JS)

Constrói uma pequena aplicação de tarefas: adicionar, marcar como concluída e remover, tudo no navegador.

FerramentasVS CodeNavegador

Este exercício junta tudo o que viste nesta fase — HTML, CSS, DOM e eventos — num projeto pequeno mas completo, do tipo que vais reconhecer em praticamente qualquer curso de programação web.

Passos a realizar

  1. Cria uma pasta lista-tarefas dentro de fase5, com index.html, estilos.css e script.js.
  2. No HTML: um input de texto, um botão "Adicionar", e uma lista ul vazia onde as tarefas vão aparecer.
  3. No script.js, mantém um array tarefas em memória. Cada vez que adicionares uma tarefa, cria um novo elemento li, com o texto da tarefa e um botão "Remover" dentro dele, e adiciona-o à lista com appendChild.
  4. Ao clicar numa tarefa (não no botão remover), adiciona/remove uma classe CSS "concluida" que risca o texto (dica CSS: text-decoration: line-through).
  5. O botão "Remover" de cada tarefa deve eliminar apenas esse li da lista, usando remove().
  6. Estiliza a lista no estilos.css: tarefas concluídas com opacidade reduzida, espaçamento confortável entre itens, e um botão remover visualmente distinto (ex: vermelho).

Fluxo de funcionamento

  1. 1Adicionar: cria <li> e insere na lista
  2. 2Clique na tarefa: alterna classe "concluida"
  3. 3Clique em Remover: remove o <li>
  4. 4CSS reage às classes

Código de exemplo

script.js
const input = document.querySelector("#nova-tarefa");
const botaoAdicionar = document.querySelector("#botao-adicionar");
const lista = document.querySelector("#lista-tarefas");

botaoAdicionar.addEventListener("click", function () {
  const texto = input.value.trim();
  if (texto === "") return;

  const item = document.createElement("li");
  item.textContent = texto;

  const botaoRemover = document.createElement("button");
  botaoRemover.textContent = "Remover";
  botaoRemover.addEventListener("click", function (evento) {
    evento.stopPropagation(); // evita marcar como concluída ao remover
    item.remove();
  });

  item.addEventListener("click", function () {
    item.classList.toggle("concluida");
  });

  item.appendChild(botaoRemover);
  lista.appendChild(item);
  input.value = "";
});
Ponto de partida — completa a lógica de adicionar e remover

Dicas úteis

  • Cada tarefa nova precisa do seu próprio addEventListener — se criares os elementos dinamicamente, tens de ligar os eventos a cada um assim que o crias, não só uma vez no início.
  • element.classList.toggle("concluida") é a forma mais simples de adicionar/remover uma classe consoante ela já lá estiver ou não.

Erros comuns

  • Ligar o evento de clique de "remover tarefa" ao <li> inteiro, fazendo com que clicar em qualquer parte da tarefa a apague sem querer.
  • Esquecer de limpar o valor do input depois de adicionar, permitindo adicionar a mesma tarefa várias vezes sem reparar.

As minhas dúvidas