User Stats Card — Free HTML CSS JS Snippet

User Stats Card · Dashboards · Plain HTML, CSS & JS · Live preview

Share & Support

What's included

Features

GitHub-style activity heatmap from DOM divs with 6-level colour intensity
Circular SVG progress ring via stroke-dashoffset (same formula as SVG Progress Ring snippet)
Follow button .following toggle — fills button on follow, outlines on following
Stats row: followers, following, repos in equal flex columns
Heatmap built from JS loop: 12 cols × 7 rows of coloured divs
Card uses gradient avatar initials matching Profile Card pattern
Export as HTML, JSX, or Tailwind CSS
Mobile/Tablet/Desktop preview
Live editor — preview updates as you type
Save via Save as to IndexedDB

About this UI Snippet

User Stats Card — Activity Heatmap, Progress Arc & Follow Toggle

Screenshot of the User Stats Card snippet rendered live

A user stats card displays a developer profile with activity metrics, a contribution heatmap, skill progress, and social stats. Used on portfolio sites, developer dashboards, and community platforms.

The activity heatmap

The heatmap is built from DOM elements, not canvas. A JS loop creates 12 columns × 7 rows of divs. Each div gets a random background colour from the levels array (from light grey to deep blue) simulating contribution frequency. The break-inside: avoid CSS on cells prevents grid rows from wrapping.

Circular progress bar

The skill progress uses the same SVG stroke-dashoffset technique as the SVG Progress Ring snippet: stroke-dasharray: CIRCUMFERENCE and stroke-dashoffset: CIRCUMFERENCE * (1 - pct/100). The ring animates from 0 to the target value on page load.

Follow button toggle

The follow button toggles between "Follow" and "Following" states via .following class — the same pattern as the Social Post Card snippet.

The activity heatmap

The contribution heatmap is a 52-week × 7-day grid of small squares. Each square corresponds to one day. The colour intensity (from light grey to deep indigo) represents activity count on that day — 0 activity is the lightest; maximum activity is the darkest. JavaScript generates the grid using nested loops: for each week (column), create 7 day squares and append to the grid container. Random or real activity data determines each square's colour class.

The circular progress rings

Multiple SVG progress rings use the stroke-dashoffset technique to show different skill or metric percentages. Each ring has a different radius, colour, and target value. The rings animate simultaneously when the component mounts or scrolls into view. See the SVG Progress Ring snippet in this library for the full mathematics explanation.

The follow button state

The follow button toggles between "Follow" and "Following" states using a CSS class and a click handler. The button border and text colour change on toggle. In a real app, the click triggers a POST request to your follow API endpoint. Revert to "Follow" if the API call fails — the same optimistic update pattern as the social post card like button.

GitHub-style profile integration

For a developer portfolio using real GitHub data: fetch the GitHub GraphQL API with your personal access token to get contribution calendar data. Map the contributionCalendar weeks array to the heatmap grid. The contributionsByDay values map directly to colour intensity levels. Update the streak and total contribution counts from the API response summary fields.

The activity heatmap

The contribution heatmap is a 52-week × 7-day grid of small squares. Each square corresponds to one day. The colour intensity (from light grey to deep indigo) represents activity count on that day — 0 activity is the lightest; maximum activity is the darkest. JavaScript generates the grid using nested loops: for each week (column), create 7 day squares and append to the grid container. Random or real activity data determines each square's colour class.

The circular progress rings

Multiple SVG progress rings use the stroke-dashoffset technique to show different skill or metric percentages. Each ring has a different radius, colour, and target value. The rings animate simultaneously when the component mounts or scrolls into view. See the SVG Progress Ring snippet in this library for the full mathematics explanation.

The follow button state

The follow button toggles between "Follow" and "Following" states using a CSS class and a click handler. The button border and text colour change on toggle. In a real app, the click triggers a POST request to your follow API endpoint. Revert to "Follow" if the API call fails — the same optimistic update pattern as the social post card like button.

GitHub-style profile integration

For a developer portfolio using real GitHub data: fetch the GitHub GraphQL API with your personal access token to get contribution calendar data. Map the contributionCalendar weeks array to the heatmap grid. The contributionsByDay values map directly to colour intensity levels. Update the streak and total contribution counts from the API response summary fields.

Build with AI

Build, Understand, Optimize, and Extend It With AI

