OsirionStickySidebar
OsirionStickySidebar renders an aside that sticks below your header while the page scrolls and scrolls on its
own when its content is taller than the viewport. Use it for a table of contents or documentation navigation next to
long content. It is pure CSS, so it works under static SSR without script.
Package Osirion.Blazor.Core, namespace Osirion.Blazor.Components. Source on GitHub.
@using Osirion.Blazor.Components
@* Scroll inside the frame: the sidebar stays in view while the sample text moves. The frame stands in for the
viewport, so the sidebar's height is capped here instead of filling the viewport as it does on a page. *@
<style>
.sticky-sidebar-demo aside.osirion-sticky-sidebar {
height: auto;
max-height: 11rem;
}
</style>
<div class="sticky-sidebar-demo"
role="region"
aria-label="Scrollable sample page"
tabindex="0"
style="height: 16rem; overflow-y: auto; border: 1px solid var(--osirion-border-color, #d1d5db); border-radius: 0.5rem; padding: 1rem; --osirion-header-height: 0.5rem;">
<div style="display: grid; grid-template-columns: 12rem 1fr; gap: 1.5rem; align-items: start;">
<OsirionStickySidebar>
<nav aria-label="Layout components">
<ul style="list-style: none; margin: 0; padding: 0;">
<li><a href="/components/page-layout">OsirionPageLayout</a></li>
<li><a href="/components/footer">OsirionFooter</a></li>
<li><a href="/components/sticky-sidebar">OsirionStickySidebar</a></li>
<li><a href="/components/page-loading">OsirionPageLoading</a></li>
<li><a href="/components/background-pattern">OsirionBackgroundPattern</a></li>
</ul>
</nav>
</OsirionStickySidebar>
<article>
@for (var section = 1; section <= 6; section++)
{
<h3>Sample section @section</h3>
<p>Sample text that makes the page taller than the frame. It says nothing about any product; it only gives the sidebar something to stay beside while you scroll.</p>
}
</article>
</div>
</div>Scroll inside the frame to see the sidebar stay in view. The frame stands in for the viewport, so the demo caps the sidebar's height at 11 rem; on a page it fills the viewport below the header. At 768 pixels wide or less the sidebar is static and flows with the page, so on a phone it scrolls away with the text.
Usage
@using Osirion.Blazor.Components
<div class="docs-grid">
<article>
<h1>Installation</h1>
</article>
<OsirionStickySidebar>
<nav aria-label="Documentation">
<a href="/docs/installation">Installation</a>
<a href="/docs/configuration">Configuration</a>
</nav>
</OsirionStickySidebar>
</div>
The CMS article page uses it the same way for its table of contents. Give the sidebar a column in a grid or flex
layout; position: sticky only takes effect while the parent is taller than the sidebar and no ancestor between
them sets overflow: hidden.
When your header is taller than 2.5rem, set TopOffset in pixels (<OsirionStickySidebar TopOffset="64">), or set the
custom property the stylesheet reads, which applies while TopOffset is left at its default:
.docs-grid {
--osirion-header-height: 4rem;
}
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
ChildContent |
RenderFragment? |
null |
The content of the aside element. |
TopOffset |
int |
40 |
The offset from the top of the viewport, in pixels (default 40, which is 2.5rem). A value other than the default is written to the aside as --osirion-header-height; at the default the stylesheet decides, so a site that sets the custom property itself keeps working. |
HideScrollbar |
bool |
true |
Whether the scrollbar is hidden (class osirion-no-scrollbar). The sidebar still scrolls with the wheel, touch and keyboard. |
IsSticky |
bool |
true |
Whether the sidebar sticks below the header. false adds osirion-non-sticky, which renders a normal, static aside with its natural height. |
Theme |
ThemeMode |
ThemeMode.System |
The component's color mode. Light or Dark writes it to data-theme (data-bs-theme under Bootstrap) on the root element; System writes nothing. |
Class |
string? |
null |
Extra CSS classes for the component's root element. |
Style |
string? |
null |
An inline style for the component's root element. |
A TopOffset other than the default is written to the aside as an inline --osirion-header-height, which wins over
a value set in CSS. Style, Theme and unmatched attributes are not applied to the markup.
Behavior
- Sticky area. The
asideisposition: stickywithtopandheightderived from--osirion-header-height(default2.5rem), so it fills the viewport below the header and scrolls internally (overflow-y: auto). - Small screens. At 768 pixels wide or less the sidebar is static, with its natural height and no scroll area of its own, so it flows with the page. Hide or move it with your own CSS if a mobile layout needs that.
- Motion. Smooth scrolling inside the sidebar is turned off when the visitor prefers reduced motion.
- Accessibility. The element is an
aside, a complementary landmark. Put a labellednavinside it when it holds navigation, as in the example, so screen reader users can tell several landmarks apart. WithHideScrollbar, make sure the content is reachable by keyboard (links are) because there is no visible scrollbar to drag.
Styling
| Class or property | Purpose |
|---|---|
osirion-sticky-sidebar |
The aside. |
osirion-no-scrollbar |
Added by HideScrollbar. |
osirion-non-sticky |
Added when IsSticky is false. |
--osirion-header-height |
Top offset and height reduction, default 2.5rem. |
--osirion-scrollbar-thumb, --osirion-scrollbar-thumb-hover |
Scrollbar thumb colors in WebKit browsers when the scrollbar is shown. |