7 min

Construa um app de tarefas simples passo a passo (linguagem clara)

Um guia claro e passo a passo para criar um pequeno app de tarefas: planeje recursos, crie as telas, adicione lógica, salve dados, teste e publique.

Construa um app de tarefas simples passo a passo (linguagem clara)

O que vamos construir (e o que você vai aprender)

Quando eu digo “app” neste guia, quero dizer um pequeno web app: uma única página que você abre no navegador e que responde ao que você clica e digita. Sem instalações, sem contas e sem configurações pesadas — apenas um projeto simples que você pode executar localmente.

O objetivo (o que o app final fará)

No final, você terá um app de tarefas que pode:

  • Adicionar tarefas a partir de uma caixa de entrada
  • Marcar tarefas como concluídas (para ver o que já foi feito)
  • Excluir tarefas que você não precisa mais
  • Manter tarefas após um refresh usando localStorage (para que fechar a aba não apague tudo)

Não será perfeito nem “pronto para empresas”, e esse é o objetivo. Este é um projeto para iniciantes projetado para ensinar o básico sem empilhar muitas ferramentas.

O que você vai aprender (em linguagem simples)

Você vai construir o app passo a passo e aprender as peças principais de como apps front-end funcionam:

  • HTML para criar a estrutura da página (input, botão, lista)
  • CSS para deixar a interface legível e agradável
  • JavaScript para lidar com cliques, criar itens de lista e atualizar a página
  • localStorage para salvar e carregar tarefas para que elas permaneçam
  • Testes e debugging básicos (identificar pequenos erros e corrigi-los)

O que você precisa antes de começar

Mantenha simples. Você só precisa de:

  • Um computador (Windows, Mac ou Linux)
  • Um navegador moderno (Chrome, Firefox, Safari ou Edge)
  • Um editor de código (VS Code é popular, mas qualquer editor serve)

Se você sabe criar uma pasta e editar alguns arquivos, está pronto.

Passo 1: Decida o objetivo e as funcionalidades do app

Antes de escrever qualquer código, decida como será o “sucesso”. Este tutorial constrói um app pequeno com uma tarefa clara: ajudar você a acompanhar tarefas que precisa fazer.

Escolha a única função do app

Escreva uma frase-alvo para manter em mente enquanto constrói:

“Este app me permite adicionar tarefas a uma lista para não esquecê-las.”

Isso é tudo. Se surgir a tentação de adicionar calendários, lembretes, tags ou contas, deixe essas ideias para depois.

Obrigatório vs. desejável

Faça duas listas rápidas:

Obrigatório (para este projeto):

  • Adicionar uma tarefa (digitar texto, clicar um botão)
  • Ver tarefas em uma lista
  • Marcar uma tarefa como concluída
  • Excluir uma tarefa
  • Manter tarefas após atualizar a página (usaremos localStorage depois)

Desejável (não obrigatório hoje): datas de vencimento, prioridades, categorias, pesquisa, arrastar-e-soltar, sincronização na nuvem.

Manter o “obrigatório” pequeno ajuda a terminar de fato.

Descreva a tela em palavras simples

Este app pode ser uma única página com:

  • Um campo de texto (“Adicionar uma tarefa…”) e um botão “Adicionar”
  • Uma lista de tarefas logo abaixo
  • Cada tarefa com um botão de “concluído” e um botão de “excluir”

Defina o que significa “concluído”

Seja específico para não travar:

  • “Concluído” = a tarefa aparece riscada (ou desbotada) e permanece na lista até ser excluída.

Com isso decidido, você está pronto para preparar os arquivos do projeto.

Passo 2: Configure os arquivos do projeto

Antes de escrever código, vamos criar uma “casa” limpa para o app. Manter os arquivos organizados desde o início facilita os próximos passos.

1) Crie uma pasta do projeto

Faça uma nova pasta no seu computador e chame algo como todo-app. Essa pasta conterá tudo do projeto.

Dentro dela, crie três arquivos:

  • index.html (a estrutura da página)
  • styles.css (a aparência e layout)
  • app.js (o comportamento e interatividade)

