Vanilla JavaScript Projects

Project 17, Modern UI

Responsive Dashboard Widgets

Drag the corner of any widget. Each one picks its own layout from its own width, not the screen width, so the same widget works in a sidebar or full width.

82%
Main API
CSS Container Queries
Also uses
ResizeObserver, Canvas
Dependencies
None
Your browser
Checking

Resize the widgets

Drag the bottom right corner of any widget, or try a preset.

Revenue this month

$48.2k
+12% vs last month
Best day: Tuesday the 14th, $3.1k from 58 orders.

Visitors

9,410
+4% this week
Most from search (46%) and direct (31%).

Open tasks

7
  • Done: Fix login bug
  • To do: Write release notes
  • To do: Review pull request 142
  • To do: Update pricing page

Dhaka

31°C
Humid, light wind
Next 7 hours: warming to 33°C at 2 pm.

How it works

  1. Make it a containerEach widget has container-type: inline-size, so its children can ask how wide the widget is.
  2. Style by size@container rules switch the layout at 260 px and 440 px of widget width, whatever the page width.
  3. Redraw on resizeResizeObserver reports the new size and the canvas chart is redrawn to fit, sharp on high density screens.
.widget { container-type: inline-size; resize: both; overflow: hidden; }

/* The widget, not the screen, decides the layout */
@container (min-width: 260px) { .widget canvas { display: block; } }
@container (min-width: 440px) { .widget .body { display: grid; grid-template-columns: auto 1fr; } }

// Keep the canvas sharp at every size
new ResizeObserver(([entry]) => {
  const { width, height } = entry.contentRect;
  canvas.width = width * devicePixelRatio;
  canvas.height = height * devicePixelRatio;
  draw();
}).observe(canvas);