In this tutorial, you’ll learn how to create a stylish To-Do list app using HTML, CSS, and JavaScript – no frameworks needed! It’s a beginner-friendly project with modern UI, progress tracking, and task editing.
What Will You Learn?
- How to add, edit, and delete tasks
- How to save tasks temporarily in memory
- How to show progress (like 2/5 tasks done)
- Basic DOM manipulation in JavaScript
- Responsive and dark UI design
Final Output Preview
Here’s what your final To-Do app will look like:

Step 1: Create Your Project Folder
Create a folder named todo-app
and inside it, create these files:
- index.html
- style.css
- script.js
Step 2: HTML Structure (index.html)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Todo Done</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div class="container">
<div class="header">
<h2>Todo Done</h2>
<p>Keep it up!</p>
<div class="progress-circle">
<span id="progressText">0/0</span>
<div class="bar"><div id="barFill"></div></div>
</div>
</div>
<div class="task-input">
<input type="text" id="taskInput" placeholder="Write your task" />
<button id="addTask">+</button>
</div>
<ul id="taskList"></ul>
</div>
<script src="script.js"></script>
</body>
</html>
Step 3: Styling with CSS (style.css)
body {
margin: 0;
font-family: "Segoe UI", sans-serif;
background-color: #0f1123;
color: #fff;
display: flex;
justify-content: center;
padding: 40px;
}
.container {
width: 350px;
background-color: #1c1f3a;
padding: 20px;
border-radius: 16px;
box-shadow: 0 0 15px rgba(0,0,0,0.5);
}
.header {
text-align: center;
}
.progress-circle {
margin-top: 10px;
}
.bar {
background: #2a2d49;
border-radius: 10px;
overflow: hidden;
height: 6px;
margin: 10px auto;
width: 80%;
}
#barFill {
height: 6px;
background: #1de9b6;
width: 0%;
transition: width 0.3s ease;
}
#progressText {
font-size: 18px;
color: #a2a9f7;
}
.task-input {
display: flex;
margin-top: 20px;
}
.task-input input {
flex: 1;
padding: 10px;
border-radius: 8px;
border: none;
background: #2c2f4d;
color: #fff;
}
.task-input button {
background-color: #636dff;
color: white;
border: none;
border-radius: 8px;
margin-left: 10px;
padding: 0 14px;
font-size: 20px;
cursor: pointer;
}
#taskList {
list-style: none;
padding: 0;
margin-top: 20px;
}
.task {
display: flex;
align-items: center;
background: #222548;
margin-bottom: 12px;
padding: 10px;
border-radius: 10px;
}
.task input[type="checkbox"] {
margin-right: 10px;
}
.task span {
flex: 1;
color: #c7caff;
text-decoration: none;
}
.task.done span {
text-decoration: line-through;
color: #1de9b6;
}
.task button {
background: none;
border: none;
cursor: pointer;
margin-left: 8px;
font-size: 16px;
color: #f77;
}
Step 4: Add JavaScript Logic (script.js)
const taskInput = document.getElementById('taskInput');
const addTaskBtn = document.getElementById('addTask');
const taskList = document.getElementById('taskList');
const progressText = document.getElementById('progressText');
const barFill = document.getElementById('barFill');
let tasks = [];
function updateProgress() {
const total = tasks.length;
const completed = tasks.filter(task => task.done).length;
progressText.textContent = `${completed}/${total}`;
barFill.style.width = total ? `${(completed / total) * 100}%` : '0%';
}
function renderTasks() {
taskList.innerHTML = '';
tasks.forEach((task, index) => {
const li = document.createElement('li');
li.className = 'task' + (task.done ? ' done' : '');
const checkbox = document.createElement('input');
checkbox.type = 'checkbox';
checkbox.checked = task.done;
checkbox.onclick = () => {
tasks[index].done = !tasks[index].done;
renderTasks();
};
const span = document.createElement('span');
span.textContent = task.text;
const editBtn = document.createElement('button');
editBtn.innerHTML = '✏️';
editBtn.onclick = () => {
const newText = prompt('Edit task:', task.text);
if (newText) {
tasks[index].text = newText;
renderTasks();
}
};
const deleteBtn = document.createElement('button');
deleteBtn.innerHTML = '🗑️';
deleteBtn.onclick = () => {
tasks.splice(index, 1);
renderTasks();
};
li.appendChild(checkbox);
li.appendChild(span);
li.appendChild(editBtn);
li.appendChild(deleteBtn);
taskList.appendChild(li);
});
updateProgress();
}
addTaskBtn.onclick = () => {
const taskText = taskInput.value.trim();
if (taskText) {
tasks.push({ text: taskText, done: false });
taskInput.value = '';
renderTasks();
}
};
renderTasks();