Snippets List

Bootstrap 5 To-Do List with Filters and Progress

A clean to-do list with an add field, check-off tasks, a progress bar and All/Active/Done filters.

Bootstrap 5 No jQuery Dec 2019 2.5K views

<section class="wdw-stage">
  <div class="container" style="max-width: 580px;">
    <div class="wdw-card overflow-hidden" id="todo">
      <div class="p-4 p-md-5 pb-3 pb-md-4">
        <div class="d-flex align-items-start justify-content-between gap-3 mb-4">
          <div>
            <span class="wdw-eyebrow">Today</span>
            <h2 class="wdw-heading h3 mb-0">To-do list</h2>
          </div>
          <span class="badge rounded-pill text-bg-primary fs-6 px-3 py-2" id="todo-count">2 left</span>
        </div>
        <div class="d-flex align-items-center gap-3 mb-4">
          <div class="progress flex-grow-1" style="height: 8px;" role="progressbar" aria-label="Completed tasks" aria-valuemin="0" aria-valuemax="100" aria-valuenow="33" id="todo-progress">
            <div class="progress-bar" id="todo-bar" style="width: 33%"></div>
          </div>
          <span class="small fw-semibold text-body-secondary text-nowrap" id="todo-stat">1 of 3 done</span>
        </div>
        <form class="input-group input-group-lg" id="todo-form">
          <label for="todo-input" class="visually-hidden">New task</label>
          <input type="text" class="form-control" id="todo-input" placeholder="Add a new task" autocomplete="off" required>
          <button class="btn btn-primary px-4" type="submit">Add</button>
        </form>
      </div>
      <div class="px-4 px-md-5 pb-3">
        <div class="nav nav-pills gap-1" id="todo-filter" role="group" aria-label="Filter tasks">
          <button type="button" class="nav-link rounded-pill py-1 px-3 active" data-filter="all" aria-pressed="true">All</button>
          <button type="button" class="nav-link rounded-pill py-1 px-3" data-filter="active" aria-pressed="false">Active</button>
          <button type="button" class="nav-link rounded-pill py-1 px-3" data-filter="done" aria-pressed="false">Done</button>
        </div>
      </div>
      <ul class="list-group list-group-flush" id="todo-list">
        <li class="list-group-item d-flex align-items-center gap-3 px-4 px-md-5 py-3">
          <label class="d-flex align-items-center gap-3 flex-grow-1 todo-row">
            <input class="form-check-input m-0 todo-check" type="checkbox">
            <span class="flex-grow-1"><span class="todo-text d-block">Go to maths class</span><span class="badge bg-primary-subtle text-primary-emphasis rounded-pill mt-1">Due 9:00</span></span>
          </label>
          <button type="button" class="btn btn-sm btn-outline-secondary border-0 todo-del" aria-label="Delete Go to maths class"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 6h18M8 6V4h8v2m-9 0 1 14h8l1-14"/></svg></button>
        </li>
        <li class="list-group-item d-flex align-items-center gap-3 px-4 px-md-5 py-3">
          <label class="d-flex align-items-center gap-3 flex-grow-1 todo-row">
            <input class="form-check-input m-0 todo-check" type="checkbox">
            <span class="flex-grow-1"><span class="todo-text d-block">Buy new clothes</span><span class="badge bg-primary-subtle text-primary-emphasis rounded-pill mt-1">Errand</span></span>
          </label>
          <button type="button" class="btn btn-sm btn-outline-secondary border-0 todo-del" aria-label="Delete Buy new clothes"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 6h18M8 6V4h8v2m-9 0 1 14h8l1-14"/></svg></button>
        </li>
        <li class="list-group-item d-flex align-items-center gap-3 px-4 px-md-5 py-3">
          <label class="d-flex align-items-center gap-3 flex-grow-1 todo-row">
            <input class="form-check-input m-0 todo-check" type="checkbox" checked>
            <span class="flex-grow-1"><span class="todo-text d-block">Visit George</span><span class="badge bg-primary-subtle text-primary-emphasis rounded-pill mt-1">Friends</span></span>
          </label>
          <button type="button" class="btn btn-sm btn-outline-secondary border-0 todo-del" aria-label="Delete Visit George"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 6h18M8 6V4h8v2m-9 0 1 14h8l1-14"/></svg></button>
        </li>
      </ul>
      <p class="text-center wdw-muted small py-4 mb-0 d-none" id="todo-empty">Nothing here. Enjoy the quiet.</p>
      <p class="visually-hidden" id="todo-status" role="status" aria-live="polite"></p>
    </div>
  </div>
</section>

Built on Bootstrap 5.3.8 with plain JavaScript — no jQuery. Supports light and dark mode via data-bs-theme.

Free to use in personal and commercial projects under the MIT license.