Floating, with sub-menus
The Sub-menus layout with variant="floating": on a desktop the sidebar is a panel with a margin all
round, rounded corners (in the vega skin) and a shadow, instead of a column along the edge of the screen. The
application’s CSS makes it wider (19 rem), puts more room between the sections and takes the line away from the
sub-menus. The page’s header has no border. On a phone the panel is the same as for every
variant.
Rendered HTML
<a class="skip-link" href="#main">Skip to main content</a><div class="sidebar-provider" x-data="slSidebar" data-state="expanded"> <nav class="sidebar" id="sidebar" popover aria-label="Main" data-variant="floating"> <div class="sidebar-header"> <ul class="sidebar-menu"> <li class="sidebar-menu-item"> <a class="sidebar-menu-button" data-size="lg" href="/"> <span class="app-logo"> <svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"> <path d="M7 2h10"></path> <path d="M5 6h14"></path> <rect width="18" height="12" x="3" y="10" rx="2"></rect> </svg> </span> <span class="sidebar-menu-button-label"> <strong>Documentation</strong> <small>v1.0.0</small> </span> </a> </li> </ul> </div> <div class="sidebar-content"> <div class="sidebar-group"> <ul class="sidebar-menu docs-nav"> <li class="sidebar-menu-item"> <a class="sidebar-menu-button" href="/getting-started"> <span class="sidebar-menu-button-label">Getting Started</span> </a> <ul class="sidebar-menu-sub docs-nav-sub"> <li class="sidebar-menu-sub-item"> <a class="sidebar-menu-sub-button" href="/getting-started/installation"> <span class="sidebar-menu-sub-button-label">Installation</span> </a> </li> <li class="sidebar-menu-sub-item"> <a class="sidebar-menu-sub-button" href="/getting-started/project-structure"> <span class="sidebar-menu-sub-button-label">Project Structure</span> </a> </li> </ul> </li> <li class="sidebar-menu-item"> <a class="sidebar-menu-button" href="/build"> <span class="sidebar-menu-button-label">Build Your Application</span> </a> <ul class="sidebar-menu-sub docs-nav-sub"> <li class="sidebar-menu-sub-item"> <a class="sidebar-menu-sub-button" href="/build/routing"> <span class="sidebar-menu-sub-button-label">Routing</span> </a> </li> <li class="sidebar-menu-sub-item"> <a class="sidebar-menu-sub-button" aria-current="page" href="/build/data-fetching"> <span class="sidebar-menu-sub-button-label">Data Fetching</span> </a> </li> <li class="sidebar-menu-sub-item"> <a class="sidebar-menu-sub-button" href="/build/rendering"> <span class="sidebar-menu-sub-button-label">Rendering</span> </a> </li> <li class="sidebar-menu-sub-item"> <a class="sidebar-menu-sub-button" href="/build/caching"> <span class="sidebar-menu-sub-button-label">Caching</span> </a> </li> <li class="sidebar-menu-sub-item"> <a class="sidebar-menu-sub-button" href="/build/styling"> <span class="sidebar-menu-sub-button-label">Styling</span> </a> </li> </ul> </li> <li class="sidebar-menu-item"> <a class="sidebar-menu-button" href="/api"> <span class="sidebar-menu-button-label">API Reference</span> </a> <ul class="sidebar-menu-sub docs-nav-sub"> <li class="sidebar-menu-sub-item"> <a class="sidebar-menu-sub-button" href="/api/components"> <span class="sidebar-menu-sub-button-label">Components</span> </a> </li> <li class="sidebar-menu-sub-item"> <a class="sidebar-menu-sub-button" href="/api/file-conventions"> <span class="sidebar-menu-sub-button-label">File Conventions</span> </a> </li> <li class="sidebar-menu-sub-item"> <a class="sidebar-menu-sub-button" href="/api/functions"> <span class="sidebar-menu-sub-button-label">Functions</span> </a> </li> </ul> </li> <li class="sidebar-menu-item"> <a class="sidebar-menu-button" href="/architecture"> <span class="sidebar-menu-button-label">Architecture</span> </a> <ul class="sidebar-menu-sub docs-nav-sub"> <li class="sidebar-menu-sub-item"> <a class="sidebar-menu-sub-button" href="/architecture/accessibility"> <span class="sidebar-menu-sub-button-label">Accessibility</span> </a> </li> <li class="sidebar-menu-sub-item"> <a class="sidebar-menu-sub-button" href="/architecture/fast-refresh"> <span class="sidebar-menu-sub-button-label">Fast Refresh</span> </a> </li> </ul> </li> <li class="sidebar-menu-item"> <a class="sidebar-menu-button" href="/community"> <span class="sidebar-menu-button-label">Community</span> </a> <ul class="sidebar-menu-sub docs-nav-sub"> <li class="sidebar-menu-sub-item"> <a class="sidebar-menu-sub-button" href="/community/contribution-guide"> <span class="sidebar-menu-sub-button-label">Contribution Guide</span> </a> </li> </ul> </li> </ul> </div> </div> </nav> <main class="sidebar-inset" id="main" tabindex="-1"> <header class="site-header"> <button class="button sidebar-trigger" type="button" data-variant="ghost" data-size="icon-sm" popovertarget="sidebar" aria-controls="sidebar" aria-label="Toggle sidebar"> <svg xmlns="http://www.w3.org/2000/svg" class="icon sidebar-trigger-icon" viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"> <rect width="18" height="18" x="3" y="3" rx="2"></rect> <path d="M9 3v18"></path> </svg> </button> <div class="separator" data-orientation="vertical" role="none"></div> <nav class="breadcrumb" aria-label="Breadcrumb"> <ol class="breadcrumb-list"> <li class="breadcrumb-item"> <a class="breadcrumb-link" href="/build">Build Your Application</a> </li> <li class="breadcrumb-separator" role="presentation" aria-hidden="true"> <svg xmlns="http://www.w3.org/2000/svg" class="icon breadcrumb-separator-icon" viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"> <path d="m9 18 6-6-6-6"></path> </svg> </li> <li class="breadcrumb-item"> <span class="breadcrumb-page" aria-current="page">Data Fetching</span> </li> </ol> </nav> </header> <div class="page"> <h1>Data Fetching</h1> <div class="placeholder-grid"> <div class="placeholder"></div> <div class="placeholder"></div> <div class="placeholder"></div> </div> <div class="placeholder placeholder-tall"></div> </div> </main></div>For reference: the shadcn/ui block this layout is based on.
The layout
Section titled “The layout”The whole layout file, with what every layout needs. The
sub-menus have a class of their own, docs-nav-sub, for the CSS below.
<!DOCTYPE html><html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:sl="https://shadleaf.dev/sl" th:fragment="layout(pageTitle, breadcrumb, content)"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title th:text="${pageTitle}">Page</title> <th:block th:replace="~{sl/layout :: theme-script}"></th:block> <th:block th:replace="~{sl/layout :: assets}"></th:block> <link rel="stylesheet" th:href="@{/css/application.css}"></head><body><sl:skip-link/><sl:sidebar-provider> <sl:sidebar variant="floating"> <sl:sidebar-header> <sl:sidebar-menu> <sl:sidebar-menu-item> <sl:sidebar-menu-button th:href="@{/}" size="lg"> <sl:slot name="icon-start"><span class="app-logo"><sl:icon name="gallery-vertical-end"/></span></sl:slot> <strong>Documentation</strong> <small>v1.0.0</small> </sl:sidebar-menu-button> </sl:sidebar-menu-item> </sl:sidebar-menu> </sl:sidebar-header> <sl:sidebar-content> <sl:sidebar-group> <sl:sidebar-menu class="docs-nav"> <sl:sidebar-menu-item> <sl:sidebar-menu-button th:href="@{/getting-started}" th:active="${#slNav.current('/getting-started', true)}"> Getting Started </sl:sidebar-menu-button> <sl:sidebar-menu-sub class="docs-nav-sub"> <sl:sidebar-menu-sub-item> <sl:sidebar-menu-sub-button th:href="@{/getting-started/installation}" th:active="${#slNav.current('/getting-started/installation')}"> Installation </sl:sidebar-menu-sub-button> </sl:sidebar-menu-sub-item> <sl:sidebar-menu-sub-item> <sl:sidebar-menu-sub-button th:href="@{/getting-started/project-structure}" th:active="${#slNav.current('/getting-started/project-structure')}"> Project Structure </sl:sidebar-menu-sub-button> </sl:sidebar-menu-sub-item> </sl:sidebar-menu-sub> </sl:sidebar-menu-item> <sl:sidebar-menu-item> <sl:sidebar-menu-button th:href="@{/build}" th:active="${#slNav.current('/build', true)}"> Build Your Application </sl:sidebar-menu-button> <sl:sidebar-menu-sub class="docs-nav-sub"> <sl:sidebar-menu-sub-item> <sl:sidebar-menu-sub-button th:href="@{/build/routing}" th:active="${#slNav.current('/build/routing')}"> Routing </sl:sidebar-menu-sub-button> </sl:sidebar-menu-sub-item> <sl:sidebar-menu-sub-item> <sl:sidebar-menu-sub-button th:href="@{/build/data-fetching}" th:active="${#slNav.current('/build/data-fetching')}"> Data Fetching </sl:sidebar-menu-sub-button> </sl:sidebar-menu-sub-item> <sl:sidebar-menu-sub-item> <sl:sidebar-menu-sub-button th:href="@{/build/rendering}" th:active="${#slNav.current('/build/rendering')}"> Rendering </sl:sidebar-menu-sub-button> </sl:sidebar-menu-sub-item> <sl:sidebar-menu-sub-item> <sl:sidebar-menu-sub-button th:href="@{/build/caching}" th:active="${#slNav.current('/build/caching')}"> Caching </sl:sidebar-menu-sub-button> </sl:sidebar-menu-sub-item> <sl:sidebar-menu-sub-item> <sl:sidebar-menu-sub-button th:href="@{/build/styling}" th:active="${#slNav.current('/build/styling')}"> Styling </sl:sidebar-menu-sub-button> </sl:sidebar-menu-sub-item> </sl:sidebar-menu-sub> </sl:sidebar-menu-item> <sl:sidebar-menu-item> <sl:sidebar-menu-button th:href="@{/api}" th:active="${#slNav.current('/api', true)}"> API Reference </sl:sidebar-menu-button> <sl:sidebar-menu-sub class="docs-nav-sub"> <sl:sidebar-menu-sub-item> <sl:sidebar-menu-sub-button th:href="@{/api/components}" th:active="${#slNav.current('/api/components')}"> Components </sl:sidebar-menu-sub-button> </sl:sidebar-menu-sub-item> <sl:sidebar-menu-sub-item> <sl:sidebar-menu-sub-button th:href="@{/api/file-conventions}" th:active="${#slNav.current('/api/file-conventions')}"> File Conventions </sl:sidebar-menu-sub-button> </sl:sidebar-menu-sub-item> <sl:sidebar-menu-sub-item> <sl:sidebar-menu-sub-button th:href="@{/api/functions}" th:active="${#slNav.current('/api/functions')}"> Functions </sl:sidebar-menu-sub-button> </sl:sidebar-menu-sub-item> </sl:sidebar-menu-sub> </sl:sidebar-menu-item> <sl:sidebar-menu-item> <sl:sidebar-menu-button th:href="@{/architecture}" th:active="${#slNav.current('/architecture', true)}"> Architecture </sl:sidebar-menu-button> <sl:sidebar-menu-sub class="docs-nav-sub"> <sl:sidebar-menu-sub-item> <sl:sidebar-menu-sub-button th:href="@{/architecture/accessibility}" th:active="${#slNav.current('/architecture/accessibility')}"> Accessibility </sl:sidebar-menu-sub-button> </sl:sidebar-menu-sub-item> <sl:sidebar-menu-sub-item> <sl:sidebar-menu-sub-button th:href="@{/architecture/fast-refresh}" th:active="${#slNav.current('/architecture/fast-refresh')}"> Fast Refresh </sl:sidebar-menu-sub-button> </sl:sidebar-menu-sub-item> </sl:sidebar-menu-sub> </sl:sidebar-menu-item> <sl:sidebar-menu-item> <sl:sidebar-menu-button th:href="@{/community}" th:active="${#slNav.current('/community', true)}"> Community </sl:sidebar-menu-button> <sl:sidebar-menu-sub class="docs-nav-sub"> <sl:sidebar-menu-sub-item> <sl:sidebar-menu-sub-button th:href="@{/community/contribution-guide}" th:active="${#slNav.current('/community/contribution-guide')}"> Contribution Guide </sl:sidebar-menu-sub-button> </sl:sidebar-menu-sub-item> </sl:sidebar-menu-sub> </sl:sidebar-menu-item> </sl:sidebar-menu> </sl:sidebar-group> </sl:sidebar-content> </sl:sidebar> <sl:sidebar-inset> <sl:site-header> <sl:sidebar-trigger/> <sl:separator orientation="vertical"/> <sl:breadcrumb> <sl:breadcrumb-list> <th:block th:replace="${breadcrumb}"></th:block> </sl:breadcrumb-list> </sl:breadcrumb> </sl:site-header> <div class="page"> <h1 th:text="${pageTitle}"></h1> <div th:replace="${content}"></div> </div> </sl:sidebar-inset></sl:sidebar-provider><div id="modal-root"></div><sl:toaster> <sl:toast th:each="toast : ${toasts}" th:title="${toast.title}" th:description="${toast.description}" th:variant="${toast.variant}" th:duration="${toast.duration}"/></sl:toaster></body></html>A page
Section titled “A page”A page passes its title, its breadcrumb’s levels and its content, as for the Sub-menus layout:
<html xmlns:th="http://www.thymeleaf.org" xmlns:sl="https://shadleaf.dev/sl" th:replace="~{layout/main :: layout('Data Fetching', ~{::breadcrumb}, ~{::#page-content})}"><body><th:block th:ref="breadcrumb"> <sl:breadcrumb-item> <sl:breadcrumb-link th:href="@{/build}">Build Your Application</sl:breadcrumb-link> </sl:breadcrumb-item> <sl:breadcrumb-separator/> <sl:breadcrumb-item> <sl:breadcrumb-page>Data Fetching</sl:breadcrumb-page> </sl:breadcrumb-item></th:block><div id="page-content"> ...</div></body></html>The CSS
Section titled “The CSS”The width is a token: --sidebar-width on .sidebar-provider replaces the skin’s 16 rem, and the floating panel’s
footprint follows it. Rules outside a cascade layer, as here, win over Shadleaf’s, which are in one.
/* The square behind the logo in the sidebar's header. */.app-logo { display: grid; place-items: center; flex-shrink: 0; inline-size: 2rem; block-size: 2rem; border-radius: calc(var(--radius) - 2px); background: var(--sidebar-primary); color: var(--sidebar-primary-foreground);}.app-logo > svg { inline-size: 1rem; block-size: 1rem; }
/* A wider sidebar, more room between the sections, the sub-menus without their line. */.sidebar-provider { --sidebar-width: 19rem; }.docs-nav { gap: 0.5rem; }.docs-nav > .sidebar-menu-item > .sidebar-menu-button { font-weight: 500; }.docs-nav-sub { margin-inline: 0; border-inline-start: 0; padding-inline: 0.375rem; }
/* The page's padding: the header above it has its own. */.page { padding: 0 1rem 1rem; }.page > h1 { margin-block-end: 1rem; font-size: 1.5rem; font-weight: 600; }