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.
- 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
- Make it a containerEach widget has container-type: inline-size, so its children can ask how wide the widget is.
- Style by size@container rules switch the layout at 260 px and 440 px of widget width, whatever the page width.
- 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);