webdevpuneet.com

Dashboard Layout — Free HTML CSS Admin Snippet

Dashboard Layout · Dashboards · Plain HTML & CSS · Live preview

CategoryDashboards

Copy & paste

Source Code

<div class="app">
  <aside class="sidebar">
    <div class="logo">◈ Dash</div>
    <nav>
      <a href="#" class="link active">
        <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="3" width="7" height="7"/><rect x="14" y="3" width="7" height="7"/><rect x="3" y="14" width="7" height="7"/><rect x="14" y="14" width="7" height="7"/></svg>
        Overview
      </a>
      <a href="#" class="link">
        <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><polyline points="22 12 18 12 15 21 9 3 6 12 2 12"/></svg>
        Analytics
      </a>
      <a href="#" class="link">
        <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/></svg>
        Users
        <span class="badge">12</span>
      </a>
      <a href="#" class="link">
        <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><line x1="12" y1="1" x2="12" y2="23"/><path d="M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6"/></svg>
        Billing
      </a>
    </nav>
  </aside>
  <div class="main">
    <header class="topbar">
      <div class="page-title">Overview</div>
      <div class="topbar-right">
        <div class="search"><svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg><input placeholder="Search…" /></div>
        <div class="user-dot">PS</div>
      </div>
    </header>
    <div class="content">
      <div class="metric-grid">
        <div class="metric"><span class="m-val">$24.8k</span><span class="m-key">Revenue</span><span class="m-trend up">↑ 12%</span></div>
        <div class="metric"><span class="m-val">1,284</span><span class="m-key">Users</span><span class="m-trend up">↑ 8%</span></div>
        <div class="metric"><span class="m-val">98.2%</span><span class="m-key">Uptime</span><span class="m-trend up">↑ 0.1%</span></div>
        <div class="metric"><span class="m-val">42ms</span><span class="m-key">Avg Response</span><span class="m-trend down">↑ 3ms</span></div>
      </div>
      <div class="chart-placeholder">
        <div class="chart-label">Revenue — last 7 days</div>
        <div class="bars">
          <div class="bar" style="--h:40%">Mon</div>
          <div class="bar" style="--h:65%">Tue</div>
          <div class="bar" style="--h:55%">Wed</div>
          <div class="bar" style="--h:80%">Thu</div>
          <div class="bar" style="--h:72%">Fri</div>
          <div class="bar" style="--h:45%">Sat</div>
          <div class="bar active" style="--h:90%">Sun</div>
        </div>
      </div>
    </div>
  </div>
</div>

Extend with AI

Take This Snippet Further With AI

The AI prompt for this one is for Patreon supporters ($3 a month), along with a site with no ads. Supporters enter the passcode once and it is remembered in this browser.

· Become a supporter

What's included

Features

display: flex app shell with height: 100vh — fixed sidebar, scrollable main
Sidebar: fixed 180px dark panel with logo, nav links, and user section
Main: flex: 1; overflow-y: auto — fills remaining width, scrolls independently
Stats row: CSS grid repeat(4,1fr) for equal-width metric cards
Data table with border-collapse and alternating row backgrounds
Status badges using the same rgba-tinted pattern as Badges & Chips snippet
Responsive: sidebar collapses on narrow screens via @media
Pure HTML and CSS — no JavaScript required
Export as HTML, JSX, or Tailwind CSS
Live editor — preview updates as you type

About this UI Snippet

Dashboard Layout — Flex App Shell, Fixed Sidebar & Content Grid

Screenshot of the Dashboard Layout snippet rendered live

A dashboard layout is the foundational structure of any admin panel, analytics tool, or SaaS application. This snippet provides a complete dashboard frame: a fixed sidebar, a scrollable main content area, a stats cards row, and a data table.

The flex app shell

.app { display: flex; height: 100vh } creates the full-height application frame. The sidebar has a fixed width: 180px and flex-shrink: 0. The main content has flex: 1; overflow-y: auto — it fills all remaining space and scrolls independently of the sidebar.

The stats cards row

Four stats cards use display: grid; grid-template-columns: repeat(4, 1fr) for equal-width distribution. Each card shows an icon, label, value, and change indicator.

The data table

A standard <table> with border-collapse: collapse and alternating row backgrounds communicates tabular data clearly. The status column uses coloured badge chips identical to the Badges & Chips snippet.

The sidebar navigation

