Todo App Interface Project

Create a modern todo app with task management and filtering capabilities.

Project Overview

This project will guide you through creating a modern todo app interface using CSS. You'll learn to design task lists, input forms, and interactive elements.

  • Task input and display
  • Complete/incomplete states
  • Filter and search functionality
  • Responsive design

Estimated Time

Beginner: 1-2 hours | Intermediate: 1 hour

Difficulty Level: Beginner to Intermediate

Step-by-Step Implementation

1 Create the HTML Structure

HTML Example

<div class="todo-app">
    <header class="todo-header">
        <h1>My Todo List</h1>
        <form class="todo-form">
            <input type="text" placeholder="Add a new task..." class="todo-input">
            <button type="submit" class="todo-btn">Add</button>
        </form>
    </header>
    <div class="todo-filters">
        <button class="filter-btn active" data-filter="all">All</button>
        <button class="filter-btn" data-filter="active">Active</button>
        <button class="filter-btn" data-filter="completed">Completed</button>
    </div>
    <ul class="todo-list">
        <li class="todo-item">
            <input type="checkbox" class="todo-checkbox">
            <span class="todo-text">Learn CSS Grid</span>
            <button class="todo-delete"><i class="fas fa-trash"></i></button>
        </li>
        <li class="todo-item completed">
            <input type="checkbox" class="todo-checkbox" checked>
            <span class="todo-text">Build responsive layout</span>
            <button class="todo-delete"><i class="fas fa-trash"></i></button>
        </li>
    </ul>
    <div class="todo-stats">
        <span>3 tasks remaining</span>
        <button class="clear-completed">Clear completed</button>
    </div>
</div>

2 Add CSS for Layout & Design

Basic CSS Example

.todo-app {
    max-width: 600px;
    margin: 2rem auto;
    background: white;
    border-radius: 20px;
    box-shadow: 0 10px 30px rgba(0,0,0,0.1);
    overflow: hidden;
}
.todo-header {
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    color: white;
    padding: 2rem;
    text-align: center;
}
.todo-header h1 {
    margin-bottom: 1.5rem;
    font-size: 2rem;
}
.todo-form {
    display: flex;
    gap: 1rem;
}
.todo-input {
    flex: 1;
    padding: 1rem;
    border: none;
    border-radius: 10px;
    font-size: 1rem;
    outline: none;
}
.todo-btn {
    background: rgba(255,255,255,0.2);
    color: white;
    border: none;
    padding: 1rem 2rem;
    border-radius: 10px;
    cursor: pointer;
    font-weight: 600;
    transition: background 0.2s;
}
.todo-btn:hover {
    background: rgba(255,255,255,0.3);
}
.todo-filters {
    display: flex;
    justify-content: center;
    gap: 1rem;
    padding: 1.5rem;
    background: #f8f9fa;
}
.filter-btn {
    background: white;
    border: 2px solid #e9ecef;
    padding: 0.5rem 1rem;
    border-radius: 20px;
    cursor: pointer;
    transition: all 0.2s;
}
.filter-btn.active,
.filter-btn:hover {
    background: #667eea;
    color: white;
    border-color: #667eea;
}
.todo-list {
    list-style: none;
    padding: 0;
    margin: 0;
}
.todo-item {
    display: flex;
    align-items: center;
    padding: 1rem 1.5rem;
    border-bottom: 1px solid #f0f0f0;
    transition: background 0.2s;
}
.todo-item:hover {
    background: #f8f9fa;
}
.todo-checkbox {
    margin-right: 1rem;
    transform: scale(1.2);
}
.todo-text {
    flex: 1;
    font-size: 1rem;
    color: #333;
}
.todo-item.completed .todo-text {
    text-decoration: line-through;
    color: #999;
}
.todo-delete {
    background: none;
    border: none;
    color: #e74c3c;
    cursor: pointer;
    padding: 0.5rem;
    border-radius: 5px;
    transition: background 0.2s;
}
.todo-delete:hover {
    background: #ffe6e6;
}
.todo-stats {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 1.5rem;
    background: #f8f9fa;
    color: #666;
}
.clear-completed {
    background: none;
    border: none;
    color: #e74c3c;
    cursor: pointer;
    text-decoration: underline;
}
.clear-completed:hover {
    color: #c0392b;
}
@media (max-width: 768px) {
    .todo-app {
        margin: 1rem;
    }
    .todo-form {
        flex-direction: column;
    }
    .todo-filters {
        flex-wrap: wrap;
    }
    .todo-stats {
        flex-direction: column;
        gap: 1rem;
        text-align: center;
    }
}

3 Add Interactivity (JS)

Todo App Logic (JS)

class TodoApp {
    constructor() {
        this.todos = [];
        this.filter = 'all';
        this.init();
    }
    
    init() {
        this.bindEvents();
        this.render();
    }
    
    bindEvents() {
        document.querySelector('.todo-form').addEventListener('submit', (e) => {
            e.preventDefault();
            this.addTodo();
        });
        
        document.querySelector('.todo-list').addEventListener('click', (e) => {
            if (e.target.classList.contains('todo-checkbox')) {
                this.toggleTodo(e.target);
            } else if (e.target.closest('.todo-delete')) {
                this.deleteTodo(e.target.closest('.todo-item'));
            }
        });
        
        document.querySelectorAll('.filter-btn').forEach(btn => {
            btn.addEventListener('click', (e) => {
                this.setFilter(e.target.dataset.filter);
            });
        });
    }
    
    addTodo() {
        const input = document.querySelector('.todo-input');
        const text = input.value.trim();
        if (text) {
            this.todos.push({ id: Date.now(), text, completed: false });
            input.value = '';
            this.render();
        }
    }
    
    toggleTodo(checkbox) {
        const todoItem = checkbox.closest('.todo-item');
        const todoId = parseInt(todoItem.dataset.id);
        const todo = this.todos.find(t => t.id === todoId);
        if (todo) {
            todo.completed = !todo.completed;
            this.render();
        }
    }
    
    deleteTodo(todoItem) {
        const todoId = parseInt(todoItem.dataset.id);
        this.todos = this.todos.filter(t => t.id !== todoId);
        this.render();
    }
    
    setFilter(filter) {
        this.filter = filter;
        document.querySelectorAll('.filter-btn').forEach(btn => {
            btn.classList.toggle('active', btn.dataset.filter === filter);
        });
        this.render();
    }
    
    render() {
        const todoList = document.querySelector('.todo-list');
        const filteredTodos = this.filter === 'all' ? this.todos :
                             this.filter === 'active' ? this.todos.filter(t => !t.completed) :
                             this.todos.filter(t => t.completed);
        
        todoList.innerHTML = filteredTodos.map(todo => `
            <li class="todo-item ${todo.completed ? 'completed' : ''}" data-id="${todo.id}">
                <input type="checkbox" class="todo-checkbox" ${todo.completed ? 'checked' : ''}>
                <span class="todo-text">${todo.text}</span>
                <button class="todo-delete"><i class="fas fa-trash"></i></button>
            </li>
        `).join('');
        
        const remaining = this.todos.filter(t => !t.completed).length;
        document.querySelector('.todo-stats span').textContent = 
            `${remaining} task${remaining !== 1 ? 's' : ''} remaining`;
    }
}

new TodoApp();

4 Test Responsiveness & Accessibility

Checklist

  • Test on mobile, tablet, and desktop
  • Check keyboard navigation and focus states
  • Use semantic HTML for todo elements
  • Ensure color contrast is accessible
  • Validate your HTML and CSS

Project Checklist

Back to Calculator Interface Next: Chat Interface