SolutionsCase StudiesAI ToolsResourcesAboutContact
Get Your Free AI Automation Audit Book a Free 30-Minute Strategy Call
Playground~/frontend Open editor

~/css/dashboard-layouts

7 CSS Dashboard Layouts

7 Pure CSSPublished 2026-10-05Free · no sign-up

Seven dashboard pieces: an app shell with sidebar and header, a row of KPI cards, a weekly sales chart made from list items, a recent orders table, widgets placed with named grid areas, an activity feed and the two-column settings layout.

01. App Shell: Sidebar, Header, Main

DashboardGrid areas

The skeleton of most dashboards built with grid-template-areas: a sidebar, a header and a main area. Under 420px of container width the areas are redefined to stack, so the whole reflow is a single property change.

View code
<div class="db1"><div class="in"><nav aria-label="App"><b>Acme</b><a href="#home" aria-current="page">Home</a><a href="#orders">Orders</a><a href="#stock">Stock</a></nav><header>Overview</header><main><div></div><div></div><div class="w"></div></main></div></div>
.db1 { width: 560px; max-width: 100%; container-type: inline-size; font: 13px Inter, system-ui, sans-serif; }
.db1 .in { display: grid; grid-template-columns: 120px 1fr; grid-template-areas: "nav head" "nav main"; gap: 0; height: 300px; border: 1px solid #e4e7ec; border-radius: 14px; overflow: hidden; background: #f9fafb; }
.db1 nav { grid-area: nav; display: grid; align-content: start; gap: 4px; padding: 12px; background: #101828; }
.db1 nav b { margin-bottom: 8px; color: #fff; font-size: 15px; }
.db1 nav a { padding: 6px 8px; border-radius: 6px; color: #98a2b3; text-decoration: none; } .db1 nav a[aria-current] { background: #1d2939; color: #fff; }
.db1 header { grid-area: head; padding: 12px 16px; border-bottom: 1px solid #e4e7ec; background: #fff; color: #101828; font-weight: 800; font-size: 15px; }
.db1 main { grid-area: main; display: grid; grid-template-columns: 1fr 1fr; gap: 10px; padding: 14px; align-content: start; }
.db1 main div { height: 70px; border-radius: 10px; background: #fff; border: 1px solid #e4e7ec; } .db1 main .w { grid-column: 1 / -1; height: 110px; }
.db1 a:focus-visible { outline: 2px solid #84adff; outline-offset: 1px; }
@container (max-width: 419px) { .db1 .in { grid-template-columns: 1fr; grid-template-areas: "head" "nav" "main"; height: auto; } .db1 nav { grid-auto-flow: column; justify-content: start; align-items: center; } .db1 nav b { display: none; } }

02. KPI Cards Row

DashboardStats

Four headline numbers, each with its label, change since last period and a direction word. Up and down are written as text (up 12%) as well as coloured arrows, so the meaning does not rely on red and green.

View code
<ul class="db2"><li><span>Revenue</span><b>$48.2k</b><em class="up">↑ up 12%</em></li><li><span>Orders</span><b>1,204</b><em class="up">↑ up 4%</em></li><li><span>Refunds</span><b>18</b><em class="dn">↓ down 9%</em></li><li><span>Avg order</span><b>$40</b><em>no change</em></li></ul>
.db2 { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 8px; width: 560px; max-width: 100%; margin: 0; padding: 0; list-style: none; font-family: Inter, system-ui, sans-serif; }
.db2 li { display: grid; gap: 2px; padding: 14px; border: 1px solid #263048; border-radius: 12px; background: #111727; }
.db2 span { color: #94a3b8; font-size: 12px; } .db2 b { color: #fff; font-size: 22px; }
.db2 em { color: #94a3b8; font-size: 12px; font-style: normal; font-weight: 600; } .db2 .up { color: #4ade80; } .db2 .dn { color: #fbbf24; }

03. Chart Card with CSS Bars

DashboardChart

A weekly sales card with a bar chart made from list items whose heights come from a custom property. It is a list, so each bar can carry its day and value as text for screen readers, which an image of a chart cannot.

View code
<section class="db3" aria-labelledby="db3h"><h3 id="db3h">Sales this week</h3><ul><li style="--v:40"><span class="sr">Monday: $400</span></li><li style="--v:65"><span class="sr">Tuesday: $650</span></li><li style="--v:52"><span class="sr">Wednesday: $520</span></li><li style="--v:90"><span class="sr">Thursday: $900</span></li><li style="--v:72"><span class="sr">Friday: $720</span></li></ul><div class="ax" aria-hidden="true"><span>M</span><span>T</span><span>W</span><span>T</span><span>F</span></div></section>
.db3 { width: 300px; max-width: 100%; box-sizing: border-box; padding: 16px; border: 1px solid #e4e7ec; border-radius: 14px; background: #fff; font-family: Inter, system-ui, sans-serif; }
.db3 h3 { margin: 0 0 12px; color: #101828; font-size: 15px; }
.db3 ul, .db3 .ax { display: grid; grid-template-columns: repeat(5, 1fr); gap: 10px; margin: 0; padding: 0; list-style: none; }
.db3 ul { align-items: end; height: 130px; border-bottom: 1px solid #e4e7ec; }
.db3 li { height: calc(var(--v) * 1%); border-radius: 6px 6px 0 0; background: #6941c6; }
.db3 li:nth-child(4) { background: #9e77ed; }
.db3 .ax { margin-top: 6px; color: #475467; font-size: 12px; text-align: center; }
.db3 .sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }

04. Recent Orders Table Card

DashboardTable

A card with a compact table of recent orders and status pills. The table has a caption, the wrapper scrolls sideways on small screens instead of squashing columns, and the status is text inside the pill, not just its colour.

View code
<div class="db4" tabindex="0" role="region" aria-labelledby="db4c"><table><caption id="db4c">Recent orders</caption><thead><tr><th scope="col">Order</th><th scope="col">Customer</th><th scope="col">Total</th><th scope="col">Status</th></tr></thead><tbody><tr><td>#1042</td><td>Ana R.</td><td>$84</td><td><span class="p ok">Paid</span></td></tr><tr><td>#1041</td><td>Jonas K.</td><td>$120</td><td><span class="p sh">Shipped</span></td></tr><tr><td>#1040</td><td>Mei T.</td><td>$36</td><td><span class="p rf">Refunded</span></td></tr></tbody></table></div>
.db4 { box-sizing: border-box; width: 420px; max-width: 100%; overflow-x: auto; border: 1px solid #263048; border-radius: 14px; background: #111727; font: 13px Inter, system-ui, sans-serif; }
.db4:focus-visible { outline: 2px solid #818cf8; outline-offset: 2px; }
.db4 table { width: 100%; border-collapse: collapse; }
.db4 caption { padding: 12px 14px; color: #fff; font-weight: 800; font-size: 15px; text-align: left; }
.db4 th, .db4 td { padding: 10px 14px; border-top: 1px solid #1f2937; text-align: left; white-space: nowrap; }
.db4 th { color: #94a3b8; font-weight: 600; font-size: 12px; } .db4 td { color: #e2e8f0; }
.db4 .p { padding: 3px 8px; border-radius: 999px; font-size: 12px; font-weight: 700; }
.db4 .ok { background: #052e16; color: #86efac; } .db4 .sh { background: #172554; color: #93c5fd; } .db4 .rf { background: #3f1d1d; color: #fca5a5; }

05. Widget Grid with Named Areas

DashboardGrid areas

Dashboard widgets placed with grid-template-areas strings, which read like a map of the layout. A container query swaps in a different map for narrow spaces, moving the chart above the side widgets without touching the HTML.

View code
<div class="db5"><div class="in"><section class="chart">Chart</section><section class="goal">Goal</section><section class="list">Top products</section><section class="map">Map</section></div></div>
.db5 { width: 520px; max-width: 100%; container-type: inline-size; font: 700 13px Inter, system-ui, sans-serif; }
.db5 .in { display: grid; gap: 8px; grid-template-columns: 2fr 1fr; grid-template-areas: "chart goal" "chart list" "map list"; }
.db5 section { display: grid; place-items: center; min-height: 70px; border-radius: 12px; background: #f2f4f7; color: #344054; }
.db5 .chart { grid-area: chart; min-height: 150px; background: #eef4ff; color: #1e3a8a; }
.db5 .goal { grid-area: goal; background: #ecfdf3; color: #054f31; } .db5 .list { grid-area: list; } .db5 .map { grid-area: map; background: #fef6ee; color: #93370d; }
@container (max-width: 400px) { .db5 .in { grid-template-columns: 1fr 1fr; grid-template-areas: "chart chart" "goal map" "list list"; } }

06. Activity Feed Panel

DashboardFeed

A narrow panel listing recent activity with an avatar, an action sentence and a relative time in a time element with the exact timestamp. The list scrolls inside the panel so it never pushes the rest of the dashboard down.

View code
<section class="db6" aria-labelledby="db6h"><h3 id="db6h">Activity</h3><ul tabindex="0" aria-label="Activity, scroll"><li><span class="av" aria-hidden="true">AR</span><p><b>Ana</b> refunded order #1040 <time datetime="2026-10-05T09:12">2 min ago</time></p></li><li><span class="av" aria-hidden="true">JK</span><p><b>Jonas</b> added 3 products <time datetime="2026-10-05T08:40">35 min ago</time></p></li><li><span class="av" aria-hidden="true">MT</span><p><b>Mei</b> changed shipping rates <time datetime="2026-10-05T07:55">1 h ago</time></p></li><li><span class="av" aria-hidden="true">AR</span><p><b>Ana</b> published a discount <time datetime="2026-10-04T17:20">yesterday</time></p></li></ul></section>
.db6 { box-sizing: border-box; width: 300px; max-width: 100%; border: 1px solid #263048; border-radius: 14px; background: #111727; font: 13px/1.4 Inter, system-ui, sans-serif; }
.db6 h3 { margin: 0; padding: 12px 14px; border-bottom: 1px solid #263048; color: #fff; font-size: 15px; }
.db6 ul { max-height: 200px; overflow-y: auto; margin: 0; padding: 4px 0; list-style: none; }
.db6 ul:focus-visible { outline: 2px solid #818cf8; outline-offset: -2px; }
.db6 li { display: flex; gap: 10px; padding: 10px 14px; }
.db6 .av { flex: none; display: grid; place-items: center; width: 30px; height: 30px; border-radius: 50%; background: #312e81; color: #c7d2fe; font-size: 11px; font-weight: 800; }
.db6 p { margin: 0; color: #cbd5e1; } .db6 b { color: #fff; }
.db6 time { display: block; color: #64748b; font-size: 12px; }

07. Settings Page Two-Column Layout

DashboardForms

The settings pattern: each section's title and explanation on the left, its fields on the right. On narrow containers the description goes above the fields. Every field has a visible label and the sections are fieldsets with legends.

View code
<form class="db7"><fieldset><div class="d"><legend>Store details</legend><p>Shown on invoices and emails.</p></div><div class="f"><label>Store name<input value="Linea Home"></label><label>Support email<input type="email" value="help@example.com"></label></div></fieldset><fieldset><div class="d"><legend>Currency</legend><p>Prices are shown in this currency.</p></div><div class="f"><label>Currency<select><option>EUR</option><option>GBP</option><option>USD</option></select></label></div></fieldset></form>
.db7 { width: 560px; max-width: 100%; container-type: inline-size; font: 13px Inter, system-ui, sans-serif; color: #101828; }
.db7 fieldset { display: grid; gap: 10px; min-inline-size: 0; margin: 0; padding: 16px 0; border: 0; border-bottom: 1px solid #e4e7ec; }
.db7 legend { float: left; padding: 0; font-weight: 800; font-size: 14px; }
.db7 .d p { clear: both; margin: 4px 0 0; color: #475467; }
.db7 .f { display: grid; gap: 10px; }
.db7 label { display: grid; gap: 4px; font-weight: 600; }
.db7 input, .db7 select { min-width: 0; padding: 9px 10px; border: 1px solid #98a2b3; border-radius: 8px; background: #fff; font: 14px Inter, system-ui, sans-serif; }
.db7 input:focus-visible, .db7 select:focus-visible { outline: 3px solid #84adff; outline-offset: 1px; }
@container (min-width: 480px) { .db7 fieldset { grid-template-columns: 180px 1fr; gap: 24px; } }

About these CSS Dashboard Layouts

Map the layout with named areas

grid-template-areas describes a dashboard as a small text map. Changing the map in a container or media query rearranges the whole layout without touching the HTML.

Charts that can be read

A bar chart built from list items can carry each value as text for screen readers. Image or canvas charts need a table or summary alongside them.

Status is never colour alone

Paid, Shipped and Refunded should be words inside their pills. Write up and down with KPI changes too, so red and green are not the only signal.

Tables scroll, they do not squash

Put wide tables in a focusable wrapper with overflow-x: auto and a label. Squashing columns into a narrow screen makes the data unreadable.

Frequently asked questions

Is this a full admin template?

No. These are layout building blocks you can combine and wire to your own data.

Why use container queries here?

Dashboards are made of widgets placed in columns of different widths; each widget adapts to its own space.

Do I need a chart library?

For simple bars, no. For line charts, axes and tooltips, a library or SVG is better.