Se seu sistema esconde extensões, confirme que você tem arquivos reais (um erro comum é acabar com index.html.txt).

2) Abra a pasta no editor e no navegador

Abra a pasta todo-app no seu editor (VS Code, Sublime Text etc.). Depois abra index.html no navegador.

Nesse ponto a página pode estar em branco — e tudo bem. Vamos adicionar conteúdo no próximo passo.

3) Como ver as mudanças

Quando você editar os arquivos, o navegador não atualiza automaticamente (a menos que use uma ferramenta que faça isso).

O ciclo básico é:

  1. Salve o arquivo no editor
  2. Vá até a aba do navegador
  3. Atualize a página para ver a mudança

Se algo “não funciona”, atualizar a página é a primeira ação a tentar.

Opcional: use um servidor local simples (útil, não obrigatório)

Você pode abrir o index.html diretamente, mas um servidor local evita problemas estranhos depois (especialmente ao salvar dados ou carregar arquivos).

Opções simples para iniciantes:

  • No VS Code, instale Live Server e clique em “Go Live”
  • Se você tem Python instalado, execute dentro da pasta:
python -m http.server

Depois abra o endereço que ele informar (geralmente http://localhost:8000) no navegador.

Passo 3: Construa a estrutura da página (HTML)

Agora vamos criar um esqueleto limpo para o app. Esse HTML não fará nada interativo ainda (isso vem depois), mas fornece pontos claros para o JavaScript ler e escrever.

O layout mínimo que precisamos

Incluiremos:

  • Um título para a página ficar óbvia de relance
  • Uma caixa de entrada para o texto da tarefa
  • Um botão Adicionar para enviar a tarefa
  • Uma área de lista onde as tarefas aparecerão

Nomes simples e legíveis ajudam. IDs/classes claros facilitam o JavaScript buscar elementos sem confusão.

Cole isto em index.html

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>To‑Do App</title>
    <link rel="stylesheet" href="styles.css" />
  </head>
  <body>
    <main class="app" id="app">
      <h1 class="app__title" id="appTitle">My To‑Do List</h1>

      <form class="task-form" id="taskForm">
        <label class="task-form__label" for="taskInput">New task</label>
        <div class="task-form__row">
          <input
            id="taskInput"
            class="task-form__input"
            type="text"
            placeholder="e.g., Buy milk"
            autocomplete="off"
          />
          <button id="addButton" class="task-form__button" type="submit">
            Add
          </button>
        </div>
      </form>

      <ul class="task-list" id="taskList" aria-label="Task list"></ul>
    </main>

    <script src="app.js"></script>
  </body>
</html>

Isso é tudo para a estrutura. Observe que usamos id="taskInput" e id="taskList" — esses serão os elementos que você mais manipulará no JavaScript.

Passo 4: Deixe a aparência limpa (CSS)

Agora a página existe, mas provavelmente parece um documento simples. Um pouco de CSS torna o uso mais fácil: espaçamento claro, texto legível e botões que parecem clicáveis.

Comece com um contêiner centralizado

Uma caixa centralizada mantém o app focado e evita que o conteúdo se estique demais em telas largas.

/* Basic page setup */
body {
  font-family: Arial, sans-serif;
  background: #f6f7fb;
  margin: 0;
  padding: 24px;
}

/* Centered app container */
.container {
  max-width: 520px;
  margin: 0 auto;
  background: #ffffff;
  padding: 16px;
  border-radius: 10px;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.08);
}

Facilite a leitura das tarefas

Cada tarefa deve parecer uma “linha” separada, com espaçamento confortável.

ul { list-style: none; padding: 0; margin: 16px 0 0; }

li {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 12px;
  border: 1px solid #e7e7ee;
  border-radius: 8px;
  margin-bottom: 10px;
}

.task-text { flex: 1; }

Adicione uma aparência clara para “concluído”

Quando uma tarefa estiver completa, ela deve mudar visualmente para ser reconhecida rapidamente.

.done .task-text {
  text-decoration: line-through;
  color: #777;
  opacity: 0.85;
}

Padronize os botões

Mantenha os botões do mesmo tamanho e estilo para que pareçam parte de um único app.

