Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Offcanvas Sidebar Block for React

A reading app in a fixed-height window whose sidebar slides fully out of view, so the article's line length grows from 62 to 78 characters; the trigger, the edge rail and Ctrl or Command with B bring it back.

Framework
UI library

Preview

Preview width

Installation

Part of Pro
Pro unlocks the code and one-line install of every Pro button and text effect, plus the MCP for your AI editor.
Have Pro already? Sign in to open it.Opens here as soon as you're Pro.

Overview

Give a reading app all of its width with this offcanvas sidebar for React with Base UI. A window framed by a hairline with a plus mark on each corner holds the Sidebar set to collapsible="offcanvas": folding it slides the whole rail out of the window, with no strip of icons remaining, and the page takes the room. The rail holds five typed articles on two shelves, Up next and Finished; choose one and the page shows it with a subhead and three paragraphs. Its measure follows the rail: lines run up to 62 characters beside the rail and up to 78 once it is gone, which the article, a readout and the status line all say. The menu button in the top bar, the rail along the window's edge and Ctrl or Command with B (while focus is inside the window, shown with Kbd keys) all bring it back. Below the medium breakpoint the rail is a sheet, and the window never changes height. It's built from Sidebar, Kbd and Guides, with a CSS entrance only. For readers, documentation, editors and any app where the content comes first.

FAQ

How is offcanvas different from the icon collapse?

collapsible="icon" shrinks the rail to a strip of icons with tooltips; collapsible="offcanvas" moves the whole rail out of the window and keeps no strip at all, only the menu button in the page's top bar and the thin rail along the edge. Offcanvas gives the page the most room and is the right choice when the navigation is something you reach for, not something you watch. The measure readout in this block is there to show what the room is for: the line length cap moves from 62 to 78 characters, with a short transition that stops under reduced motion.

How does Ctrl or Command with B work here?

The provider's own shortcut is off (shortcut={false}), because it listens on the whole page and a docs page that holds this block needs the keys for itself. Instead, the block adds a capture listener to the window's own element, so the keys work only while focus is inside the window, and they toggle the rail through useSidebar().toggleSidebar(). The key caps read ⌘ B on Apple devices and Ctrl B everywhere else, swapped in after the page loads. For a full-page app, remove both props from the provider and the catalog's page-wide shortcut comes back.

What is the measure readout, and is it real?

It's the cap on the article's line length: max-w-[62ch] while the rail is open and max-w-[78ch] once it isn't, where one ch is the width of a zero in the page's font. A line never runs longer than that, and on a narrow window it is shorter, so the readout says "up to". It reads the rail's state from useSidebar(), the same state the status line reports, so the three always agree.

What stays in the page, and how do I connect it?

Everything. The five articles are typed in ARTICLES at the top of the file, and choosing one swaps the page's text in the block's own state; nothing is saved, synced or marked as read. Replace ARTICLES with your content and keep the same split: a link per article, one open at a time. The links go to # and a handler shows the article instead of navigating. They're SidebarMenuButtons with render set to an a element. Point them at your routes and mark the current one with isActive.

How does it work on a phone?

Below the medium breakpoint the sidebar is a sheet, whatever its collapsible value: the menu button opens it from the start edge, the right in a right-to-left layout, and Escape or choosing an article closes it and returns focus to the button. The slide-out and the measure are desktop behaviors, so the shortcut hint is hidden there and the article simply fills the window. The window keeps its height, and the status line at its foot says which article is open.

Is it accessible?

The rail is a navigation landmark named after the product, each shelf is named by its label, and the open article is marked as the current page; each link's name carries its reading time. When the rail slides out, its links leave the tab order and the reading order, and one polite status line says that the rail is hidden and what the page did. The article is a scrollable region you can reach with Tab, named by the page's heading. Motion is a short CSS transition that stops under reduced motion.

  • Pro

    Controlled State Sidebar

    State and theming

    A layout playground in a fixed-height window with a controlled sidebar: Open, Close, Toggle, a switch and Ctrl or Command with B all drive the provider, and every onOpenChange call is logged with where it came from.

  • Pro

    A team file manager in a fixed-height window with its sidebar on the end side: choose a file in the list and the sidebar shows its details, a Copy path button and a Close button, and on a phone it opens as a sheet.

  • Pro

    A hosting platform's settings console in a fixed-height window where the sidebar's width is the control: four presets set its CSS variable, and a measured count shows how many of ten long labels get cut at each.

  • Pro

    A mail client in a fixed-height window: mailboxes and labels whose counts follow the mail you file, a searchable message list beside the open message, and Compose for a local draft.

  • Pro

    Sidebar Toggle Navbar

    Mobile and drawers

    A navbar with a sidebar toggle for a project tracker: a button, the [ key and a tooltip fold a mini sidebar under the bar between icons only and icons with labels, and on phones the same button opens it as a sheet.

  • Pro

    Sticky Header Sidebar

    Headers and sections

    A store admin in a fixed-height window whose sidebar keeps its header and footer in place over eighteen scrolling pages, with a hairline that appears only while there is something to scroll, a filter, and a Back to top button.