Complete To-Do List App with Dark Mode - Full Code Walkthrough
Here's the complete implementation of your modern To-Do List application with dark mode functionality, including all HTML, CSS, and JavaScript code.
In this step-by-step tutorial, i will create a feature-rich To-Do List app with:
✅ Dark/light mode toggle (auto-saves preference)
✅ Add, edit, delete, and mark tasks complete
✅ "Delete All" with confirmation
✅ Keyboard support (Enter key to add tasks)
✅ Persistent storage (tasks survive page refresh)
📱 App Preview (Live Demo)
Light Mode | Dark Mode |
---|---|
![]() |
![]() |
📁 File Structure
📁 todo-app/
├── 📄 index.html
├── 📄 style.css
├── 📄 script.js
└── 📁 images/
├── 📄 checked.png
├── 📄 delete.png
├── 📄 to-do-list-icon.png
└── 📄 unchecked.png
🖥️ HTML (index.html)
</span>
lang="en">
charset="UTF-8" />
name="viewport" content="width=device-width, initial-scale=1.0" />
To-Do List App
rel="stylesheet" href="style.css" />
class="theme-toggle-container">
class="theme-toggle" id="theme-toggle">
class="toggle-icon">🌙
class="toggle-text">Dark Mode
class="container">
class="todo-app">
To-Do-List
src="images/to-do-list-icon.png" class="todo-icon" />
class="row">
type="text" id="input-box" placeholder="Add your text" />
id="add-btn" onclick="addTask()" disabled>Add
id="list-container">
id="delete-all" class="delete-all-btn">Delete All
<span class="na">src="script.js">
Enter fullscreen mode
Exit fullscreen mode
🎨 CSS (style.css)
@import url("https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap");
:root {
/* Light Mode Colors */
--primary-bg: linear-gradient(
to right,
#e3a1a1,
#b0c4c4,
#4fc2dd,
#a897d6,
#70c0d3
);
--app-bg: #ffffff;
--text-color: #002655;
--input-bg: #dfe2e5;
--add-btn: #ff4d3a;
--delete-all-btn: linear-gradient(to right, #ff5e6f, #b2e4ff, #ff5e6f);
--list-item-bg: #ffffff;
--checked-item: #666;
/* Dark Mode Colors */
--dark-primary-bg: linear-gradient(to right, #101d26, #1c3544, #284c5e);
--dark-app-bg: #1c1c1c;
--dark-text-color: #f5f5f5;
--dark-input-bg: #333;
--dark-add-btn: #e65a5a;
--dark-delete-all-btn: linear-gradient(to right, #ff3b5c, #ff4825);
--dark-list-item-bg: #333;
--dark-checked-item: #bbb;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: "Poppins", sans-serif;
transition: background 0.3s, color 0.3s;
}
body {
transition: background 0.5s ease, color 0.5s ease;
}
body.dark-mode {
--primary-bg: var(--dark-primary-bg);
--app-bg: var(--dark-app-bg);
--text-color: var(--dark-text-color);
--input-bg: var(--dark-input-bg);
--add-btn: var(--dark-add-btn);
--delete-all-btn: var(--dark-delete-all-btn);
--list-item-bg: var(--dark-list-item-bg);
--checked-item: var(--dark-checked-item);
}
.container {
width: 100%;
min-height: 100vh;
background: var(--primary-bg);
padding: 10px;
}
.todo-app {
width: 100%;
max-width: 540px;
background: var(--app-bg);
margin: 100px auto 20px;
padding: 40px 30px 70px;
border-radius: 10px;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
}
.todo-app h2 {
color: var(--text-color);
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 20px;
}
.todo-app h2 img.todo-icon {
width: 60px;
height: 60px;
margin-left: 10px;
}
.row {
display: flex;
align-items: center;
justify-content: space-between;
background: var(--input-bg);
border-radius: 30px;
padding-left: 20px;
margin-bottom: 25px;
}
input {
flex: 1;
outline: none;
border: none;
background: transparent;
padding: 10px;
font-size: 14px;
color: var(--text-color);
}
button {
border: none;
outline: none;
padding: 16px 50px;
background: var(--add-btn);
color: #fff;
font-size: 16px;
cursor: pointer;
border-radius: 40px;
font-weight: 500;
}
/* Disable button style */
button:disabled {
background: gray;
cursor: not-allowed;
}
/* To-Do List Items */
ul li {
list-style: none;
font-size: 17px;
padding: 12px 8px 12px 50px;
user-select: none;
cursor: pointer;
position: relative;
background: var(--list-item-bg);
margin-bottom: 8px;
color: var(--text-color);
border-radius: 8px;
}
/* Checkbox icon before list items */
ul li::before {
content: "";
position: absolute;
height: 28px;
width: 28px;
border-radius: 50%;
background-image: url(images/unchecked.png);
background-size: cover;
background-position: center;
top: 12px;
left: 8px;
}
/* Checked list item */
ul li.checked {
color: var(--checked-item);
text-decoration: line-through;
}
/* Change checkbox image when checked */
ul li.checked::before {
background-image: url(images/checked.png);
}
/* Delete icon */
ul li .delete-icon {
position: absolute;
right: 10px;
top: 50%;
transform: translateY(-50%);
width: 20px;
height: 20px;
cursor: pointer;
opacity: 0.7;
transition: opacity 0.2s;
filter: var(--icon-filter);
}
ul li .delete-icon:hover {
opacity: 1;
}
/* Delete All Button */
.delete-all-btn {
background: var(--delete-all-btn);
margin: 20px auto 0;
padding: 15px 45px;
text-align: center;
transition: 0.5s;
background-size: 200% auto;
color: white;
border-radius: 10px;
display: block;
border: none;
font-weight: 500;
cursor: pointer;
}
.delete-all-btn:hover {
background-position: right center;
}
/* Dark Mode Specific */
body.dark-mode .delete-icon {
filter: invert(1);
}
body.dark-mode ul li {
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
}
/* Theme Toggle Button - Top Left */
.theme-toggle-container {
position: absolute;
top: 20px;
left: 20px;
}
.theme-toggle {
background: linear-gradient(to right, #6a11cb 0%, #2575fc 100%);
color: white;
border: none;
padding: 12px 25px;
border-radius: 30px;
cursor: pointer;
font-size: 16px;
font-weight: 500;
transition: all 0.3s ease;
}
.theme-toggle:hover {
transform: translateY(-2px);
}
body.dark-mode .theme-toggle {
background: linear-gradient(to right, #f5af19 0%, #f12711 100%);
color: #fff;
}
Enter fullscreen mode
Exit fullscreen mode
⚡ JavaScript (script.js)
const inputBox = document.getElementById("input-box");
const listContainer = document.getElementById("list-container");
const deleteAllBtn = document.getElementById("delete-all");
const themeToggle = document.getElementById("theme-toggle");
const toggleIcon = themeToggle.querySelector(".toggle-icon");
const toggleText = themeToggle.querySelector(".toggle-text");
const addButton = document.getElementById("add-btn");
// Initialize theme
function initTheme() {
const isDark = localStorage.getItem("darkMode") === "true";
if (isDark) document.body.classList.add("dark-mode");
updateThemeButton(isDark);
}
// Update theme button
function updateThemeButton(isDark) {
toggleIcon.textContent = isDark ? "☀️" : "🌙";
toggleText.textContent = isDark ? "Light Mode" : "Dark Mode";
}
// Toggle theme
themeToggle.addEventListener("click", () => {
const isDark = document.body.classList.toggle("dark-mode");
localStorage.setItem("darkMode", isDark);
updateThemeButton(isDark);
});
// Disable Add button when input is empty
inputBox.addEventListener("input", () => {
addButton.disabled = inputBox.value.trim() === "";
});
// Add new task
function addTask() {
if (inputBox.value.trim() === "") {
alert("Please enter a task");
return;
}
const li = document.createElement("li");
li.textContent = inputBox.value.trim();
const deleteIcon = document.createElement("img");
deleteIcon.src = "images/delete.png";
deleteIcon.className = "delete-icon";
deleteIcon.alt = "Delete task";
li.appendChild(deleteIcon);
listContainer.appendChild(li);
inputBox.value = "";
addButton.disabled = true; // Disable button after adding task
saveData();
updateDeleteAllVisibility();
}
// Handle list interactions (check/uncheck and delete)
listContainer.addEventListener("click", function (e) {
if (e.target.tagName === "LI") {
e.target.classList.toggle("checked");
saveData();
} else if (e.target.classList.contains("delete-icon")) {
e.target.parentElement.remove();
saveData();
updateDeleteAllVisibility();
}
});
// Delete all tasks
deleteAllBtn.addEventListener("click", function () {
if (listContainer.children.length === 0) return;
if (confirm("Are you sure you want to delete ALL tasks?")) {
listContainer.innerHTML = "";
saveData();
updateDeleteAllVisibility();
}
});
// Save data to localStorage
function saveData() {
localStorage.setItem("data", listContainer.innerHTML);
}
// Load tasks from localStorage
function showTask() {
listContainer.innerHTML = localStorage.getItem("data") || "";
updateDeleteAllVisibility();
}
// Show/hide Delete All button based on tasks
function updateDeleteAllVisibility() {
deleteAllBtn.style.display =
listContainer.children.length > 0 ? "block" : "none";
}
// Initialize app
initTheme();
showTask();
// Add task on Enter key press
inputBox.addEventListener("keypress", function (e) {
if (e.key === "Enter") {
addTask();
}
});
Enter fullscreen mode
Exit fullscreen mode
🌟 Key Features Explained
Dark/Light Mode Toggle
Uses CSS variables for easy theme switching
Saves user preference in localStorage
Task Management
Add tasks by clicking "Add" or pressing Enter
Mark tasks as complete by clicking them
Delete individual tasks with the trash icon
"Delete All" button with confirmation
Data Persistence
All tasks are saved to localStorage automatically
Tasks persist even after closing/reopening the browser
User Experience
"Add" button disabled when input is empty
Smooth transitions between themes
Responsive design works on all devices
🚀 How to Use This App
Download all files and images
Open index.html in your browser
Start adding tasks!
Toggle between light/dark mode using the button
You can find the complete project on GitHub:
🔗 GitHub Repository