Practical CSS System: Building a Responsive Dashboard
Combine modern CSS concepts into a realistic responsive dashboard architecture using Grid, Flexbox, custom properties, responsive design, and accessibility.
Dashboard Foundation
A production dashboard benefits from semantic design tokens, predictable layout primitives, responsive containers, and component boundaries. Start with global tokens and a page shell rather than styling every element independently.
:root {
--surface: #ffffff;
--surface-muted: #f8fafc;
--text: #0f172a;
--text-muted: #64748b;
--border: #e2e8f0;
--primary: #2563eb;
--radius: 0.875rem;
--space: 1rem;
}
body {
margin: 0;
background: var(--surface-muted);
color: var(--text);
font-family: system-ui, sans-serif;
}- Define semantic tokens before building many components.
- Keep global styles focused on foundations.
Why are semantic tokens useful in a dashboard design system?
Dashboard Grid
Use Grid for the overall two-dimensional application shell and Flexbox for internal one-dimensional component arrangements. This separation makes each layout system responsible for the problem it solves best.
.dashboard {
display: grid;
grid-template-columns: 240px minmax(0, 1fr);
min-height: 100dvh;
}
@media (max-width: 800px) {
.dashboard {
grid-template-columns: 1fr;
}
}
.dashboard__content {
min-width: 0;
padding: clamp(1rem, 3vw, 2rem);
}- Use Grid for page-level two-dimensional structure.
minmax(0, 1fr)helps prevent content from forcing unexpected overflow.
Why is `minmax(0, 1fr)` useful in a dashboard column?
Responsive Dashboard Cards
Dashboard cards are often ideal candidates for auto-fitting Grid layouts. Instead of defining separate desktop, tablet, and mobile card widths, intrinsic sizing can allow the browser to determine the number of columns.
.stats {
display: grid;
grid-template-columns: repeat(
auto-fit,
minmax(min(100%, 220px), 1fr)
);
gap: 1rem;
}
.stat-card {
padding: 1.25rem;
border: 1px solid var(--border);
border-radius: var(--radius);
background: var(--surface);
}- Intrinsic responsive grids can reduce breakpoint complexity.
- Use
min()insideminmax()when narrow containers are possible.
What does `auto-fit` help the Grid do?