Dashboard widget with CQ
A dashboard stat widget that adapts its layout from compact (icon + number stacked) to expanded (icon left, stats right) using CSS container queries.
Drag the bottom-right corner of the box to resize and watch each widget adapt independently.
Quick implementation
.widget-cq {
container-type: inline-size;
}
.dash-widget {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 0.5rem;
padding: 1.25rem;
background: var(--card);
border-radius: var(--radius);
}
.dash-widget__icon {
font-size: 1.5rem;
line-height: 1;
}
.dash-widget__value {
font-size: 2rem;
font-weight: 800;
line-height: 1;
color: var(--text);
}
.dash-widget__label {
font-size: 0.8rem;
color: var(--muted);
}
.dash-widget__trend {
font-size: 0.8rem;
font-weight: 600;
color: oklch(0.7 0.18 145);
}
@container (min-width: 14rem) {
.dash-widget {
flex-direction: row;
align-items: center;
gap: 1rem;
}
.dash-widget__body {
flex: 1;
}
}
Prompt this to your LLM
Includes role, constraints, two framework variants, and edge cases to handle.
You are a senior frontend engineer building adaptive dashboard widgets.
Goal: A stat widget that switches from a compact stacked layout (icon
above number above label) to a horizontal expanded layout (icon left,
stats right) based on its container width using CSS container queries.
Technical constraints:
- Apply container-type: inline-size to a .widget-cq wrapper around each
widget instance.
- Default layout: display: flex; flex-direction: column.
- At container min-width: 14rem, switch to flex-direction: row with the
icon on the left and a .dash-widget__body div on the right.
- .dash-widget__body gets flex: 1 to fill remaining space.
- Use oklch(0.7 0.18 145) for the positive trend color — pair it with an
accessible text label or arrow character, not color alone.
- Use var(--card) for the widget background.
- Use oklch() for all other color values — no hex or rgba.
Framework variant (pick one):
A) Vanilla CSS + HTML — .widget-cq wrapper, .dash-widget, .dash-widget__icon,
.dash-widget__body, .dash-widget__value, .dash-widget__label,
.dash-widget__trend classes.
B) React component — accepts icon, value, label, and trend props; applies
container-type via an inline style or CSS Module on the wrapper div.
Edge cases to handle:
- If the trend value is negative, use a different oklch() color (e.g.
oklch(0.65 0.2 25) for red) and a downward arrow — never rely on
color alone.
- If the icon is absent, the text column should still align correctly
without a gap placeholder.
- Add container-name to .widget-cq if widgets are nested inside another
container query context.
Return CSS only (or a React component if variant B).
Why
Dashboard widgets are the canonical container query use case — the same widget appears in a narrow sidebar, a wide main panel, and a modal. Each context demands a different layout. Container queries remove the need for per-instance CSS overrides or JavaScript ResizeObserver logic.
The logic
Wrap each widget in .widget-cq with container-type: inline-size. The default layout is flex-direction: column. At container widths of 14rem or more, @container switches to flex-direction: row with the icon on the left and a .dash-widget__body div on the right holding the number, label, and trend. The icon size and number size stay constant — only the arrangement changes.
Accessibility & performance
The trend indicator oklch(0.7 0.18 145) (green) must not be the only signal of direction — pair it with an accessible text label or an arrow character. Container queries have no runtime cost and do not require ResizeObserver polyfills in modern browsers.