button {
  border: none;
  border-radius: 8px;
  padding: 8px 10px;
  cursor: pointer;
}

button:hover { filter: brightness(0.95); }

Isso é suficiente para uma UI limpa e amigável — sem truques avançados. A seguir, vamos ligar o comportamento com JavaScript.

Passo 5: Adicionar tarefas (conceitos básicos de JavaScript)

Experimente versão para celular
Transforme sua ideia de lista de tarefas em um app móvel Flutter usando o mesmo fluxo de chat.

Agora que você tem o input, o botão e a lista na página, vamos fazê-los funcionar. O objetivo: quando alguém digitar uma tarefa e clicar Adicionar (ou apertar Enter), um novo item aparece na lista.

Ligue o botão e a tecla Enter

No seu arquivo JavaScript, primeiramente capture os elementos necessários e depois escute duas ações: o clique no botão e a tecla Enter dentro do input.

const taskInput = document.querySelector('#taskInput');
const addBtn = document.querySelector('#addBtn');
const taskList = document.querySelector('#taskList');

function addTask() {
  const text = taskInput.value.trim();

  // Block empty tasks (including ones that are just spaces)
  if (text === '') return;

  const li = document.createElement('li');
  li.textContent = text;
  taskList.appendChild(li);

  // Clear the input and put the cursor back
  taskInput.value = '';
  taskInput.focus();
}

addBtn.addEventListener('click', addTask);

taskInput.addEventListener('keydown', (event) => {
  if (event.key === 'Enter') {
    addTask();
  }
});

O que isso faz (em linguagem simples)

  • Lê o texto do input e usa trim() para remover espaços extras no início/fim.
  • Para se a tarefa estiver vazia, para não adicionar itens em branco.
  • Cria um novo li, define seu texto e adiciona à lista.
  • Limpa o input e devolve o foco para agilizar a digitação da próxima tarefa.

Se nada acontecer, verifique se os IDs no HTML batem exatamente com os seletores do JavaScript (um erro comum de iniciante).

Passo 6: Marcar como concluído e excluir tarefas

Agora que você pode adicionar tarefas, vamos torná-las acionáveis: você deve poder marcar como concluída e remover uma tarefa.

Armazene tarefas como dados simples

Em vez de usar strings simples, represente cada tarefa como um objeto. Assim cada tarefa tem identidade estável e espaço para marcar se está concluída:

  • text: o texto da tarefa
  • done: true ou false
  • id: um número único para encontrar/excluir a tarefa correta

Exemplo simples:

let tasks = [
  { id: 1, text: "Buy milk", done: false },
  { id: 2, text: "Email Sam", done: true }
];

Adicione controle de “concluído” e botão de “excluir”

Ao renderizar cada tarefa, inclua uma checkbox ou um botão “Concluído”, além de um botão “Excluir”.

Um padrão amigável para iniciantes é delegação de eventos: coloque um único listener de clique no contêiner da lista e verifique onde o clique aconteceu.

function toggleDone(id) {
  tasks = tasks.map(t => t.id === id ? { ...t, done: !t.done } : t);
  renderTasks();
}

function deleteTask(id) {
  tasks = tasks.filter(t => t.id !== id);
  renderTasks();
}

document.querySelector("#taskList").addEventListener("click", (e) => {
  const id = Number(e.target.dataset.id);
  if (e.target.matches(".toggle")) toggleDone(id);
  if (e.target.matches(".delete")) deleteTask(id);
});

Na sua função renderTasks():

  • Adicione data-id="${task.id}" em cada botão.
  • Mostre visualmente tarefas concluídas (por exemplo, adicionando a classe .done).

Passo 7: Salve as tarefas para que persistam (localStorage)

Agora sua lista tem um problema chato: se você atualizar a página (ou fechar a aba), tudo desaparece.

Isso acontece porque as tarefas só existem na memória do JavaScript. Ao recarregar, essa memória é zerada.

localStorage = uma pequena "caixa de salvar" dentro do navegador

localStorage já faz parte do navegador. Pense nele como uma caixinha onde você guarda texto sob um nome (uma “chave”). É perfeito para projetos de iniciante porque não precisa de servidor nem conta.