The sidebar contains a brand logo, navigation links with icons, and a user profile section at the bottom. Each nav link uses a flex row with icon + label. The active link has background: rgba(accent,0.12) and accent-coloured text. The sidebar uses overflow-y: auto so long nav lists scroll without pushing the user profile off screen.

Responsive behaviour

On mobile, the sidebar should be hidden by default and toggled via a hamburger button. Add @media (max-width: 768px) { .sidebar { position: fixed; left: -180px; transition: left 0.3s; } .sidebar.open { left: 0; } .main { margin-left: 0; } }. A hamburger button in the header calls sidebar.classList.toggle("open").

The stats grid

Four metric cards use display: grid; grid-template-columns: repeat(4, 1fr). Each card has an icon, metric value, label, and change indicator. The change uses green for positive and red for negative. This pattern is from the Stats Card snippet in this library — wire to real data by updating the value and change fields from your API response.

Extending the layout

Drop any snippet from this library into the .main content area. The area scrolls independently, so content of any length works without affecting the sidebar or header. Add a .tabs nav inside the main header for sub-page navigation within the dashboard section.

Step by step

How to Use

  1. 1
    Load the snippetClick "Dashboard Layout" in the sidebar. The preview shows the full app shell: dark sidebar, stats row, and data table.
  2. 2
    Update sidebar nav linksIn the HTML panel, change the sidebar link labels and SVG icons.
  3. 3
    Update stats card valuesChange the metric values, labels, and change percentages in the four stats cards.
  4. 4
    Update table dataReplace the table rows with your own data. Update column headers and row content.
  5. 5
    Change sidebar widthUpdate width: 180px on .sidebar in the CSS panel to adjust the sidebar size.
  6. 6
    Export in your formatClick "HTML" for a standalone file, "JSX" for a React component, or "Tailwind" for a React + Tailwind version.

Real-world uses

Common Use Cases

SaaS admin and analytics dashboards
The foundational layout for any admin panel. Wire the sidebar links to your routes, populate the stats cards from your API, and render data in the table. The flex app shell handles sizing and scrolling automatically.
Prototype dashboard UIs before building
Use as a wireframe base to prototype any dashboard. Swap placeholder stats and table rows with real data structures before committing to a framework or component library.
Learn flex app shell and sticky sidebar
The layout uses display:flex on the root with a fixed sidebar and flex:1 main. Edit the sidebar width and main overflow to understand how flex distributes height and scroll independently.
CMS and content management interfaces
Apply the sidebar + content shell to a blog CMS, file manager, or settings interface. Each sidebar link navigates to a different content area in the main panel.
Foundation for any multi-section application
The layout shell works as a starting point for any web application with navigation. Replace sidebar links with your routes, add a topbar for user account, and populate the main area with your page components.
Team and project management tools
Add kanban boards, team member tables, and project status grids inside the scrollable main area. The dark sidebar accommodates icon-only collapsed state for more content space.
Related: Geolocation Accuracy Indicator
See the Geolocation Accuracy Indicator for a related dashboards pattern worth pairing with this one.

Got questions?

Frequently Asked Questions

The .app container is display: flex; height: 100vh. The .sidebar has flex-shrink: 0 (prevents compression) and its own height: 100vh with overflow-y: auto. The .main has flex: 1; overflow-y: auto. Both fill full height; the main area scrolls independently while the sidebar stays pinned.

Toggle a .collapsed class on the sidebar. CSS .sidebar.collapsed { width: 48px } collapses it to icon-only. Add overflow: hidden and hide the text labels with .collapsed .nav-label { display: none }. The main content expands into the freed space automatically via flex.

Add @media (max-width: 768px) { .sidebar { position: fixed; left: -180px; transition: left 0.3s; z-index: 100; } .sidebar.open { left: 0 } .app { padding-left: 0 } }. Add a hamburger button that toggles .open. An overlay behind the sidebar closes it on tap.

Yes. Create a Layout component that wraps all pages. The Sidebar component manages its own collapsed state. In Next.js, use the App Router layout.js to wrap all routes: export default function RootLayout({ children }) { return <div className="app"><Sidebar /><main>{children}</main></div> }

Add a .topbar element inside .main before .content. Give it position: sticky; top: 0; z-index: 10; background: #fff. Because .main uses overflow-y: auto, sticky positioning is scoped to the main scroll container — it pins to the top of the main area, not the viewport.

After your API fetch resolves, update each stat: const stats = await fetch("/api/stats").then(r => r.json()); document.getElementById("stat-revenue").textContent = "$" + stats.revenue.toLocaleString(). In React, store API data in useState and pass values as props to StatsCard components.