Create a Drag and Drop To-Do List Tutorial (Source Code)


By Faraz -

Learn how to create an interactive drag and drop to-do list using HTML, CSS, and JavaScript. Follow our step-by-step tutorial for web development success.

Create a Drag and Drop To-Do List Tutorial.jpg

Table of Contents

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

In today's digital age, where productivity is paramount, interactive and user-friendly web applications have become indispensable. One such web feature that has gained immense popularity is the drag and drop to-do list. This ingenious creation empowers users to effortlessly organize their tasks by simply dragging and dropping them, streamlining the way we manage our daily responsibilities.

Aspiring web developers and enthusiasts often seek to unravel the secrets behind crafting these intuitive task management tools. Fortunately, you've arrived at the right place. In this comprehensive tutorial, we will walk you through the process of building your very own drag and drop to-do list from scratch, using the dynamic trio of HTML, CSS, and JavaScript. By the end of this guide, you'll not only have a functional to-do list but also a deeper understanding of web development principles and interactive user interface design.

So, fasten your seatbelts and get ready to embark on a journey into the exciting realm of web development. Whether you're a seasoned coder looking to enhance your skill set or a newcomer eager to learn, this tutorial will equip you with the knowledge and tools to create a visually appealing and highly functional drag and drop to-do list. Let's dive in and unlock the potential of web technology to transform the way you manage tasks!

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.

Here's a breakdown of the code:

1. <!DOCTYPE html>: This declaration specifies the document type and version of HTML being used, which is HTML5 in this case.

2. <html lang="en">: This is the opening tag for the HTML document. It includes the lang attribute set to "en" to indicate that the content is in English.

3. <head>: This section contains metadata about the document and links to external resources. Here's what's inside the <head> section:

  • <title>To-Do List</title>: Sets the title of the web page to "To-Do List," which will be displayed in the browser's title bar or tab.
  • <meta charset="UTF-8" />: Defines the character encoding of the document as UTF-8, which includes a wide range of characters from various languages.
  • <meta name="viewport" content="width=device-width" />: Specifies how the page should be scaled on different devices. In this case, it's set to the width of the device, ensuring that the page is responsive.
  • <link rel="stylesheet" href="">: Links to an external CSS stylesheet called "normalize.css." This stylesheet is used to reset and normalize default styles across different web browsers, ensuring a consistent appearance.
  • <link rel="stylesheet" href="styles.css" />: Links to an external CSS stylesheet named "styles.css," which is used to style the web page's content.

4. <body>: This is the main content area of the web page, where the visible content is displayed.

5. <header>: This section contains the header of the web page.

  • <h1>Drag & Drop<br/><span>To Do List</span></h1>: It contains an <h1> (heading) element with the text "Drag & Drop" and "To Do List" wrapped in a <span>. This represents the title of the page.

6. <div class="add-task-container">: This div element contains a form for adding new tasks to the to-do list.

  • <input type="text" maxlength="12" id="taskText" placeholder="New Task..." onkeydown="if (event.keyCode == 13) document.getElementById('add').click()">: This input field is for entering new tasks. It has a maximum length of 12 characters, an id attribute for JavaScript reference, and a placeholder text "New Task...". The onkeydown attribute is set to trigger the "Add" button click event when the Enter key is pressed.
  • <button id="add" class="button add-button" onclick="addTask()">Add New Task</button>: This button is used to add new tasks to the to-do list. It has an id attribute for JavaScript reference, a class for styling, and an onclick attribute to call a JavaScript function named addTask() when clicked.

7. <div class="main-container">: This div is the main content container for the to-do list.

  • Inside this container, there are four columns for organizing tasks: "To Do," "Doing," "Done," and "Trash."
  • Each column (<li class="column ...">) has a title (e.g., "To Do") and a list (<ul class="task-list" id="...">) where individual tasks are represented as list items (<li class="task">) containing task descriptions (<p>...</p>).
  • The "Trash" column also has a "Delete" button.

8. <footer>: This is the footer section of the web page.

9. <p>Built with <a href="" target="_blank">Dragula</a> and Vanilla JS by <a href="" target="_blank">Nikki Pantony</a></p>: It contains a text message indicating that the page was built using the "Dragula" library (a library for drag-and-drop functionality) and Vanilla JavaScript by Nikki Pantony. It includes links to the Dragula GitHub repository and Nikki Pantony's website.

