Plenty of internal admin panels and monitoring screens carry a full component framework just to get a sidebar and a few cards onto the page. Plain CSS handles that job fine these days.
Container queries are the biggest reason. According to web.dev, they became Baseline widely available in August 2025, so a card can switch layouts based on the width of its own grid cell and no longer has to wait on a viewport breakpoint.
What Is a CSS Dashboard?
See the Pen
Dashboard UI by Håvard Brynjulfsen (@havardob)
on CodePen.
Admin Dashboard with Materialize
See the Pen
Admin Dashboard with Materialize by Tirth Patel (@T-P)
on CodePen.
Take the data away and what’s left is one page split into named regions. Navigation, KPI cards, tables and chart containers all sit in those regions, positioned with CSS Grid, Flexbox and custom properties.
The stylesheet decides layout, theme and responsive behavior. The HTML stays plain, and the data comes from wherever the project already keeps it.
Most dashboards end up with the same skeleton. The header carries search and account controls, and the sidebar holds navigation. Everything else lives in the main area, which is the widget grid with the KPI cards, tables and chart containers inside it.
Since the whole user interface lives in one stylesheet, changing the sidebar width or the accent color takes a one-line edit.
The term gets stretched in a few directions, though. Libraries such as Highcharts Dashboards ship their own markup, and the Highcharts documentation lists a fixed set of class names (such as highcharts-dashboards-row and highcharts-dashboards-cell) that developers override with plain CSS.
Hosted tools go further in the same direction. Checkly lets customers restyle its dashboards through a custom CSS editor, but only on its Team and Enterprise plans, and the vendor still controls the markup.
Then there’s the version where the markup and the stylesheet are both yours. That’s what the rest of this article assumes.
CSS places widgets and styles them. Fetching data and drawing chart values stays with JavaScript.
Which CSS Layout Module Fits Each Dashboard Region?
See the Pen
Dashboard Design with Flexbox by Aysenur Turk (@TurkAysenur)
on CodePen.
Grid runs the page frame and the widget area. Flexbox works better once you’re inside a single component, and subgrid only comes in when neighboring cards need their content to line up.
| Region | Module | Reason |
|---|---|---|
| Page frame (header, sidebar, main) | CSS Grid | Rows and columns defined together, named areas |
| Widget area | CSS Grid | Auto-fit columns, per-card spans |
| Card header, toolbar, nav items | Flexbox | One axis, sized by content |
| Card content across a row | Subgrid | Reuses parent tracks so labels and values align |
A grid layout fits the frame because the header, sidebar and main region depend on each other’s size. Flexbox can’t express that relationship without nested wrappers.
A flex-only frame still works for a single-column admin panel. Once there’s more than one content column, Grid saves you the extra wrapper divs and the percentage math.
Subgrid fixes cards whose titles wrap to different heights and push their values out of line, because the nested grid reuses the parent’s tracks. MDN lists it as Baseline widely available, supported across browsers since September 2023.
Each of these has a spot where it quietly breaks. A subgridded dimension has no implicit grid, so any surplus items land in the last track (MDN).
The 1fr column catches people more often. It has an automatic minimum size, so a wide table stretches the layout past the screen until the track is written as minmax(0, 1fr). Flexbox has the same habit, since items refuse to shrink below their content width unless min-width is set to 0.
Use Grid for the frame and Flexbox inside components. Reach for subgrid only when cards need shared alignment. That split covers most dashboards.
Building the Dashboard Frame with grid-template-areas
The idea is to name the regions on the elements and describe the whole layout once, on the container. The main region then scrolls on its own.
- Write semantic HTML with a header, a nav or aside for the sidebar, and a main element.
- Give each element a grid-area name (header, sidebar and main).
- On the container, set display: grid, grid-template-columns: 240px minmax(0, 1fr), and grid-template-areas: “sidebar header” “sidebar main”.
- Set the container height to 100svh and grid-template-rows to auto minmax(0, 1fr), so the frame fills the screen and the page itself never scrolls.
- Add overflow: auto to main. The header and sidebar stay in place because they sit outside the scrolling region.
The area names have to describe a complete grid of rectangles. MDN’s guide to grid template areas states that every row needs the same number of cells and every named area must be rectangular, otherwise the property is ignored. That one bites easily, since a single typo in one row throws the whole declaration away.
Height needs care on phones. According to MDN, plain vh equals the large viewport, so a 100vh frame can run under the browser toolbar while the toolbar is showing.
svh sizes to the small viewport, so the frame always fits. dvh tracks the toolbar as it moves, but MDN notes that dynamic units are not stable even when the viewport is unchanged, which makes them a poor fit for a large scrolling region. I’d skip dvh here.
The minmax(0, 1fr) in step 3 is what stops a wide data table from stretching the main track.
I’d sketch the track sizes in a visual CSS grid generator first. It saves a few rounds of trial and error.
How to Make a CSS Dashboard Responsive
On a dashboard, responsive design mostly means keeping the data readable. Stacking everything into one column isn’t the goal. A table that scrolls sideways inside its card beats a table squeezed to an unreadable width.
The card grid doesn’t need breakpoints at all. repeat(auto-fit, minmax(240px, 1fr)) fills each row with as many cards as fit.
The page skeleton is different. Below a chosen width the sidebar moves to the top or into an off-canvas panel, and that’s still a job for media queries. MDN’s grid template areas guide shows the same pattern: assign the area names to the elements once, then redefine only grid-template-areas inside the query, so a sidebar can move without any change to the HTML.
Widgets are where container queries come in. A card shows full detail in a wide cell and a compact summary in a narrow one, whatever the viewport does.
Size container queries became Baseline newly available in February 2023, and web.dev’s August 2025 digest marks them widely available, which matches Baseline’s 30-month rule.
Style queries are newer. Container style queries for custom properties became Baseline newly available on 19 May 2026, when Firefox 151 joined Chrome and Edge 111 and Safari 18. Because they are not yet widely available, give visitors on older Firefox versions a fallback.
Every container has one limit. Setting container-type applies containment, so a container cannot take its size from its own contents on the queried axis.
Sidebar, Header, KPI Card and Data Table Styling
See the Pen
Admin Dashboard by Robin Selmer (@robinselmer)
on CodePen.
The sidebar works best as a fixed-width track with a clear active link. Keep the text labels visible by default in the sidebar navigation and collapse to icons only on narrow screens.
In the frame built above, the header already stays put because main scrolls beneath it. Use position: sticky only when the whole page scrolls, and add scroll-padding-top equal to the header height so anchor links do not land underneath it.
Each KPI card needs a value and a label, plus some kind of change indicator. Pull border-radius, shadow and padding from shared custom properties so the cards match, then adapt existing card styles and vary only the accent color per metric.
Tables go inside an overflow-x: auto wrapper, and the header row should be sticky. Row actions need a hit area of at least 24 by 24 CSS pixels.
That 24-pixel floor is WCAG 2.2 success criterion 2.5.8 (Level AA). W3C’s Understanding document shows six icon buttons at 20 by 20 pixels passing with 4 pixels between them and failing with none.
Chart containers should reserve their space before the chart renders, with aspect-ratio or a fixed min-height, so a late-loading chart does not push the cards below it.
Every component should pull color from custom properties, and radius and spacing as well. That habit pays off the moment the theme changes.
Chart Rendering Options for a CSS Dashboard
See the Pen
Dashboard UI #1 : Project management with Charts by Olsi Odobashi (@olsiodobashi)
on CodePen.
Draw small, static charts with CSS or inline SVG. Bring in a charting library when a chart needs tooltips or zoom, or when the data updates live.
A progress bar or share-of-total ring needs no more than a custom property and conic-gradient(), and the theme tokens recolor it for free. Examples of pure CSS charts usually stop there, because axes and tooltips are not something a stylesheet can supply.
Inline SVG in HTML goes further. Each mark is an element, so CSS can color it and a title element can name it for screen readers.
| Option | Pros | Cons |
|---|---|---|
| CSS-only | No JavaScript, themed by tokens | No axes, no tooltips |
| Inline SVG | Full shape control, styled by CSS | Hand-built markup grows fast |
| Library (Chart.js, ApexCharts) | Tooltips, zoom, live updates | Script weight, extra accessibility work |
Libraries cost you in weight first. The ApexCharts installation docs list the default script-tag bundle at 263,188 bytes gzipped and the bare core at 157,032 (measured on version 8.0.0), which is a lot to ship for three bars.
Accessibility takes extra work too. Chart.js draws on a canvas, and its documentation says canvas content is not available to screen readers unless the page adds an aria-label with role=”img”, or fallback text inside the canvas tags.
The same page warns that a generic “browser does not support canvas” message counts as inaccessible fallback content.
Pick the lightest option that still shows the data honestly.
How to Add Dark Mode with Custom Properties
See the Pen
Dark UI – Bank dashboard concept by Håvard Brynjulfsen (@havardob)
on CodePen.
Define each color token once on :root, set color-scheme to light dark, and let light-dark() pick the value. A prefers-color-scheme media query does the same job with more lines.
MDN lists light-dark() as Baseline 2024 newly available, working across browsers since May 2024. It only runs when color-scheme is light dark, usually declared on :root. The function also has an image form (two images instead of two colors), but that part is newer and not Baseline: Chrome, Edge and Firefox added it in version 150, and Safari (up to 26.5) does not support it.
Following the system setting is the simpler route. The tokens switch with the operating system and there’s no JavaScript and no stored state. The catch is that users cannot override it from inside the dashboard.
Letting the user choose takes more work. A data-theme attribute on the html element holds light, dark or auto, a short script reads the saved choice before first paint, and a control flips the attribute and stores the new value.
Bootstrap 5.3 takes the second route, with data-bs-theme on the html element or on a single component. Its documentation notes that switching the Sass mixin to the media query output removes per-component themes.
The same docs suggest loading the toggler script at the top of the page to reduce flicker on reload. That flicker is the usual failure of attribute-based themes, where the page paints light and then flips.
Hard-coded hex values inside components ignore the token swap, which is why one card stays light in a dark theme. Chart series need their own dark set too, and an accessible color palette generator helps when choosing the pairs.
Where the image form of light-dark() is supported, a logo can swap with the theme in one declaration. Elsewhere, use a prefers-color-scheme media query for the logo.
How to Check a CSS Dashboard for Accessibility and Performance
These are the thresholds worth testing against, all taken from W3C and web.dev.
- Text contrast of 4.5:1, or 3:1 for large-scale text of 18 point or 14 point bold (W3C, WCAG 2.2 SC 1.4.3)
- Interface components and chart marks at 3:1, unless visible labels and values carry the same information (W3C, SC 1.4.11)
- Largest Contentful Paint at 2.5 seconds or less (web.dev)
- Interaction to Next Paint at 200 milliseconds or less (web.dev)
- Cumulative Layout Shift at 0.1 or less (web.dev)
Accessibility checks
Landmarks come first. Header, nav, main and aside map onto the frame regions and give screen reader users places to jump to.
Text and chart marks must meet the contrast ratios above in both themes. Check color contrast on each one, because a pair that passes on the light surface can fail on the dark one.
Focus is the easy one to forget. A sticky header or footer that completely covers a focused control fails WCAG 2.2 SC 2.4.11 (Focus Not Obscured, Minimum) at Level AA. W3C names scroll-padding as a sufficient technique (C43) and lists a header hiding focus as failure F110.
The prefers-reduced-motion: reduce media feature has been Baseline widely available since January 2020 (MDN), so card hover motion and chart entry animations can be toned down for users who ask.
Data tables also need real header cells and a caption, which the accessible tables guidance walks through.
Performance checks
Core Web Vitals are judged at the 75th percentile of page loads, split by mobile and desktop, according to web.dev. A page passes only when all three metrics meet their targets.
Interaction to Next Paint became a stable Core Web Vital in 2024 and replaced First Input Delay, so a test plan that still cites FID is out of date.
Lighthouse’s default page-load run cannot measure INP because it loads pages with no user input. Total Blocking Time is the lab proxy, and field data is the only full answer (web.dev, page last updated September 2025).
Layout shift is the metric a CSS dashboard controls most directly. Fixed sidebar tracks and reserved chart heights keep widgets in place while data loads.
Profile blur and shadow effects in DevTools instead of guessing at their cost.
When a CSS Dashboard Is the Wrong Choice
Plain CSS is the wrong tool when users need to rearrange widgets and have the layout saved for next time. It’s also a poor fit when the team needs ready-made forms, modals and date pickers on a deadline.
Webix shows what the first case takes. Its Dashboard widget lets users drag panels into new cells and resize them with a handle, then save and restore the layout through a cookie, local storage or session storage. It only ships in the Webix Pro edition, though.
| Situation | Better fit | Why |
|---|---|---|
| Fixed internal screen, few widgets | Plain CSS dashboard | No dependency to update |
| Many forms, modals, date pickers | Bootstrap or a Tailwind CSS kit | Prebuilt components |
| Widgets users arrange and save | Dashboard library such as Webix | Drag, resize, state saving built in |
| Large or live datasets | Charting library inside the CSS frame | Rendering handled in JavaScript |
A framework trades stylesheet weight and override work for build time. That trade pays off once the interface needs more than a few components.
A Tailwind CSS dashboard keeps the layout in utility classes inside the markup, which suits teams that already work that way. It does not remove the need for a charting library.
For an internal tool with fewer than a handful of fixed widgets, plain CSS wins.
CSS Dashboard Examples To Check Out
Dashboard UI by Azri Kahar
See the Pen
Dashboard UI by Azri Kahar (@azrikahar)
on CodePen.
Circl Dashboard