Vamos salvar a lista inteira de tarefas como texto JSON e carregá-la quando a página abrir.

1) Salve após cada alteração

Sempre que você adicionar, marcar ou excluir uma tarefa, chame saveTasks().

const STORAGE_KEY = "todo.tasks";

function saveTasks(tasks) {
  localStorage.setItem(STORAGE_KEY, JSON.stringify(tasks));
}

Onde seu app atualiza o array tasks, faça isso em seguida:

saveTasks(tasks);
renderTasks(tasks);

2) Carregue no início da página (e renderize)

Ao carregar a página, leia o valor salvo. Se não houver nada salvo, use uma lista vazia.

function loadTasks() {
  const saved = localStorage.getItem(STORAGE_KEY);
  return saved ? JSON.parse(saved) : [];
}

let tasks = loadTasks();
renderTasks(tasks);

Pronto: seu app agora lembra das tarefas após um refresh.

Dica: localStorage só guarda strings, então JSON.stringify() transforma seu array em texto, e JSON.parse() transforma de volta em um array real ao carregar.

Passo 8: Teste e corrija bugs comuns

Comece seu próximo projeto
Prototipe seu próximo app para iniciantes em minutos e aprenda lendo o código.

Testar soa chato, mas é a forma mais rápida de transformar seu app de “funciona no meu computador” para “funciona sempre”. Faça um rápido teste após cada pequena mudança.

Uma passagem de teste rápida (60 segundos)

Execute o fluxo principal nesta ordem:

  • Adicionar uma tarefa
  • Marcá-la como concluída
  • Excluí-la
  • Atualizar a página (para confirmar que o salvamento funciona)

Se alguma etapa falhar, conserte antes de adicionar novas funcionalidades. Apps pequenos ficam bagunçados quando você empilha problemas.

Teste casos extremos que quebram apps de iniciantes

Casos extremos são entradas que você não planejou, mas pessoas reais farão:

  • Texto muito longo (quebra o layout?)
  • Tarefas repetidas (você exclui a certa?)
  • Input em branco (adiciona tarefa vazia?)

Uma correção comum é bloquear tarefas em branco:

const text = input.value.trim();
addButton.disabled = text === "";

(Rode isso no evento input e novamente antes de adicionar.)

Checklist rápido quando “nada acontece”

Quando cliques não fazem nada, geralmente é uma destas:

  • O seletor não corresponde (um id ou classe difere entre HTML e JS).
  • O script não foi carregado (nome/caminho errado, ou app.js não encontrado).
  • Há um erro de JavaScript que interrompe o restante do arquivo.

Use o console para entender o que está acontecendo

Quando algo parece aleatório, registre valores:

console.log("Adding:", text);
console.log("Current tasks:", tasks);

Verifique o Console do navegador por erros (texto em vermelho). Depois de corrigir, remova os logs para não poluir o projeto.

Passo 9: Torne o app confortável de usar (Acessibilidade + Mobile)

Um app de tarefas só está “pronto” quando é confortável para pessoas reais — em celulares, com teclado e com ferramentas assistivas como leitores de tela.

Facilite toques em mobile

Em telas pequenas, botões minúsculos são frustrantes. Dê espaço aos elementos clicáveis:

  • Use padding maior em botões (alvo de ~44px de altura)
  • Separe os botões Concluído e Excluir para evitar toques errados
  • Mantenha o campo de input em largura total no mobile para digitar confortavelmente

Aumentar padding, font-size e gap no CSS normalmente traz o maior benefício.

Adicione labels e ARIA (o que e por que)

Leitores de tela precisam de nomes claros para controles.

  • Seu input de texto deve ter um label real (melhor opção). Se não quiser exibir, esconda visualmente com CSS, mas mantenha no HTML.
  • Botões só com ícone (ex.: lixeira) devem ter aria-label="Delete task" para que o leitor de tela saiba do que se trata.

Isso ajuda pessoas a entenderem cada controle sem adivinhar.

Suporte a teclado: Tab + Enter

