Setup Checklist Onboarding Widget — Free HTML CSS JS Snippet

Setup Checklist Onboarding Widget · Dashboards · Plain HTML, CSS & JS · Live preview

CategoryDashboards

What's included

Features

Single TASKS array as the source of truth for the checklist, progress bar, and progress ring
SVG circular progress ring animated via stroke-dasharray/stroke-dashoffset, no canvas or library
Linear progress bar and "X of Y complete" text kept perfectly in sync with the ring
Click-to-toggle checklist rows with checkmark and strikethrough styling on completion
Collapsible card body with a smooth height/opacity transition and rotating chevron
Live recomputed completed-count state on every toggle, not a static percentage
Fully keyboard-accessible header button with aria-expanded state
Self-contained card styling that drops into any dashboard or sidebar

About this UI Snippet

Setup Checklist Onboarding Widget — Collapsible Progress Ring Checklist

Screenshot of the Setup Checklist Onboarding Widget snippet rendered live

New users rarely finish setup on their own, so many products surface a persistent "Get started" widget that tracks completion of a handful of onboarding tasks and nudges the user toward finishing them. This snippet implements that pattern as a single card: a circular progress ring plus a linear progress bar, and a five-item checklist that can be toggled complete by clicking any row.

One state array drives every visual

A plain TASKS array of { id, label, done } objects is the entire source of truth. renderList() builds the checklist rows from it, and renderProgress() recomputes the completed count, the linear progress bar's width, and the ring's stroke offset — all three visuals are derived, never set independently, so they can never disagree with each other.

The progress ring without a library

The ring is a pair of concentric SVG <circle> elements. The foreground circle's stroke-dasharray is fixed to its full circumference; its stroke-dashoffset is set to circumference * (1 - completedFraction), which visually "fills in" the ring proportionally to progress, animated with a CSS transition on stroke-dashoffset.

Toggling and collapsing

Clicking any checklist row flips that task's done flag and re-renders both the list and the progress visuals — there is no separate "mark complete" button, keeping the interaction to a single click per task. The header itself is a button that toggles a .sc-collapsed class on the card, collapsing the body via a max-height/opacity transition and rotating the chevron, so the widget can be tucked away without losing its progress state.

Step by step

How to Use

  1. 1
    Load the snippetClick "Setup Checklist Onboarding Widget" in the sidebar to load its HTML, CSS, and JS into the editor panels. The preview updates instantly.
  2. 2
    Edit the codeModify any panel — HTML, CSS, or JS. The preview refreshes as you type. Use Reset in each panel header to restore the original.
  3. 3
    Preview on devicesClick the Mobile (375px), Tablet (768px), or Desktop buttons in the preview header to check responsiveness.
  4. 4
    Export in your formatClick "HTML" to download a standalone file, "JSX" for a React component, "Tailwind" for a React + Tailwind CSS component, "Tailwind HTML" for a standalone HTML file with Tailwind CDN, "Vue" for a Vue 3 SFC with <template>/<script setup>/<style scoped>, or "Angular" for a standalone Angular .component.ts file. "Copy all" copies the full code to clipboard.
  5. 5
    Save your versionClick "Save as", type a name, and press Enter. Your snippet saves to IndexedDB and appears in the Saved tab.

Real-world uses

Common Use Cases

🚀
Product onboarding dashboards
Surface a persistent Get started widget in the corner of an app, with a progress ring and an X of Y complete count that nudges people to finish.
🎯
Free-trial activation flows
Guide trial users toward the actions that predict conversion, with click-to-toggle rows and strikethrough styling confirming each completed step.
✅
Account setup tracking
Track completion of profile, security and integration tasks, with a single TASKS array driving the checklist, the bar and the ring together.
🎓
Derived UI state reference
See how the ring offset, the linear bar and the count all compute from one source of truth, so they cannot drift out of sync.

Got questions?

Frequently Asked Questions

It is two SVG circles. The foreground circle's stroke-dasharray equals its full circumference, and its stroke-dashoffset is set to circumference times (1 minus the completed fraction), which visually reveals more of the stroke as progress increases.

All three are recalculated from the same TASKS array inside renderProgress(), which runs after every toggle. There is no independent state for any of the three visuals.

The row's done flag flips, both renderList() and renderProgress() re-run, and the row gets a filled checkmark and strikethrough label while the ring and bar animate to the new percentage.

Yes — clicking a completed row toggles it back to incomplete, and all three progress visuals update accordingly.

Build with AI

Build, Understand, Optimize, and Extend It With AI

Hand this snippet's HTML, CSS, and JavaScript to an AI coding assistant like Claude and ask it to adapt "Setup Checklist Onboarding Widget" to your project — restyle it to match your design system, wire it up to real data instead of the static example, or port it to the framework you're building in.

Prompt to recreate it

Copy this into your AI assistant of choice to build the effect from scratch, or as a jumping-off point for your own variant:

text
Build a dashboards component called "Setup Checklist Onboarding Widget" using plain HTML, CSS, and vanilla JavaScript — no framework, no build step.

Requirements:
- Match the structure and behavior of the "Setup Checklist Onboarding Widget" snippet from the UI Snippets Library.
- Keep the markup semantic and the styling self-contained (no external dependencies beyond what the original snippet uses).
- Keep the JavaScript vanilla, with no framework runtime required.
- Make it easy to restyle via CSS custom properties or class overrides so it can be dropped into a real project.

Want to tighten it up first? Run this prompt through the AI Prompt Studio to score it across 8 quality dimensions, catch anti-patterns, and tune the wording for Claude, ChatGPT, or Gemini before you paste it in.

Source Code

<div class="sc-card" id="scCard">
  <button class="sc-header" id="scHeader" aria-expanded="true">
    <div class="sc-header-left">
      <svg class="sc-ring" width="44" height="44" viewBox="0 0 44 44">
        <circle class="sc-ring-track" cx="22" cy="22" r="18"></circle>
        <circle class="sc-ring-fill" id="scRingFill" cx="22" cy="22" r="18"></circle>
      </svg>
      <div>
        <h3>Get started</h3>
        <p id="scProgressText">0 of 5 complete</p>
      </div>
    </div>
    <svg class="sc-chevron" id="scChevron" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M6 9l6 6 6-6"/></svg>
  </button>

  <div class="sc-body" id="scBody">
    <div class="sc-progress-bar"><div class="sc-progress-fill" id="scProgressFill"></div></div>
    <ul class="sc-list" id="scList"></ul>
  </div>
</div>