Create a Responsive To-Do List App using HTML, CSS, and JavaScript (Source Code)


By Faraz -

Learn how to create a responsive to-do list app using HTML, CSS, and JavaScript. Manage tasks seamlessly across devices!

Create a Responsive To-Do List App using HTML, CSS, and JavaScript.jpg

Table of Contents

  1. Project Introduction
  2. HTML Code
  3. CSS Code
  4. JavaScript Code
  5. Preview
  6. Conclusion

In today's fast-paced world, staying organized and managing our daily tasks efficiently has become more crucial than ever. With numerous responsibilities demanding our attention, a well-structured to-do list has emerged as an indispensable tool for keeping track of our activities, boosting productivity, and maintaining a sense of accomplishment. However, in a digital landscape that extends across various devices and screen sizes, it's imperative that our to-do list isn't confined to a single platform. This is where the concept of a responsive to-do list comes into play.

A responsive to-do list ensures that your task management companion is as adaptable as you are. Whether you're meticulously planning on your desktop, quickly checking off completed items on your tablet, or adding new tasks on the go from your smartphone, a responsive to-do list seamlessly tailors itself to your preferred device, enhancing your ability to manage tasks effectively regardless of your location or the tools at hand.

In this comprehensive tutorial, we'll embark on a journey to create our very own responsive to-do list application. We'll harness the combined power of HTML, CSS, and JavaScript to craft a dynamic and user-friendly interface that not only captures and displays your tasks but also adapts intelligently to the screen size you're using. By following along with each step of this guide, you'll gain invaluable insights into front-end web development, understand the nuances of responsive design, and acquire the skills needed to bring your creative ideas to life in the digital realm.

So, whether you're a budding web developer eager to expand your skill set, a task management enthusiast seeking a tailored solution, or simply someone who loves to learn by doing, this tutorial is your gateway to building a responsive to-do list that seamlessly integrates into your daily routine. Let's dive in and unlock the potential of creating a personalized, cross-device task management experience like never before.

Code by: Cassie Evans

Source Code

Step 1 (HTML Code):

To get started, we will first need to create a basic HTML file. In this file, we will include the main structure for our to-do list.

After creating the files just paste the following codes into your file. Make sure to save your HTML document with a .html extension, so that it can be properly viewed in a web browser.

Let's break down the different sections and elements:

1. <!DOCTYPE html>: This declaration specifies that the document is an HTML5 document type.

2. <html lang="en">: The opening tag of the HTML document, with the "lang" attribute set to "en" (English), indicating the language of the document's content.

3. <head>: The head section of the HTML document, which contains metadata and links to external resources.

4. <title>To-Do List</title>: Sets the title of the web page displayed in the browser's title bar or tab.

5. <meta charset="UTF-8" />: Specifies the character encoding for the document (UTF-8, which supports a wide range of characters and symbols).

6. <meta name="viewport" content="width=device-width" />: Configures the viewport width to match the device's width, providing better responsiveness for various screen sizes.

7. <link rel="stylesheet" href="styles.css" />: Links to an external CSS file named "styles.css" to apply styling to the HTML elements.

8. <body>: The body section of the HTML document, which contains the visible content of the web page.

9. <section class="container">: A section element with the class "container," used to group related content.

10. <div class="heading">: A division element with the class "heading" for the title and image at the top of the page.

11. <img class="heading__img" src="...">: An image element with the class "heading__img" that displays an image of a laptop.

12. <h1 class="heading__title">To-Do List</h1>: A heading level 1 element with the class "heading__title," displaying the text "To-Do List."

13. <form class="form">: A form element with the class "form" for user input.

14. <label class="form__label" for="todo">...: A label for the input field, indicating what the user should input.

15. <input class="form__input" type="text" id="todo" name="to-do" size="30" required>: An input field for the user to enter their to-do item. It has a class "form__input," a unique ID "todo," a name "to-do," a size of 30 characters, and is required.

16. <button class="button"><span>Submit</span></button>: A button element with the class "button," containing the text "Submit."