Products Dashboard UI by Aybuke Ceylan
See the Pen
Products Dashboard UI by Aybüke Ceylan (@aybukeceylan)
on CodePen.
Healthcare Dashboard UI
See the Pen
Healthcare Dashboard UI by Zafer AYAN (@zaferayan)
on CodePen.
Responsive Flexbox by ZingChart
See the Pen
Responsive Flexbox Dashboard by ZingChart (@zingchart)
on CodePen.
Beautiful Dashboard UI by AbubakerSaeed
See the Pen
Beautiful Dashboard UI by Abubaker Saeed (@AbubakerSaeed)
on CodePen.
Dashboard by Óscar Eusse
See the Pen
Dashboard by Óscar Eusse (@o-eusse)
on CodePen.
Project/Kanban Board
See the Pen
Project/Kanban Board – with Tailwind CSS by Rob Stinson (@robstinson)
on CodePen.
CSS Dashboard by alphardex
See the Pen
Dashboard by alphardex (@alphardex)
on CodePen.
Dashboard UI by Mert Cukuren
See the Pen
Dashboard UI by Mert Cukuren (@knyttneve)
on CodePen.
Dashboard Demo by Miles Manners
See the Pen
Dashboard Demo by Miles Manners (@milesmanners)
on CodePen.
Deals Management Dashboard for Account Management by Chris Coyler
See the Pen
Deals Management Dashboard for Account Managers by Chris Coyier (@chriscoyier)
on CodePen.
Dashboard New by Felix
See the Pen
Dashboard New by Felix (@felixsusanto)
on CodePen.
CSS Grid Admin Dashboard
See the Pen
CSS Grid Admin Dashboard by Max Böck (@mxbck)
on CodePen.
Stock App Dashboard
See the Pen
Dribbble Stock App Dashboard by Filip Vitas (@FilipVitas)
on CodePen.
Dashboard Magic by Joseph Rex
See the Pen
Dashboard by Joseph Rex (@josephrexme)
on CodePen.
Masterpiece by Mike Torosian
See the Pen
Dashboard UI by Mike Torosian (@mtorosian)
on CodePen.
New User Tour – Dashboard
See the Pen
New user tour – Dashboard by Manpreet Singh Gulati (@manpreet)
on CodePen.
Sabarinathan’s Trendsetter
See the Pen
Dashboard Layout Design – iPad Pro by Sabarinathan Masilamani (@nathan5x)
on CodePen.
Vojtech’s User-Centric Design
See the Pen
Users Dashboard by Vojtěch Musil (@blex)
on CodePen.
Keeping it Basic with Rizwan Ahmed
See the Pen
Basic Responsive Admin Dashboard by Rizwan Ahmed (@rizwanahmed19)
on CodePen.
Kim77’s Crowd-Pleaser
See the Pen
Responsive Dashboard by kim77 (@goodpublisher77)
on CodePen.
Lato’s Brilliance by Steven Tan
See the Pen
Lato – Dashboard by Steven Tan (@chienleng)
on CodePen.
Matthew’s Clean Design
See the Pen
Simple CSS Grid Dashboard by Matthew Holland (@trooperandz)
on CodePen.
Eric’s Practice Ground
See the Pen
Dashboard Css Grid Practice by Eric (@adjeteyboy)
on CodePen.
Student Life by Praveen Bisht
See the Pen
Student Dashboard | Using CSS by Praveen Bisht (@prvnbist)
on CodePen.
High Stakes with Liombe
See the Pen
GitBets – Betting Dashboard UI by Liombe (@Liombe)
on CodePen.
Claymorphic Dash Magic by Mozzarella
See the Pen
Claymorphic Dashboard * (Responsive, CSS Only) by MOZZARELLA (@TheMOZZARELLA)
on CodePen.
Tom Barton’s Slice of Dash
See the Pen
Dashboard by Tom Barton (@tombarton)
on CodePen.
Vibes with Internal Video Platform UI
See the Pen
Internal Video Platform UI by Aybüke Ceylan (@aybukeceylan)
on CodePeMedian.
Neo’s Dash Adventure