Assegure que o app funcione sem mouse:

  • Use Tab para navegar até o input e botões.
  • Pressionar Enter no input deve adicionar a tarefa (usar um <form> faz o Enter funcionar naturalmente).
  • Ao adicionar uma tarefa, considere devolver o foco ao input para agilizar múltiplas inserções.

Legibilidade: contraste e tamanho de fonte

Use tamanho de fonte legível (16px como base) e contraste forte (texto escuro em fundo claro, ou o oposto). Evite depender apenas de cor para indicar “concluído” — adicione um estilo claro como riscar o texto.

Passo 10: Limpe e organize seu código

Publique sem dor de cabeça
Hospede seu app no Koder.ai quando estiver pronto para compartilhá-lo publicamente.

Agora que tudo funciona, dedique 10–15 minutos para arrumar. Isso facilita correções futuras e ajuda você a entender o projeto quando voltar.

Estrutura simples de pastas

Mantenha pequeno e previsível:

  • /index.html — estrutura da página (input, botão, lista)
  • /styles.css — aparência (espaçamentos, fontes, estilo “concluído”)
  • /app.js — comportamento (adicionar, marcar, excluir, salvar/carregar)
  • /README.md — notas rápidas para o “você do futuro”

Se preferir subpastas, tudo bem:

  • /css/styles.css
  • /js/app.js

Apenas garanta que os caminhos em <link> e <script> batam.

Deixe o JavaScript mais legível

Pequenas melhorias:

  • Use nomes claros: taskInput, taskList, saveTasks()
  • Mantenha funções pequenas: uma função = uma tarefa
  • Comente pouco, apenas onde o código não é óbvio

Por exemplo, fica fácil ler:

  • renderTasks(tasks)
  • addTask(text)
  • toggleTask(id)
  • deleteTask(id)

Adicione um README pequeno

Seu README.md pode ser simples:

  • O que faz (uma lista de tarefas que salva os itens)
  • Como rodar (abrir index.html no navegador)
  • Opcional: limitações conhecidas

Faça backup do projeto

Ao menos compacte a pasta após concluir uma etapa importante (por exemplo: “localStorage funcionando”). Se quiser histórico, use Git — mas não é obrigatório. Mesmo um backup pode salvar de exclusões acidentais.

Passo 11: Publique seu app e compartilhe

Publicar significa colocar os arquivos (HTML, CSS, JS) em algum lugar público para que outras pessoas possam abrir um link e usar. Como este app é um “site estático” (roda no navegador sem servidor), você pode hospedá-lo gratuitamente em vários serviços.

Opção 1: GitHub Pages (ótimo para sites estáticos)

Passos gerais:

  1. Crie uma conta no GitHub (se não tiver).
  2. Faça um novo repositório e envie os arquivos (ou dê push com Git).
  3. No repositório, vá em Settings → Pages.
  4. Escolha o branch para publicar (geralmente main) e a pasta (geralmente / root).
  5. Salve — o GitHub fornecerá uma URL pública.

Se usar arquivos separados, confira nomes exatos (ex.: styles.css vs style.css).

Opção 2: Netlify ou Vercel (upload simples)

Para o caminho mais fácil:

  1. Crie conta no Netlify ou Vercel.
  2. Procure Deploy / Add New Project.
  3. Arraste a pasta do projeto (ou conecte um repositório GitHub).
  4. Aguarde o upload/construção abrir.
  5. Teste a URL gerada.
  • Atualize a página: as tarefas devem permanecer (localStorage ok).
  • Adicione, conclua e exclua tarefas: nada quebrado.
  • Abra no mobile (ou reduza a janela): nada vaza para fora da tela.

Quando passar, mande o link para um amigo e peça um teste — olhos frescos acham problemas rápido.

Próximos passos: melhorias fáceis para tentar

Você construiu um app funcional. Se quiser continuar aprendendo sem um salto enorme, essas melhorias adicionam valor e ensinam padrões úteis.

1) Editar o texto da tarefa

Adicione um botão “Editar” ao lado de cada tarefa. Ao clicar, troque o rótulo por um pequeno input (pré-preenchido), mais “Salvar” e “Cancelar”.