10. <script>: These are JavaScript script tags that include external JavaScript files. These scripts provide interactivity and functionality to the web page.

  • <script src=""></script>: Links to the Dragula library, which is used for implementing drag-and-drop functionality.
  • <script src="script.js"></script>: Links to an external JavaScript file named "script.js," which contains custom JavaScript code for the To-Do List application.

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. Let's break down the code and explain each part:

1. @import Rule:

  • This rule imports external stylesheets from Google Fonts.
  • It imports two font families: "Arimo" with weights 400 and 700, and "Roboto Slab" with weights 400 and 700. These fonts can be used throughout the webpage.

2. :root Selector:

  • This sets the base font size for the entire document using CSS Custom Properties (variables).
  • The font size is calculated based on the viewport width (vw) and viewport height (vh).

3. Universal Selector *:

  • This rule applies to all elements on the page.
  • It sets the CSS box-sizing property to "border-box," which includes padding and borders in the element's total width and height.

4. body Selector: Sets a minimum width for the body element, ensuring a minimum width of 420 pixels.

5. h1 and h4 Selectors: Sets the font family for h1 and h4 elements to "Arimo" and specifies a line height of 1.3.

6. header h1 Selector: Styles the h1 element within the header, adjusting its font size and margin.

7. span Selector: Styles the span elements, setting their font size to 3rem.

8. p Selector: Sets the font family for all p elements to "Roboto Slab."

9. a and a:link, a:active, a:visited Selectors:

  • Styles links and their various states.
  • Sets link color, removes underlines, and adds a bottom border for links.

10. a:hover Selector: Styles links when hovered over, changing text color and the bottom border color.

11. header and footer Selectors: Set styles for the header and footer elements, controlling their width, margins, and text alignment.

12. .add-task-container Selector: Styles an element with the class "add-task-container," which is used for adding tasks.

13. .main-container Selector: Styles an element with the class "main-container," which is presumably a central part of the webpage.

14. .columns, .column, .column-header Selectors: Define styles for columns and their headers. These styles include background colors, borders, and padding.

15. Specific column classes (e.g., .to-do-column, .doing-column) Selector: Set background colors for specific column headers.

16. .task-list Selector: Defines styles for a task list, setting a minimum height.

17. ul and li Selectors: Styles for unordered lists and list items, removing default list styles.

18. .column-button Selector: Styles an element with the class "column-button," used for buttons within columns.

19. .button, .delete-button, .add-button Selectors: Styles buttons with various classes, including font family, colors, and padding.

20. .task Selector: Styles an element with the class "task," which is used for individual tasks or items.

21. #taskText Selector: Styles an element with the ID "taskText," possibly a text input field.

22. .gu-* Selectors: These selectors are related to Dragula, a library for drag-and-drop functionality. They style certain elements used for drag-and-drop operations.

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

@import url(",700|Roboto+Slab:400,700");

