TutorialsPreview
Build a Todo App

Build a Todo AppLesson 2

LearnReferencebeginner12 minBuild a Todo App

Structure & style the app

Lesson 1 of 4 — the markup and CSS the rest of the course brings to life.

You will learn

Semantic structure for a small app and how a stylesheet turns bare markup into something you would actually use.

Prerequisites

None. If you can open a file, you can do this lesson.

01

Step 112 min

Lay down the markup and the look

GoalA static todo layout exists and looks finished — before a line of behaviour.

Good apps are built shape-first. We write the index.html structure (a form, a <ul>, a footer with filter buttons) and a styles.css that makes it calm and dark. Two rows are hard-coded so you can see the design; lesson 2 replaces them with real, JavaScript-driven items.

project · todo-app · Structure & style Open in Code
index.htmlHTML
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Todo</title>
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<main class="app">
<h1>Today</h1>
<form id="new-todo">
<input id="title" name="title" placeholder="What needs doing?" autocomplete="off" />
<button type="submit">Add</button>
</form>
<ul id="list" class="list">
<li><span class="check"></span><span class="title">Read the brief</span><button class="remove" aria-label="Delete">×</button></li>
<li class="done"><span class="check"></span><span class="title">Open the editor</span><button class="remove" aria-label="Delete">×</button></li>
</ul>
<footer class="bar">
<span id="count">1 left</span>
<span class="filters">
<button data-filter="all" class="active">All</button>
<button data-filter="active">Active</button>
<button data-filter="done">Done</button>
</span>
</footer>
</main>
<script src="app.js"></script>
</body>
</html>
styles.cssCSS
* { box-sizing: border-box; }
body {
margin: 0;
min-height: 100vh;
display: grid;
place-items: start center;
padding: 6vh 16px;
font-family: system-ui, -apple-system, sans-serif;
background: #0b0e14;
color: #e7ecf3;
}
.app { width: 100%; max-width: 460px; }
h1 { font-size: 22px; letter-spacing: -0.01em; margin: 0 0 16px; }
#new-todo { display: flex; gap: 8px; margin-bottom: 18px; }
#title {
flex: 1;
padding: 11px 14px;
border-radius: 10px;
border: 1px solid #232a36;
background: #11151c;
color: inherit;
font-size: 15px;
}
#title:focus { outline: none; border-color: #6ea8fe; }
#new-todo button {
padding: 0 18px;
border-radius: 10px;
border: 1px solid #2b3340;
background: #6ea8fe;
color: #0b0e14;
font-weight: 600;
cursor: pointer;
}
.list { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
.list li {
display: flex;
align-items: center;
gap: 12px;
padding: 12px 14px;
border-radius: 10px;
background: #11151c;
border: 1px solid #1c2330;
}
.check {
width: 18px;
height: 18px;
flex: none;
border-radius: 999px;
border: 1.5px solid #3a4456;
cursor: pointer;
}
.list li.done .check { background: #4ade80; border-color: #4ade80; }
.list li.done .title { color: #5b6675; text-decoration: line-through; }
.title { flex: 1; }
.remove {
border: none;
background: none;
color: #5b6675;
font-size: 20px;
line-height: 1;
cursor: pointer;
}
.remove:hover { color: #f87171; }
.bar {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 16px;
font-size: 13px;
color: #8b93a3;
}
.filters { display: flex; gap: 4px; }
.filters button {
border: 1px solid transparent;
background: none;
color: inherit;
padding: 4px 10px;
border-radius: 8px;
cursor: pointer;
}
.filters button.active { border-color: #2b3340; color: #e7ecf3; }
app.jsJAVASCRIPT
// Step 2 brings this page to life.
// For now the rows in index.html are hard-coded so you can see the design.
preview
The static app at step 1 — press Open in Code to edit it whole.

Before lesson 2

Try it

In Code, change the <h1> from "Today" to your own list name and re-run the preview.

Concepts covered · 1

More like this

A
Reference·beginner·15 min

Add todos with JavaScript

Wire the form so typing and pressing Add creates a real item. You will hold the todos in an array and render the list from it — the pattern every UI framework formalises later.

C
Reference·beginner·14 min

Complete & delete

Click a row to toggle it done; click the × to delete it. You will do it with a single listener on the list — event delegation — instead of one per row.

O
Reference·advanced·18 min

Orchestrate agents without the codebase rotting

Putting it together: context, guardrails, and a verification loop that lets you run coding agents across a real codebase without it drifting into an incoherent pile. This is the senior loop at full speed.

Liked this one?

Pass it on

Discussion

Be the first to ask

Your questions stay private with the team. We can pin answers to share with everyone.

Sign in to ask a question privately on this tutorial.

Sign in

No pinned answers yet for this tutorial.