17. <div>: A division element containing an unordered list (ul) for displaying the to-do list items.

18. <ul class="toDoList">: An unordered list with the class "toDoList," where to-do list items will be added dynamically.

19. <script src="script.js"></script>: Links to an external JavaScript file named "script.js" for adding interactivity and functionality to the web page.

This is the basic structure of our to-do list using HTML, and now we can move on to styling it using CSS.

Step 2 (CSS Code):

Once the basic HTML structure of the to-do list is in place, the next step is to add styling to the to-do list using CSS.

Next, we will create our CSS file. In this file, we will use some basic CSS rules to style our to-do list.

1. @import: This line imports a Google Fonts stylesheet, making the "Gochi Hand" font available for use on the page.

2. body: This block of code styles the entire body of the webpage. It sets the background color, minimum height, padding, box-sizing, and various other properties to center the content both horizontally and vertically. It also sets the text color and font family to "Gochi Hand" for a cursive font style.

3. @media only screen and (min-width: 500px): Inside this media query, the minimum height of the body is adjusted to take up the full viewport height (100vh) when the screen width is at least 500px.

4. .container: This class styles a container element. It sets the width, minimum and maximum width, background color, border-radius, box shadow, and padding. It also adds a radial gradient background pattern.

5. .heading: This class styles a container for the heading. It aligns the content both horizontally and vertically and adds a margin at the bottom.

6. .heading__title: This class styles the heading title, giving it a rotated appearance, rounded border, background color, and font size. Inside the media query, the font size is increased for larger screens.

7. .form__label: This class styles labels for form inputs, adding a margin at the bottom.

8. .form__input: This class styles form input fields. It sets the box-sizing, background color, padding, border radius, and border style. The focus state adjusts the border color.

9. @media only screen and (min-width: 500px): Inside this media query, the width of the input fields are adjusted for larger screens.

10. .button: This class styles a button element. It sets various properties for the button appearance, including padding, rotation, font family, border radius, box shadow, and background image.

11. .button span: This styles the text inside the button, giving it a background color, padding, border, and border-radius.

12. .button:active, .button:focus: These styles define the appearance of the button when it is active (clicked) or focused (selected).

13. .toDoList: This class styles a to-do list on the webpage, aligning the text to the left.

14. .toDoList li: This class styles individual list items in the to-do list, adding padding.

15. .toDoList li:hover: This style is applied when hovering over a list item, giving it a line-through decoration with a wavy effect and changing the color.

This will give our to-do list an upgraded presentation. Create a CSS file with the name styles.css and paste the given codes into your CSS file. Remember that you must create a file with the .css extension.

