To-Do List Design Using HTML, CSS, and JavaScript

To-Do List Design Using HTML, CSS, and JavaScript

To-Do List Design Using HTML, CSS, and JavaScript

Create a modern, responsive to-do list using HTML, CSS, and JavaScript, featuring task input, completion toggles, deletion, and local storage for persistence. This implementation focuses on clean design, accessible interactions, and maintainable code structure, ideal for task management.

    Prerequisites

    • Basic HTML, CSS, and JavaScript knowledge
    • A code editor (e.g., VS Code)

    Part 1: To-Do List Design

    Step 1: HTML Structure (index.html)

    Create a semantic HTML structure for the to-do list with an input form and a list for tasks.

    <div class="todo-container" role="region" aria-label="To-Do List">
        <div class="todo-header">
            <input type="text" class="todo-input" placeholder="Add a new task..." aria-label="New task input">
            <button class="todo-add-btn">Add</button>
        </div>
        <ul class="todo-list" id="todoList"></ul>
    </div>

    Step 2: Core CSS Implementation (styles.css)

    Style the to-do list with a clean layout, interactive states, and responsive design.

    :root {
        --gray-900: #111827;
        --gray-700: #374151;
        --gray-200: #e5e7eb;
        --gray-100: #f3f4f6;
        --white: #ffffff;
        --primary-600: #2563eb;
        --primary-500: #3b82f6;
        --spacing-xs: 4px;
        --spacing-sm: 8px;
        --spacing-md: 12px;
        --spacing-lg: 16px;
        --radius-sm: 4px;
        --radius-md: 6px;
        --transition: 0.2s ease;
        --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
        --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
        --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    }
    
    .todo-container {
        max-width: 500px;
        width: 100%;
        background: var(--white);
        border-radius: var(--radius-md);
        box-shadow: var(--shadow-md);
        padding: var(--spacing-lg);
    }
    
    .todo-header {
        display: flex;
        gap: var(--spacing-sm);
        margin-bottom: var(--spacing-md);
    }
    
    .todo-input {
        flex: 1;
        padding: var(--spacing-sm);
        font-size: 0.9375rem;
        border: 1px solid var(--gray-200);
        border-radius: var(--radius-sm);
        transition: border-color var(--transition);
    }
    
    .todo-input:focus {
        outline: none;
        border-color: var(--primary-500);
        box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.15);
    }
    
    .todo-add-btn {
        padding: var(--spacing-sm) var(--spacing-md);
        background: var(--primary-500);
        color: var(--white);
        border: none;
        border-radius: var(--radius-sm);
        font-size: 0.9375rem;
        font-weight: 500;
        cursor: pointer;
        transition: background var(--transition);
    }
    
    .todo-add-btn:hover {
        background: var(--primary-600);
    }
    
    .todo-add-btn:focus {
        outline: none;
        box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.15);
    }
    
    .todo-list {
        list-style: none;
        padding: 0;
        margin: 0;
    }
    
    .todo-item {
        display: flex;
        align-items: center;
        gap: var(--spacing-sm);
        padding: var(--spacing-sm) 0;
        border-bottom: 1px solid var(--gray-200);
    }
    
    .todo-item:last-child {
        border-bottom: none;
    }
    
    .todo-checkbox {
        width: 18px;
        height: 18px;
        cursor: pointer;
    }
    
    .todo-text {
        flex: 1;
        font-size: 0.937,5rem;
        color: var(--gray-900);
    }
    
    .todo-text.completed {
        text-decoration: line-through;
        color: var(--gray-700);
    }
    
    .todo-delete-btn {
        background: none;
        border: none;
        color: var(--gray-700);
        font-size: 1rem;
        cursor: pointer;
        padding: var(--spacing-xs);
        transition: color var(--transition);
    }
    
    .todo-delete-btn:hover {
        color: var(--gray-900);
    }
    
    .todo-delete-btn:focus {
        outline: none;
        box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.15);
    }
    
    @media (max-width: 640px) {
        .todo-container {
            width: 95%;
        }
    
        .todo-input {
            font-size: 0.875rem;
        }
    
        .todo-add-btn {
            padding: var(--spacing-xs) var(--spacing-sm);
            font-size: 0.875rem;
        }
    
        .todo-text {
            font-size: 0.875rem;
        }
    }
    

    Step 3: JavaScript Implementation (script.js)

    Add JavaScript to handle adding, completing, and deleting tasks, with local storage for persistence.

    document.addEventListener('DOMContentLoaded', () => {
        const todoInput = document.querySelector('.todo-input');
        const todoAddBtn = document.querySelector('.todo-add-btn');
        const todoList = document.querySelector('.todo-list');
    
        // Load tasks from local storage
        const tasks = JSON.parse(localStorage.getItem('tasks')) || [];
    
        // Render tasks
        const renderTasks = () => {
            todoList.innerHTML = '';
            tasks.forEach((task, index) => {
                const li = document.createElement('li');
                li.className = 'todo-item';
                li.innerHTML = `
                    
                    ${task.text}
                    
                `;
                todoList.appendChild(li);
    
                // Handle checkbox toggle
                const checkbox = li.querySelector('.todo-checkbox');
                checkbox.addEventListener('change', () => {
                    tasks[index].completed = checkbox.checked;
                    saveTasks();
                    renderTasks();
                });
    
                // Handle delete
                const deleteBtn = li.querySelector('.todo-delete-btn');
                deleteBtn.addEventListener('click', () => {
                    tasks.splice(index, 1);
                    saveTasks();
                    renderTasks();
                });
            });
        };
    
        // Save tasks to local storage
        const saveTasks = () => {
            localStorage.setItem('tasks', JSON.stringify(tasks));
        };
    
        // Add new task
        todoAddBtn.addEventListener('click', () => {
            const text = todoInput.value.trim();
            if (text) {
                tasks.push({ text, completed: false });
                saveTasks();
                renderTasks();
                todoInput.value = '';
                todoInput.focus();
            }
        });
    
        // Add task on Enter key
        todoInput.addEventListener('keydown', (e) => {
            if (e.key === 'Enter') {
                todoAddBtn.click();
            }
        });
    
        // Initial render
        renderTasks();
    });
    

    Explanation

    • Layout: A container holds a header with an input and add button, and a list for tasks. Each task includes a checkbox, text, and delete button.
    • Interactivity: JavaScript enables adding tasks via button or Enter key, toggling completion with checkboxes, and deleting tasks. Tasks persist in local storage.
    • Styling: Tasks are styled with flexbox for alignment, borders for separation, and hover/focus effects. Completed tasks have a strikethrough.
    • Visual Feedback: The add button darkens on hover (--primary-600); focus states use a blue ring; delete buttons darken on hover.
    • Responsiveness: A media query (@media (max-width: 640px)) adjusts widths and font sizes for mobile usability.
    • Accessibility: role="region", aria-label on inputs and buttons, and focus management ensure screen reader compatibility. Keyboard support includes Enter key for adding tasks.
    UX Tip: Ensure the to-do list is intuitive with clear input and action buttons. Use ARIA attributes and test keyboard navigation for accessibility. Consider adding features like task editing or filtering in production.

    Accessibility Features

    • Use role="region" and aria-label for semantic structure
    • Ensure high contrast ratios for text and buttons (4.5:1 minimum)
    • Support keyboard navigation with focus states and Enter key
    • Provide descriptive aria-label for interactive elements

    Golden Rules

    • Use CSS variables for consistent theming
    • Implement focus states and ARIA for accessibility
    • Provide clear visual feedback for interactions
    • Optimize for mobile with responsive design

    Conclusion

    A professional to-do list should maintain visual clarity, provide intuitive interactions, remain responsive, and follow accessibility guidelines. This solution uses HTML, CSS, and JavaScript for a polished task manager with persistent storage. Experiment with features like task categories, due dates, or styling to match your design. Test across devices and browsers for usability. Feel free to leave comments with any questions or suggestions!

    Comments