Dica: mantenha os dados como um array de objetos (com id e text). Editar então vira: encontrar a tarefa por id, atualizar text, re-renderizar e salvar.

2) Filtros: Todas / Ativas / Concluídas

Adicione três botões no topo: Todas, Ativas, Concluídas.

Armazene o filtro atual em uma variável, por exemplo currentFilter = 'all'. Ao renderizar, mostre:

  • All: todas as tarefas
  • Active: tarefas não concluídas
  • Done: tarefas concluídas

3) Datas de vencimento ou categorias simples

Mantenha leve:

  • Adicione uma data opcional (YYYY-MM-DD) e mostre ao lado da tarefa
  • Ou adicione uma categoria como “Trabalho / Casa / Estudo” com um pequeno dropdown

Mesmo um campo extra ensina como atualizar modelo de dados e UI juntos.

4) Depois: vá do localStorage para um backend simples

Quando estiver pronto para avançar, a ideia é: em vez de salvar no localStorage, envie as tarefas para uma API usando fetch(). O servidor guarda em um banco de dados e você pode sincronizar entre dispositivos.

Se quiser experimentar esse salto sem refazer tudo, plataformas de prototipagem podem ajudar a gerar backends e exemplos para aprender (descrever endpoints, tabelas e mudanças na UI, iterar e exportar código).

5) Bom próximo projeto para iniciantes

Tente fazer um app de notas (com pesquisa) ou um rastreado de hábitos (checagens diárias). Reaproveitam as mesmas habilidades: renderizar listas, editar, salvar e design simples de UI.

Perguntas frequentes

O que preciso para criar este app de lista de tarefas?

Você só precisa de um computador, um navegador moderno e um editor de código. Crie uma pasta com index.html, styles.css e app.js, depois abra o arquivo HTML no navegador.

Quais recursos um app de lista de tarefas para iniciantes deve incluir?

Comece com quatro ações: adicionar uma tarefa, vê-la em uma lista, marcá-la como concluída e excluí-la. Deixe recursos extras, como datas de vencimento, categorias e contas, para depois.

O que cada arquivo faz no projeto?

O HTML cria o campo de entrada, o botão e a lista de tarefas. O CSS controla o espaçamento e a aparência. O JavaScript lê as ações do usuário, atualiza a lista e salva os dados das tarefas.

Como evitar que tarefas em branco sejam adicionadas?

Use um formulário com um campo de texto e um botão de envio. O JavaScript deve remover os espaços do valor inserido, rejeitar um resultado vazio, criar um item da lista e depois limpar e focar o campo.

Por que as tarefas devem usar objetos em vez de texto simples?

Use objetos de tarefa com valores id, text e done. O ID permite que seu código atualize ou remova a tarefa exata, mesmo quando duas tarefas têm o mesmo texto.

Como marco uma tarefa como concluída?

Adicione uma caixa de seleção ou um botão Concluída para cada tarefa. Quando alguém clicar nele, altere o valor done dessa tarefa e adicione uma classe CSS que aplique um texto riscado ou um estilo esmaecido.

Como o app pode lembrar das tarefas após uma atualização?

Armazene o array de tarefas com JSON.stringify() em um nome do localStorage e leia-o com JSON.parse() quando a página iniciar. Salve novamente depois de adicionar, concluir, editar ou excluir uma tarefa.

Por que meu botão Adicionar não faz nada?

Primeiro, atualize a página e abra o Console do navegador para ver mensagens de erro vermelhas. Depois, verifique se os IDs do HTML correspondem aos seletores do JavaScript e se o nome do arquivo de script corresponde ao caminho em index.html.

Como posso facilitar o uso do app em celulares e com o teclado?

Use um rótulo de verdade para o campo de tarefa, deixe os controles grandes o bastante para tocar e teste o app com Tab e Enter. As tarefas concluídas devem usar mais do que apenas cor, como texto riscado e texto claro.

O que devo testar antes de publicar meu app de lista de tarefas?

Teste adicionar uma tarefa, marcá-la como concluída, excluí-la e atualizar a página. Antes de compartilhar o app, também experimente campos vazios, nomes de tarefas longos e textos de tarefa duplicados.

Related posts