@import url("");
body {
  background-color: #a39bd2;
  min-height: 70vh;
  padding: 1rem;
  box-sizing: border-box;
  display: flex;
  justify-content: center;
  align-items: center;
  color: #494a4b;
  font-family: "Gochi Hand", cursive;
  text-align: center;
  font-size: 130%;

@media only screen and (min-width: 500px) {
  body {
    min-height: 100vh;
.container {
  width: 100%;
  height: auto;
  min-height: 500px;
  max-width: 500px;
  min-width: 250px;
  background: #f1f5f8;
  background-image: radial-gradient(#bfc0c1 7.2%, transparent 0);
  background-size: 25px 25px;
  border-radius: 20px;
  box-shadow: 4px 3px 7px 2px #00000040;
  padding: 1rem;
  box-sizing: border-box;

.heading {
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 1rem;

.heading__title {
  transform: rotate(2deg);
  padding: 0.2rem 1.2rem;
  border-radius: 20% 5% 20% 5%/5% 20% 25% 20%;
  background-color: rgba(0, 255, 196, 0.7);
  font-size: 1.5rem;

@media only screen and (min-width: 500px) {
  .heading__title {
    font-size: 2rem;
.heading__img {
  width: 24%;

.form__label {
  display: block;
  margin-bottom: 0.5rem;

.form__input {
  box-sizing: border-box;
  background-color: transparent;
  padding: 0.7rem;
  border-bottom-right-radius: 15px 3px;
  border-bottom-left-radius: 3px 15px;
  border: solid 3px transparent;
  border-bottom: dashed 3px #ea95e0;
  font-family: "Gochi Hand", cursive;
  font-size: 1rem;
  color: rgba(63, 62, 65, 0.7);
  width: 70%;
  margin-bottom: 20px;
.form__input:focus {
  outline: none;
  border: solid 3px #ea95e0;

@media only screen and (min-width: 500px) {
  .form__input {
    width: 60%;
.button {
  padding: 0;
  border: none;
  transform: rotate(4deg);
  transform-origin: center;
  font-family: "Gochi Hand", cursive;
  text-decoration: none;
  padding-bottom: 3px;
  border-radius: 5px;
  box-shadow: 0 2px 0 #494a4b;
  transition: all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
  background-image: url("data:image/gif;base64,R0lGODlhBAAEAIABAAAAAAAAACH/C1hNUCBEYXRhWE1QPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS4wLWMwNjEgNjQuMTQwOTQ5LCAyMDEwLzEyLzA3LTEwOjU3OjAxICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M1LjEgV2luZG93cyIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo5NUY1OENCRDdDMDYxMUUyOTEzMEE1MEM5QzM0NDVBMyIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDo5NUY1OENCRTdDMDYxMUUyOTEzMEE1MEM5QzM0NDVBMyI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjk1RjU4Q0JCN0MwNjExRTI5MTMwQTUwQzlDMzQ0NUEzIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjk1RjU4Q0JDN0MwNjExRTI5MTMwQTUwQzlDMzQ0NUEzIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+Af/+/fz7+vn49/b19PPy8fDv7u3s6+rp6Ofm5eTj4uHg397d3Nva2djX1tXU09LR0M/OzczLysnIx8bFxMPCwcC/vr28u7q5uLe2tbSzsrGwr66trKuqqainpqWko6KhoJ+enZybmpmYl5aVlJOSkZCPjo2Mi4qJiIeGhYSDgoGAf359fHt6eXh3dnV0c3JxcG9ubWxramloZ2ZlZGNiYWBfXl1cW1pZWFdWVVRTUlFQT05NTEtKSUhHRkVEQ0JBQD8+PTw7Ojk4NzY1NDMyMTAvLi0sKyopKCcmJSQjIiEgHx4dHBsaGRgXFhUUExIREA8ODQwLCgkIBwYFBAMCAQAAIfkEAQAAAQAsAAAAAAQABAAAAgYEEpdoeQUAOw==");
  background-color: rgba(0, 255, 196, 0.7);

.button span {
  background: #f1f5f8;
  display: block;
  padding: 0.5rem 1rem;
  border-radius: 5px;
  border: 2px solid #494a4b;

.button:active, .button:focus {
  transform: translateY(4px);
  padding-bottom: 0px;
  outline: 0;

.toDoList {
  text-align: left;
.toDoList li {
  position: relative;
  padding: 0.5rem;
.toDoList li:hover {
  text-decoration: line-through wavy #24bffb;

Step 3 (JavaScript Code):

Finally, we need to create a function in JavaScript.

Let's break down the code step by step:

1. An Immediately Invoked Function Expression (IIFE) is used to encapsulate the entire code block. This pattern is often used to create a private scope for variables, preventing them from polluting the global scope.

2. Inside the IIFE, several state variables and UI variables are declared and initialized:

  • toDoListArray: An array that will store the To-Do list items.
  • form, input, and ul: These variables are used to reference specific elements in the HTML structure. form refers to the HTML form element, input refers to the input field within the form, and ul refers to an unordered list where the To-Do list items will be displayed.

3. Two event listeners are set up:

  • The first listener is for the form's submit event. When the form is submitted (user presses Enter or clicks the "Submit" button), the function prevents the default form submission behavior (page reloads), generates a unique ID for the To-Do item, retrieves the input value, and then invokes two functions: addItemToDOM() and addItemToArray().
  • The second listener is for the unordered list (ul). It listens for click events within the list. When an item within the list is clicked, it checks if the clicked element has a data-id attribute. If it does, it invokes two functions: removeItemFromDOM() and removeItemFromArray().

4. Four functions are defined within the IIFE:

  • addItemToDOM(itemId, toDoItem): This function creates a new list item (<li>) element, assigns it a data-id attribute with the provided itemId, sets the inner text of the list item to the provided toDoItem, and appends the list item to the unordered list (ul).
  • addItemToArray(itemId, toDoItem): This function adds a new object to the toDoListArray array, where each object represents a To-Do item with its associated itemId and toDoItem text.
  • removeItemFromDOM(id): This function finds the list item element with the specified data-id attribute (id) and removes it from the unordered list (ul).
  • removeItemFromArray(id): This function filters the toDoListArray to exclude the object with the matching itemId, effectively removing the corresponding To-Do item from the array.

5. The IIFE is immediately invoked by enclosing the entire code block in parentheses and adding () at the end. This ensures that the code within the IIFE is executed as soon as the JavaScript file is loaded.

Create a JavaScript file with the name of script.js and paste the given codes into your JavaScript file and make sure it's linked properly to your HTML document, so that the scripts are executed on the page. Remember, you’ve to create a file with .js extension.

(() => { 
  // state variables
  let toDoListArray = [];
  // ui variables
  const form = document.querySelector(".form"); 
  const input = form.querySelector(".form__input");
  const ul = document.querySelector(".toDoList"); 

  // event listeners
  form.addEventListener('submit', e => {
    // prevent default behaviour - Page reload
    // give item a unique ID
    let itemId = String(;
    // get/assign input value
    let toDoItem = input.value;
    //pass ID and item into functions
    addItemToDOM(itemId , toDoItem);
    addItemToArray(itemId, toDoItem);
    // clear the input box. (this is default behaviour but we got rid of that)
    input.value = '';
  ul.addEventListener('click', e => {
    let id ='data-id')
    if (!id) return // user clicked in something else      
    //pass id through to functions
  // functions 
  function addItemToDOM(itemId, toDoItem) {    
    // create an li
    const li = document.createElement('li')
    li.setAttribute("data-id", itemId);
    // add toDoItem text to li
    li.innerText = toDoItem
    // add li to the DOM
  function addItemToArray(itemId, toDoItem) {
    // add item to array as an object with an ID so we can find and delete it later
    toDoListArray.push({ itemId, toDoItem});
  function removeItemFromDOM(id) {
    // get the list item by data ID
    var li = document.querySelector('[data-id="' + id + '"]');
    // remove list item
  function removeItemFromArray(id) {
    // create a new toDoListArray with all li's that don't match the ID
    toDoListArray = toDoListArray.filter(item => item.itemId !== id);

Final Output:

Create a Responsive To-Do List App using HTML, CSS, and JavaScript.gif


Congratulations! You've successfully created a responsive to-do list app using HTML, CSS, and JavaScript. You've mastered the art of structuring web content, styling interfaces, and adding functionality. Now, you can efficiently manage your tasks whether you're at your desk or on the go.

In this structured blog post, we've covered the process of creating a responsive to-do list app step by step. From setting up the HTML structure to making the app responsive, you now have the knowledge to develop your own task management tool. With HTML, CSS, and JavaScript, you can craft user-friendly and versatile web applications that cater to users across devices. Happy coding!

That’s a wrap!

I hope you enjoyed this post. Now, with these examples, you can create your own amazing page.

Did you like it? Let me know in the comments below 🔥 and you can support me by buying me a coffee.

And don’t forget to sign up to our email newsletter so you can get useful content like this sent right to your inbox!

Faraz 😊

End of the article

Subscribe to my Newsletter

Get the latest posts delivered right to your inbox

Latest Post