Instead of tracing the heatmap loop by hand, paste this snippet's HTML, CSS, and JS into an AI coding assistant like Claude and ask it to explain exactly how the nested for loops build the 12-column by 7-row grid of divs and assign each cell a random color from the levels array, and whether flexbox with flex-wrap is really the right layout choice compared to CSS grid for a fixed-size matrix like this. It's also worth an optimization question — ask whether creating 84 individual DOM elements via appendChild in a loop causes any noticeable layout thrashing, and how batching with a document fragment would change that. For extending it, have it replace the random data with a real activity count array and map counts to color levels, add hover tooltips showing the date and count per cell, or wire the whole card up to the GitHub GraphQL contributions API. Treat the code less like a finished artifact and more like a starting point for a conversation.

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 GitHub-style user stats card with an activity contribution heatmap, in plain HTML, CSS, and vanilla JavaScript with no libraries and no canvas.

Requirements:
- A profile card showing an avatar with initials, a name, a handle, a bio line, a follow button, and a row of four stat tiles (e.g. projects, followers, following, rating).
- A contribution heatmap built entirely from DOM div elements, not an image or canvas: use a nested loop to create a fixed number of columns (representing weeks), and within each column create a fixed number of row cells (representing days), appending each cell to its column and each column to the grid container.
- Each heatmap cell's background color must be selected from a small ordered array of color levels running from a neutral "no activity" shade up through several increasingly saturated shades, so the array itself functions as an intensity scale.
- Lay the columns out with flexbox so the grid reads left to right as weeks progressing through time, with each column stacking its day cells vertically.
- A skills section listing several skill tags as small pill-shaped badges plus a "+N more" indicator.
- A follow button that toggles between an outlined "Follow" state and a filled "Following" state on click, changing its border and background color accordingly.

Step by step

How to Use

  1. 1
    Load the snippetClick "User Stats Card" in the sidebar. The preview shows the profile card with heatmap, progress ring, and stats.
  2. 2
    Update user infoIn the HTML panel, change the avatar initials, username, handle, and bio text.
  3. 3
    Update heatmap dataIn the JS panel, change the levels array colours and the random generation logic to reflect real contribution data.
  4. 4
    Change progress ring percentageUpdate the data-pct attribute on the SVG .fill circle to your target percentage.
  5. 5
    Update follower statsChange the stat numbers (followers, following, repos) in the HTML stats row.
  6. 6
    Export in your formatClick "HTML" for a standalone file, "JSX" for a React component, or "Tailwind" for a React + Tailwind version.

Real-world uses

Common Use Cases

Developer portfolio profile cards
Show contribution heatmap, skill progress rings, and social stats on a developer portfolio or GitHub-style profile page.
Community platform user profiles
Display user activity and engagement metrics on developer community, open source, or learning platform profiles.
Employee analytics dashboards
Show activity heatmaps and progress metrics for team members in an HR or performance dashboard.
Learn heatmap DOM grid technique
The heatmap builds from a JS loop creating div elements with colour-coded backgrounds. Edit the levels array and loop to understand the grid construction.
Social proof and credibility displays
Show contribution streaks and activity levels as social proof on a freelancer or agency profile.
Wire to real GitHub or GitLab API
Replace the random heatmap colours with actual contribution data from the GitHub contributions API or GitLab contributions calendar.

Got questions?

Frequently Asked Questions

A JS loop creates 12 columns × 7 rows of divs. Each div gets a random background colour from the levels array (6 shades from grey to deep blue). The grid uses CSS flexbox with flex-wrap to arrange them in a grid pattern.

It uses SVG stroke-dashoffset: CIRCUMFERENCE * (1 - pct/100). The ring starts at full offset (hidden) and animates to the target offset. This is identical to the SVG Progress Ring snippet technique.

Yes. Replace Math.random() with your actual contribution counts. Map the count to a level index: Math.min(5, Math.floor(count / maxCount * 5)). Apply the corresponding level colour.

Update the levels array with your colour scale. The array goes from least active (index 0) to most active (index 5). Any 6-colour scale works.

Yes. Click "JSX" for a React component. Render the heatmap by mapping a 2D data array to div elements. Pass activity data as props.

Add a title attribute to each heatmap div: div.title = date + ": " + count + " contributions". The browser renders a native tooltip on hover.