Mustafa Omar’s CSS Brilliance
See the Pen
Dashboard by Mustafa Omar (@themustafaomar)
on CodePen.
Job Recruiter Vibes by Aybüke Ceylan
See the Pen
Job Recruiter Dashboard UI by Aybüke Ceylan (@aybukeceylan)
on CodePen.
MatPress’s Material Magic

CSS Dashboard FAQ
Where can I find free CSS dashboard templates?
GitHub and free template sites carry most of them. TemplateMo lists free dashboards built with pure HTML, CSS and JavaScript, while Tabler is an open-source HTML dashboard kit built on Bootstrap.
Check the stack before downloading. A template that pulls in Bootstrap or Tailwind CSS is not a framework-free build.
Can a sidebar open and close without JavaScript?
Yes. A hidden checkbox with a label toggles the :checked state, and :has() lets the page react to it. :has() became Baseline newly available in December 2023.
Give the checkbox an accessible name and a visible focus style. The open or closed state resets on reload unless a script stores it.
How do I build a bento-style widget grid?
Set a fixed number of columns and let selected cards span extra tracks with grid-column and grid-row. Penpot’s own tutorial builds a bento layout for a sales dashboard on a four-column, four-row grid, with selected cards spanning several cells.
Add grid-auto-flow: dense to fill gaps, but know that it can pull cards out of DOM order, which changes the keyboard tab sequence.
How should I prototype a dashboard layout before coding it?
Sketch the header, sidebar and widget regions in a design tool first. Penpot builds CSS Grid layouts visually without code, and a CodePen scratch pad turns the track sizes into live CSS.
Keep the prototype to boxes and sizes. Colors and tokens come after the frame works.
Where to Start When Building a CSS Dashboard
Get the grid frame right first, set up design tokens second, and leave the widgets for last. That order puts the costliest changes up front, before anything depends on them.
Start with named areas for the header, sidebar and main. Custom properties for color, spacing and type come next, and cards, tables and charts go into the finished frame after that.
Reordering regions after widgets exist forces edits to every card. Tokens defined early let a theme change land in one rule block.
The catch is that the layout lives only in the stylesheet, so source order in the markup still has to match the reading order. Grid placement does not change the tab sequence.
- What is Backend in Web Development? - September 13, 2026
- What is Frontend Development? - September 11, 2026
- How to Make a Button in Figma: Design Best Practices - September 10, 2026




