Page layouts
Learn how to build a sample version of the dashboard
Sample layout
To create a sample version of the dashboard, you can use the following code snippet. This code snippet will help you to create a dashboard layout with a header.
<div class="page">
<header class="navbar navbar-expand-sm d-print-none">
<div class="container-xl">
<h1 class="navbar-brand navbar-brand-autodark pe-0 pe-md-3">
<a href="#">
<img src="/static/logo.svg" width="110" height="32" alt="Tabler" class="navbar-brand-image" />
</a>
</h1>
<div class="navbar-nav flex-row order-md-last">
<div class="nav-item">
<a href="#" class="nav-link d-flex lh-1 text-reset p-0">
<span class="avatar avatar-sm" style="background-image: url(/static/avatars/002m.jpg)"></span>
<div class="d-none d-xl-block ps-2">
<div>Paweł Kuna</div>
<div class="mt-1 small text-secondary">UI Designer</div>
</div>
</a>
</div>
</div>
</div>
</header>
<div class="page-wrapper">
<main class="page-body">
<div class="container-xl">
<div class="row row-deck row-cards">
<div class="col-4">
<div class="card">
<div class="card-body" style="height: 10rem"></div>
</div>
</div>
<div class="col-4">
<div class="card">
<div class="card-body" style="height: 10rem"></div>
</div>
</div>
<div class="col-4">
<div class="card">
<div class="card-body" style="height: 10rem"></div>
</div>
</div>
<div class="col-12">
<div class="card">
<div class="card-body" style="height: 10rem"></div>
</div>
</div>
</div>
</div>
</main>
</div>
</div>Footer
Add a footer element with the footer class after .page-wrapper to close the page. d-print-none hides it when the page is printed, the same as the navbar. Use list-inline list-inline-dots for the footer links.
<footer class="footer footer-transparent d-print-none">
<div class="container-xl">
<div class="row text-center align-items-center flex-row-reverse">
<div class="col-lg-auto ms-lg-auto">
<ul class="list-inline list-inline-dots mb-0">
<li class="list-inline-item">
<a href="#" class="link-secondary">Documentation</a>
</li>
<li class="list-inline-item">
<a href="#" class="link-secondary">License</a>
</li>
<li class="list-inline-item">
<a href="#" class="link-secondary">Source code</a>
</li>
</ul>
</div>
<div class="col-12 col-lg-auto mt-3 mt-lg-0">
<ul class="list-inline list-inline-dots mb-0">
<li class="list-inline-item">Copyright © 2026 <a href="#" class="link-secondary">Your company</a> . All rights reserved.</li>
<li class="list-inline-item">
<a href="#" class="link-secondary">v1.0.0</a>
</li>
</ul>
</div>
</div>
</div>
</footer>footer-transparent drops the footer's own background, so it blends with the page behind it. Remove the class for a footer with a solid background, for example to visually separate it from the page body.
Sidebar layout
To create a sidebar layout, you can use the following code snippet. This code snippet will help you to create a sidebar layout with a header.
Vertical layout
<div class="page">
<aside class="navbar navbar-vertical navbar-expand-sm position-absolute">
<div class="container-fluid">
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#sidebar-menu" aria-controls="sidebar-menu" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<h1 class="navbar-brand navbar-brand-autodark">
<a href="#">
<img src="/static/logo.svg" width="110" height="32" alt="Tabler" class="navbar-brand-image" />
</a>
</h1>
<div class="collapse navbar-collapse" id="sidebar-menu">
<ul class="navbar-nav pt-lg-3">
<li class="nav-item">
<a class="nav-link" href="./">
<span class="nav-link-title">Home</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">
<span class="nav-link-title">Link 1</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">
<span class="nav-link-title">Link 2</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">
<span class="nav-link-title">Link 3</span>
</a>
</li>
</ul>
</div>
</div>
</aside>
<div class="page-wrapper">
<div class="page-header d-print-none">
<div class="container-xl">
<div class="row g-2 align-items-center">
<div class="col">
<h2 class="page-title">Vertical layout</h2>
</div>
</div>
</div>
</div>
<main class="page-body">
<div class="container-xl">
<div class="row row-deck row-cards">
<div class="col-sm-6 col-lg-3">
<div class="card">
<div class="card-body" style="height: 10rem"></div>
</div>
</div>
<div class="col-sm-6 col-lg-3">
<div class="card">
<div class="card-body" style="height: 10rem"></div>
</div>
</div>
<div class="col-sm-6 col-lg-3">
<div class="card">
<div class="card-body" style="height: 10rem"></div>
</div>
</div>
<div class="col-sm-6 col-lg-3">
<div class="card">
<div class="card-body" style="height: 10rem"></div>
</div>
</div>
<div class="col-lg-6">
<div class="row row-cards">
<div class="col-12">
<div class="card">
<div class="card-body" style="height: 10rem"></div>
</div>
</div>
<div class="col-12">
<div class="card">
<div class="card-body" style="height: 10rem"></div>
</div>
</div>
</div>
</div>
<div class="col-lg-6">
<div class="card">
<div class="card-body" style="height: 10rem"></div>
</div>
</div>
<div class="col-12">
<div class="card">
<div class="card-body" style="height: 10rem"></div>
</div>
</div>
<div class="col-md-12 col-lg-8">
<div class="card">
<div class="card-body" style="height: 10rem"></div>
</div>
</div>
<div class="col-md-6 col-lg-4">
<div class="card">
<div class="card-body" style="height: 10rem"></div>
</div>
</div>
<div class="col-md-6 col-lg-4">
<div class="card">
<div class="card-body" style="height: 10rem"></div>
</div>
</div>
<div class="col-md-12 col-lg-8">
<div class="card">
<div class="card-body" style="height: 10rem"></div>
</div>
</div>
<div class="col-12">
<div class="card">
<div class="card-body" style="height: 10rem"></div>
</div>
</div>
</div>
</div>
</main>
</div>
</div>Section labels
Group related menu items with a label. Add a nav-section-title list item before the first item of a group:
<ul class="navbar-nav">
<li class="nav-section-title">Overview</li>
<li class="nav-item">...</li>
<li class="nav-item">...</li>
<li class="nav-section-title">Components</li>
<li class="nav-item">...</li>
</ul>
The label is aligned with the item text and muted, so it does not compete with the links. In the folded sidebar, the label text is replaced with a short separator line centered in the gap between the groups, and the label keeps its height, so the menu does not shift when the sidebar folds. Section labels render only in vertical navbars - a horizontal navbar hides them.
Trailing entries
A .navbar-side wrapper with its own .navbar-nav after the menu is the sidebar's trailing group: a Customize link, a help link, anything that belongs at the end rather than in the menu. It stacks like the menu and never grows, and when the menu is shorter than the sidebar it is pinned to the bottom of the scroll area. In a horizontal navbar the same class lays the group out as a row on the end side.
<nav class="collapse navbar-collapse" id="sidebar-menu">
<ul class="navbar-nav">...</ul>
<div class="navbar-side">
<ul class="navbar-nav">
<li class="nav-item">
<button type="button" class="nav-link" data-bs-toggle="offcanvas" data-bs-target="#offcanvas-settings">
<span class="nav-link-icon"><svg><!-- brush icon --></svg></span>
<span class="nav-link-title">Customize</span>
</button>
</li>
</ul>
</div>
</nav>
Sidebar footer and user block
The vertical sidebar has three zones: the brand at the top, the nav as its own scroll area, and an optional navbar-footer pinned at the bottom. A common use is a user block with a drop-up menu:
<aside class="navbar navbar-vertical navbar-expand-lg">
<div class="container-fluid">
<div class="navbar-brand">...</div>
<nav class="collapse navbar-collapse" id="sidebar-menu">...</nav>
<div class="navbar-footer">
<ul class="navbar-nav">
<li class="nav-item dropup">
<a href="#" class="nav-link" data-bs-toggle="dropdown" aria-label="Open user menu">
<span class="avatar avatar-sm" style="background-image: url(...)"></span>
<span class="nav-link-title">
Paweł Kuna
<div class="small text-secondary">UI Designer</div>
</span>
</a>
<div class="dropdown-menu">
<a class="dropdown-item" href="#">Profile</a>
<a class="dropdown-item" href="#">Sign out</a>
</div>
</li>
</ul>
</div>
</div>
</aside>
The nav scrolls independently, so the footer stays visible with long menus. In the folded sidebar, the name and role collapse like link titles. Below the navbar's breakpoint, the footer moves into the mobile top bar: only the avatar shows, and its menu drops down instead of up.
Folded sidebar
Add navbar-folded to a vertical navbar to fold it into a narrow, icon-only rail. Link titles are hidden, icons are centered and submenus open as floating flyout menus next to the rail. The page content moves over automatically, so you get more space for your app.
The folded mode works only above the navbar's navbar-expand-* breakpoint. Below it, the sidebar keeps the standard mobile behavior with the toggler button.
Use data-bs-auto-close="outside" on submenu toggles in a folded sidebar, so an open flyout closes when the user clicks somewhere else.
<div class="page">
<aside class="navbar navbar-vertical navbar-expand-sm navbar-folded position-absolute">
<div class="container-fluid">
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#sidebar-folded" aria-controls="sidebar-folded" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<h1 class="navbar-brand navbar-brand-autodark">
<a href="#">
<img src="/static/logo-small.svg" width="32" height="32" alt="Tabler" class="navbar-brand-image" />
</a>
</h1>
<div class="collapse navbar-collapse" id="sidebar-folded">
<ul class="navbar-nav pt-lg-3">
<li class="nav-item active">
<a class="nav-link" href="#" aria-current="page">
<span class="nav-link-icon">
<!-- Download SVG icon from http://tabler.io/icons/icon/home -->
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false" class="icon">
<path d="M5 12l-2 0l9 -9l9 9l-2 0" />
<path d="M5 12v7a2 2 0 0 0 2 2h10a2 2 0 0 0 2 -2v-7" />
<path d="M9 21v-6a2 2 0 0 1 2 -2h2a2 2 0 0 1 2 2v6" />
</svg>
</span>
<span class="nav-link-title">Home</span>
</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" data-bs-toggle="dropdown" data-bs-auto-close="outside" role="button" aria-haspopup="true" aria-expanded="false">
<span class="nav-link-icon">
<!-- Download SVG icon from http://tabler.io/icons/icon/chart-bar -->
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false" class="icon">
<path d="M3 13a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v6a1 1 0 0 1 -1 1h-4a1 1 0 0 1 -1 -1l0 -6" />
<path d="M15 9a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v10a1 1 0 0 1 -1 1h-4a1 1 0 0 1 -1 -1l0 -10" />
<path d="M9 5a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v14a1 1 0 0 1 -1 1h-4a1 1 0 0 1 -1 -1l0 -14" />
<path d="M4 20h14" />
</svg>
</span>
<span class="nav-link-title">Reports</span>
</a>
<div class="dropdown-menu">
<a class="dropdown-item" href="#">Overview</a>
<a class="dropdown-item" href="#">Sales</a>
<a class="dropdown-item" href="#">Traffic</a>
</div>
</li>
<li class="nav-item">
<a class="nav-link" href="#">
<span class="nav-link-icon">
<!-- Download SVG icon from http://tabler.io/icons/icon/settings -->
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false" class="icon">
<path d="M10.325 4.317c.426 -1.756 2.924 -1.756 3.35 0a1.724 1.724 0 0 0 2.573 1.066c1.543 -.94 3.31 .826 2.37 2.37a1.724 1.724 0 0 0 1.065 2.572c1.756 .426 1.756 2.924 0 3.35a1.724 1.724 0 0 0 -1.066 2.573c.94 1.543 -.826 3.31 -2.37 2.37a1.724 1.724 0 0 0 -2.572 1.065c-.426 1.756 -2.924 1.756 -3.35 0a1.724 1.724 0 0 0 -2.573 -1.066c-1.543 .94 -3.31 -.826 -2.37 -2.37a1.724 1.724 0 0 0 -1.065 -2.572c-1.756 -.426 -1.756 -2.924 0 -3.35a1.724 1.724 0 0 0 1.066 -2.573c-.94 -1.543 .826 -3.31 2.37 -2.37c1 .608 2.296 .07 2.572 -1.065" />
<path d="M9 12a3 3 0 1 0 6 0a3 3 0 0 0 -6 0" />
</svg>
</span>
<span class="nav-link-title">Settings</span>
</a>
</li>
</ul>
</div>
</div>
</aside>
<div class="page-wrapper">
<main class="page-body">
<div class="container-xl">
<div class="row row-deck row-cards">
<div class="col-6">
<div class="card">
<div class="card-body" style="height: 10rem"></div>
</div>
</div>
<div class="col-6">
<div class="card">
<div class="card-body" style="height: 10rem"></div>
</div>
</div>
</div>
</div>
</main>
</div>
</div>Use a small, square logo in a folded sidebar. The brand area is only 4rem wide, so a wide logo will be cropped.
A folded rail does not scroll. If your menu has more items than the screen can fit, use the hover variant below or keep the sidebar expanded.
Unfold on hover
Use navbar-folded-hover instead of navbar-folded to get a folded rail that unfolds when the user hovers over it or moves keyboard focus into it. The expanded sidebar overlays the page content, so nothing moves around. This variant also restores scrolling of long menus while the sidebar is unfolded.
<aside class="navbar navbar-vertical navbar-expand-lg navbar-folded-hover">...</aside>
Pin button and saved state
To let users fold and unfold the sidebar at runtime, add a button with data-bs-toggle="sidebar-folded" anywhere on the page. A good place is the brand area: the logo stays on the start side and the pin button sits on the end side. The button is visible only while the sidebar is expanded. Unpinning folds the sidebar to the hover variant, so hovering the rail expands it again and shows the pin button:
<div class="navbar-brand">
<a href="." aria-label="Tabler">
<svg class="navbar-brand-image"><!-- logo mark --></svg>
</a>
<button
type="button"
class="btn btn-action btn-sm"
data-bs-toggle="sidebar-folded"
aria-pressed="false"
aria-label="Pin sidebar"
>
<svg><!-- pin icon --></svg>
</button>
</div>
Use a small, square logo mark in the brand area, so the logo does not jump when the sidebar folds and unfolds.
The button toggles the data-bs-sidebar="folded-hover" attribute on the <html> element, which folds every vertical navbar on the page. Set data-bs-sidebar="folded" yourself for a static rail that does not expand on hover. The choice is saved to localStorage under the tabler-sidebar key. The tabler-theme.js script applies the saved state before the page renders, so there is no flash of the wrong layout on reload. You can also set the state with the ?sidebar=folded URL parameter.
After each toggle, Tabler dispatches a tabler:sidebar-folded event on document. Use it to resize charts or maps after the page content changes width:
document.addEventListener('tabler:sidebar-folded', (event) => {
console.log(event.detail.folded) // true or false
myChart.resize()
})
You can also add tooltips with the link title to icon-only links, so users see the name of each item on hover.
Layout options
Beyond the sidebar, four more layout choices are available as attributes on <html>, applied before the page renders by tabler-theme.js. Every one of them has a static route too, so you can hard-code a layout without any JavaScript.
Container width
The page content runs at the container's normal width by default. Set fluid to let every container fill the viewport, or boxed to center the whole page in a frame:
<!-- attribute route, switchable at runtime -->
<html data-bs-layout="fluid">
<html data-bs-layout="boxed">
<!-- class route, fixed in the markup -->
<body class="layout-fluid">
<body class="layout-boxed">
Use one route or the other, not both. The boxed frame is the containing block of a vertical navbar, so a sidebar stays inside the frame instead of pinning to the viewport - it scrolls with the frame rather than staying fixed.
Sticky navbar
data-bs-navbar="sticky" keeps the top navbar at the top of the viewport while the page scrolls:
<html data-bs-navbar="sticky">
Only the navbar that is a direct child of .page sticks. On the two-row navbar the menu row scrolls away underneath, so the sticky strip stays one row high. Without the attribute you can still wrap a navbar in your own .sticky-top element.
Navigation position
data-bs-navbar-position picks which navigation the page shows:
<html data-bs-navbar-position="vertical">
This one needs the markup to cooperate. Render both navigations as direct children of .page, the vertical aside first:
<div class="page">
<aside class="navbar navbar-vertical navbar-expand-lg">...</aside>
<header class="navbar navbar-expand-md">...</header>
<div class="page-wrapper">...</div>
</div>
The CSS then shows one and hides the other, and removes the sidebar's width from the page offset when the sidebar is hidden. Both rules only fire when the other navigation really is on the page, so a page with a single navbar keeps it whatever the stored value says. That is what makes the layout safe to switch at runtime: no stored choice can leave a visitor with no navigation.
The demo pages use this: every page renders both navigations, and the layout demos state their own variant with the attribute.
Navigation theme
<html data-bs-navbar-theme="dark">
<html data-bs-navbar-theme="primary">
The attribute colors whichever navigation the page shows - the vertical sidebar is a navbar too. default means "follow the page color mode", so the navigation is light on a light page and dark on a dark one. dark gives it the dark palette on a light page, exactly like putting data-bs-theme="dark" on the navbar in your markup. primary paints it in the primary color and keeps the dark text palette, the same look as .bg-primary with data-bs-theme="dark":
<header class="navbar navbar-expand-md" data-bs-theme="dark">...</header>
<header class="navbar navbar-expand-md bg-primary" data-bs-theme="dark">...</header>
A light navigation inside a dark page is not supported - a light-scoped subtree inside a dark page inherits the dark styles.
Accessibility
A layout is what a screen reader user navigates by, so the landmarks matter more here than on any single component.
- Use the real elements for the regions. Tabler's own layout renders
headerfor the top bar,asidefor the vertical navbar,mainfor.page-bodyandfooterfor the footer. The classes are styling; the elements are what create the landmarks. .page-bodyshould be amain, and there is exactly one per page. It is the target the skip link points at.- Start the page with a skip link, so keyboard users can jump past the navigation. Tabler ships one:
<a href="#content" class="visually-hidden-focusable skip-link">Skip to main content</a>
...
<main class="page-body">
visually-hidden-focusable keeps the link out of the way until it takes focus, and then shows it.
- Label each navigation region. A page with a sidebar and a top bar has two
navelements, andaria-label="Primary"on one of them is what tells them apart. - The navbar toggler needs
aria-controlspointing at the collapsing element and a name such as "Toggle navigation". Bootstrap keepsaria-expandedin sync. - Keep the DOM order close to the reading order. A sidebar that appears on the right visually should still come where it belongs in the markup.
d-print-noneon the navbar and the footer removes them from print, which is what you want - but check that nothing users need only exists there.