Skip to content

App Shell

Examples for the ss-l-app layout: a full-height frame with a header, optional left and right sidebars, a main viewport and an optional status bar. Size it with --ss-app-header-height, --ss-app-sidebar-width (or -left-width / -right-width) and --ss-app-footer-height.

On a page the shell fills the viewport (100dvh); the examples below use ss-l-app--contained to fill a sized box instead. Below the md breakpoint the sidebars are hidden and open as overlays when their data-state is "open"; "closed" hides them at every width. SheetManager toggles the state from any button with data-ss-sheet-toggle.

Header, sidebars, viewport and status bar

Spatial viewer ← All demos

Inspector

HTML
<div style="height: 420px; border: 1px solid var(--ss-color-border)">
            <div class="ss-l-app ss-l-app--contained" style="--ss-app-sidebar-width: 200px">
                <div class="ss-l-app__header">
                    <button type="button" class="ss-c-button ss-c-button--ghost ss-c-button--sm"
                            data-ss-sheet-toggle aria-controls="demo-app-nav">Menu</button>
                    <strong>Spatial viewer</strong>
                    <span class="ss-l-app__spacer"></span>
                    <a class="ss-c-button ss-c-button--ghost ss-c-button--sm" href="#">&larr; All demos</a>
                </div>
                <nav class="ss-l-app__sidebar" id="demo-app-nav" aria-label="Layers">
                    <ul style="margin: 0; padding: var(--ss-space-4); list-style: none">
                        <li>Buildings</li>
                        <li>Roads</li>
                        <li>Water</li>
                    </ul>
                </nav>
                <div class="ss-l-app__main ss-l-app__main--bleed">
                    <div class="ss-l-app__fill" style="background: var(--ss-color-surface-2)"></div>
                </div>
                <div class="ss-l-app__sidebar ss-l-app__sidebar--right" role="region" aria-label="Inspector">
                    <p style="margin: 0; padding: var(--ss-space-4)">Inspector</p>
                </div>
                <div class="ss-l-app__footer ss-t-text-sm">
                    <span>Lon 5.2913</span><span>Lat 52.1326</span><span>Zoom 14</span>
                </div>
            </div>
        </div>

Collapsed sidebar

data-state="closed" hides a sidebar; the main area takes its space.

Viewer
Main viewport
HTML
<div style="height: 240px; border: 1px solid var(--ss-color-border)">
            <div class="ss-l-app ss-l-app--contained">
                <div class="ss-l-app__header"><strong>Viewer</strong></div>
                <nav class="ss-l-app__sidebar" data-state="closed" aria-label="Scene tree">…</nav>
                <div class="ss-l-app__main" style="padding: var(--ss-space-4)">Main viewport</div>
            </div>
        </div>

Resizable sidebar

A ss-c-split__handle--edge inside the sidebar, driven by SplitPaneManager, writes the sidebar width to --ss-app-sidebar-left-width on the shell (data-ss-split-root).

IFC viewer
HTML
<div style="height: 240px; border: 1px solid var(--ss-color-border)">
            <div class="ss-l-app ss-l-app--contained" data-ss-split-root>
                <div class="ss-l-app__header"><strong>IFC viewer</strong></div>
                <nav class="ss-l-app__sidebar" id="demo-app-tree" aria-label="Model tree">
                    <p style="margin: 0; padding: var(--ss-space-4)">Model tree</p>
                    <div class="ss-c-split__handle ss-c-split__handle--edge" role="separator" tabindex="0"
                         aria-orientation="vertical" aria-controls="demo-app-tree"
                         aria-valuenow="25" aria-valuemin="15" aria-valuemax="50"
                         aria-label="Resize model tree"
                         data-ss-split-property="--ss-app-sidebar-left-width"
                         data-ss-split-unit="px"></div>
                </nav>
                <div class="ss-l-app__main ss-l-app__main--bleed">
                    <canvas aria-label="3D view" style="background: var(--ss-color-surface-2)"></canvas>
                </div>
            </div>
        </div>

Padded sidebar

A sidebar has no inner padding by default, so content that sets its own spacing is not doubled. Add ss-l-app__sidebar--padded for the standard inner padding (--ss-space-4) when the content has none.

Viewer
Main viewport
HTML
<div style="height: 200px; border: 1px solid var(--ss-color-border)">
            <div class="ss-l-app ss-l-app--contained">
                <div class="ss-l-app__header"><strong>Viewer</strong></div>
                <aside class="ss-l-app__sidebar ss-l-app__sidebar--padded" aria-label="Details">
                    <p style="margin: 0">Content without its own padding.</p>
                </aside>
                <div class="ss-l-app__main" style="padding: var(--ss-space-4)">Main viewport</div>
            </div>
        </div>