:root {
  font-size: calc(0.5vw + 1vh);

* {
  -webkit-box-sizing: border-box;
  box-sizing: border-box;

body {
  min-width: 420px;

h4 {
  font-family: "Arimo", sans-serif;
  line-height: 1.3;

header h1 {
  font-size: 2.4rem;
  margin: 4rem auto;

span {
  font-size: 3rem;

p {
  font-family: "Roboto Slab", serif;

a:visited {
  color: #0066aa;
  text-decoration: none;
  border-bottom: #000013 0.16rem solid;

a:hover {
  color: #000013;
  border-bottom: #0066aa 0.16rem solid;

footer {
  width: 40rem;
  margin: 2rem auto;
  text-align: center;

.add-task-container {
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  width: 20rem;
  height: 5.3rem;
  margin: auto;
  background: #a8a8a8;
  border: #000013 0.2rem solid;
  border-radius: 0.2rem;
  padding: 0.4rem;

.main-container {
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;

.columns {
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-align: start;
  -ms-flex-align: start;
  align-items: flex-start;
  margin: 1.6rem auto;

.column {
  width: 8.4rem;
  margin: 0 0.6rem;
  background: #a8a8a8;
  border: #000013 0.2rem solid;
  border-radius: 0.2rem;

.column-header {
  padding: 0.1rem;
  border-bottom: #000013 0.2rem solid;

.column-header h4 {
  text-align: center;

.to-do-column .column-header {
  background: #ff872f;

.doing-column .column-header {
  background: #13a4d9;

.done-column .column-header {
  background: #15d072;

.trash-column .column-header {
  background: #ff4444;

.task-list {
  min-height: 3rem;

ul {
  list-style-type: none;
  margin: 0;
  padding: 0;

li {
  list-style-type: none;

.column-button {
  text-align: center;
  padding: 0.1rem;

.button {
  font-family: "Arimo", sans-serif;
  font-weight: 700;
  border: #000013 0.14rem solid;
  border-radius: 0.2rem;
  color: #000013;
  padding: 0.6rem 1rem;
  margin-bottom: 0.3rem;
  cursor: pointer;

.delete-button {
  background-color: #ff4444;
  margin: 0.1rem auto 0.6rem auto;

.delete-button:hover {
  background-color: #fa7070;

.add-button {
  background-color: #ffcb1e;
  padding: 0 1rem;
  height: 2.8rem;
  width: 10rem;
  margin-top: 0.6rem;

.add-button:hover {
  background-color: #ffdd6e;

.task {
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-pack: center;
  -ms-flex-pack: center;
  justify-content: center;
  vertical-align: middle;
  list-style-type: none;
  background: #fff;
  -webkit-transition: all 0.3s;
  transition: all 0.3s;
  margin: 0.4rem;
  height: 4rem;
  border: #000013 0.15rem solid;
  border-radius: 0.2rem;
  cursor: move;
  text-align: center;

#taskText {
  background: #fff;
  border: #000013 0.15rem solid;
  border-radius: 0.2rem;
  text-align: center;
  font-family: "Roboto Slab", serif;
  height: 4rem;
  width: 7rem;
  margin: auto 0.8rem auto 0.1rem;

.task p {
  margin: auto;

/* Dragula CSS Release 3.2.0 from: */

.gu-mirror {
  position: fixed !important;
  margin: 0 !important;
  z-index: 9999 !important;
  opacity: 0.8;
  -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=80)";
  filter: alpha(opacity=80);

.gu-hide {
  display: none !important;

.gu-unselectable {
  -webkit-user-select: none !important;
  -moz-user-select: none !important;
  -ms-user-select: none !important;
  user-select: none !important;

.gu-transit {
  opacity: 0.2;
  -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=20)";
  filter: alpha(opacity=20);

Step 3 (JavaScript Code):

Finally, we need to create a function in JavaScript. Here's a breakdown of what each part of the code does:

1. Custom Dragula JS: This code initializes the Dragula library with four containers representing the four columns in the task management system - "To Do," "Doing," "Done," and "Trash." The Dragula library is often used for implementing drag-and-drop functionality in web applications. In this case, it allows tasks to be moved between these columns by dragging and dropping them.

2. addTask() Function: This function is triggered when a user wants to add a new task. It performs the following steps:

  • It retrieves the task text entered by the user from an input field with the id "taskText."
  • It appends the entered task text as an <li> element within the "To Do" column.
  • It clears the input field, effectively removing the task text from the input after adding it.

3. emptyTrash() Function: This function is used to delete tasks in the "Trash" column. Its purpose is to clear all tasks from the "Trash" column by setting the HTML content of the "trash" container to an empty string, effectively removing all tasks from this column.

Create a JavaScript file with the name 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.

/* Custom Dragula JS */

/* Vanilla JS to add a new task */
function addTask() {
  /* Get task text from input */
  var inputTask = document.getElementById("taskText").value;
  /* Add task to the 'To Do' column */
  document.getElementById("to-do").innerHTML +=
    "<li class='task'><p>" + inputTask + "</p></li>";
  /* Clear task text from input after adding task */
  document.getElementById("taskText").value = "";

/* Vanilla JS to delete tasks in 'Trash' column */
function emptyTrash() {
  /* Clear tasks from 'Trash' column */
  document.getElementById("trash").innerHTML = "";

Final Output:

Create a Drag and Drop To-Do List Tutorial.gif


Congratulations! You've successfully created a drag and drop to-do list using HTML, CSS, and JavaScript. In this tutorial, we've covered the basics of building an interactive task manager. To take your skills to the next level, consider these enhancements:

  1. Add data persistence with local storage or a backend database.
  2. Implement task prioritization and due dates.
  3. Customize the design further to match your project's branding.

In conclusion, mastering the art of drag-and-drop functionality is a valuable skill for web developers. We hope this tutorial has been insightful and inspires you to create more interactive web applications. Happy coding!

Code by: Nikki Pantony

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