Skip to main content

Create a Simple To-Do List App with JavaScript, HTML, and CSS

Creating a basic JavaScript project is a great way to learn and apply your skills. Here's a step-by-step guide to help you build a simple yet functional JavaScript project. We'll create a To-Do List App, which is a common beginner project that covers important aspects of JavaScript like DOM manipulation, event handling, and basic functionality.

Project: To-Do List App

Project Overview

This simple to-do list app allows users to:

  • Add new tasks.
  • Mark tasks as complete.
  • Delete tasks.
  • Store tasks in local storage so they persist when the page is reloaded.

Step 1: Set up the Project Structure

Create a folder for your project, for example: todo-app.

Inside the todo-app folder, create the following files:

  • index.html — the HTML structure.
  • styles.css — the CSS for styling the app.
  • script.js — the JavaScript code to make the app interactive.

Your project structure should look like this:

todo-app/ ├── index.html ├── styles.css └── script.js

Step 2: HTML Structure (index.html)

This is where you'll define the structure of your to-do list app, including an input box for entering new tasks and a list to display them.

html
<!DOCTYPE html> 
<html lang="en"> 
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>To-Do List App</title>
<link rel="stylesheet" href="styles.css"> 
</head> 
<body> 
<div class="todo-container">
<h1>To-Do List</h1> 
<input type="text" id="todo-input" placeholder="Enter a new task">
<button id="add-button">Add Task</button>
<ul id="todo-list"></ul> 
</div> <script src="script.js">
</script> 
</body>
</html>

Explanation:

  • We have a title (<h1>) for the app.
  • An input field (<input>) for the user to type new tasks.
  • A button (<button>) that adds the task to the list when clicked.
  • An unordered list (<ul>) where the tasks will appear.
  • The JavaScript file is linked at the bottom (script.js).

Step 3: Styling the App (styles.css)

Now, let's add some basic styles to make our to-do list look neat.

body { font-family:
 Arial, sans-serif;
background-color: #f0f0f0;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0
}
.todo-container { background-color: #fff; padding: 20px; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
border-radius: 8px;
width: 300px;
text-align: center;
 } h1 { margin-bottom: 20px
#todo-input { width: 70%;
padding: 10px;
margin-right: 10px;
font-size: 16px; border-radius: 4px;
border: 1px solid #ccc;
 } #add-button { padding: 10px 15px;
font-size: 16px;
cursor: pointer;
border: none;
border-radius: 4px
background-color: #4CAF50;
color: white;
 } 
#add-button:hover {
background-color: #45a049;
 }
ul { list-style-type: none;
padding-left: 0;
 } li { padding: 10px;
border-bottom: 1px solid #ddd;
display: flex; 
justify-content: space-between;
align-items: center;
 } li.complete { text-decoration: line-through; color: #888;
} button.delete-btn { background-color: #e74c3c;
color: white; 
border: none;
padding: 5px 10px;
border-radius: 4px;
cursor: pointer;
 } 
button.delete-btn:hover{ background-color: #c0392b;
 }

Explanation:

  • The body is styled to center the app on the screen.
  • The .todo-container class adds padding and a shadow to the container.
  • The input and button elements are styled to be user-friendly.
  • The list items (li) have spacing, a bottom border, and a hover effect.
  • Tasks that are marked as "complete" have a line-through and lighter text color.
  • A delete button (.delete-btn) is styled with red color and a hover effect.

Step 4: JavaScript Functionality (script.js)

Now, let's add the functionality to make our to-do list interactive.

javascript
// Get references to HTML elements const addButton = document.getElementById('add-button'); const todoInput = document.getElementById('todo-input'); const todoList =
document.getElementById('todo-list'); // Load existing tasks from local storage when the page loads document.addEventListener('DOMContentLoaded', loadTasks);
 addButton.addEventListener('click', function () { const taskText = todoInput.value.trim(); if (taskText !== '') { addTask(taskText);
 todoInput.value = ''; // Clear the input field after adding the task } });
// Function to add a task to the list function addTask(taskText) { // Create a new list item const li = document.createElement('li');
 li.textContent = taskText;
// Create a delete button const deleteButton = document.createElement('button');
 deleteButton.textContent = 'Delete';
 deleteButton.classList.add('delete-btn'); 
// Attach delete functionality deleteButton.addEventListener('click', function () { li.remove(); saveTasks(); // Save tasks after deletion });
// Toggle task completion when clicked li.addEventListener('click', function () { li.classList.toggle('complete');saveTasks();
// Save tasks after toggling completion });
// Append the delete button to the list item li.appendChild(deleteButton); 
// Append the list item to the todo list todoList.appendChild(li);
// Save the tasks to local storage saveTasks(); }
// Function to save tasks to local storage function saveTasks() { const tasks = []; const allTasks = document.querySelectorAll('li');
 allTasks.forEach(task => { tasks.push({ text: task.textContent.replace('Delete', '').trim(), completed: task.classList.contains('complete') }); });
localStorage.setItem('tasks', JSON.stringify(tasks)); }
// Function to load tasks from local storage function loadTasks() { const tasks = JSON.parse(localStorage.getItem('tasks')) || [];
 tasks.forEach(task => { const li = document.createElement('li');
 li.textContent = task.text;
// Add the completed class if the task is marked as completed if (task.completed) { li.classList.add('complete'); }
// Create a delete button for each task const deleteButton = document.createElement('button'); deleteButton.textContent = 'Delete';
 deleteButton.classList.add('delete-btn');
 deleteButton.addEventListener('click', function () { li.remove(); saveTasks();
// Save tasks after deletion }); li.appendChild(deleteButton); todoList.appendChild(li); }); }

Explanation:

  1. Adding a Task:

    • The addTask function creates a new list item (li) with the task text and a delete button.
    • When the delete button is clicked, the task is removed from the list and the tasks are saved in local storage.
    • When a task is clicked, it toggles the complete class (line-through effect), and the tasks are saved again.
  2. Saving and Loading Tasks:

    • Tasks are stored in the browser’s localStorage so they persist across page reloads.
    • The saveTasks function saves the list of tasks in the browser's local storage as a JSON string.
    • The loadTasks function loads tasks from local storage when the page is reloaded and creates list items based on the saved data.

Step 5: Test Your App

  1. Open index.html in your browser.
  2. Try adding new tasks by typing in the input field and clicking "Add Task."
  3. Mark tasks as complete by clicking on them.
  4. Delete tasks by clicking the "Delete" button.
  5. Refresh the page to make sure the tasks persist (you’ll see tasks that were added, completed, or deleted).

Output





Summary

You’ve now created a simple To-Do List App using HTML, CSS, and JavaScript. The app:

  • Allows users to add, mark as complete, and delete tasks.
  • Stores tasks in local storage so they persist even after a page reload.

You can expand on this project by adding more features like:

  • Editing tasks.
  • Sorting tasks.
  • Adding categories or tags to tasks.

This is a great starting point for learning JavaScript and creating more interactive applications