The default mode. Use state="offscreen" as the starting state; call expand() to open. Clicking the backdrop or pressing ESC closes it by default.
A simple overlay menu that opens from the left.
<k-aside state='offscreen'>
<p>Overlay Menu Content</p>
</k-aside>
<button onclick='this.previousElementSibling.expand()'> Open Menu </button>
Overlay Menu Content
By default clicking on the overlay backdrop closes the menu. Use overlay-close="false" to disable this. Pressing ESC also closes by default; use esc-close="false" to disable.
Use hide() to close the menu programmatically, or toggle() to switch between expanded and offscreen.
<k-aside state='offscreen' overlay-close='false'>
<p>Overlay Menu</p>
<button onclick='this.closest("k-aside").hide()'> Close </button>
</k-aside>
<button onclick='this.previousElementSibling.expand()'> Open Menu </button>
Overlay Menu
Use side="right" to open the menu from the right.
<k-aside state='offscreen' side='right'>
<p>Right Side Menu</p>
</k-aside>
<button onclick='this.previousElementSibling.expand()'> Open Right Menu </button>
Right Side Menu
Set main="push" so the aside pushes page content. It dispatches aside_state_change events on window that <k-main> listens to, adjusting its margins. The aside below will push this page's content when toggled.
A push-mode sidebar that shifts the page content. Click the button to toggle it.
<k-aside main='push' state='offscreen'>
<nav>
<h3>Sidebar</h3>
<a href='#'>Home</a>
<a href='#'>About</a>
<a href='#'>Contact</a>
</nav>
</k-aside>
<button onclick='this.previousElementSibling.toggle()'> Toggle Sidebar </button>
Use collapse() to show a narrow strip (width set by --collapsed-width). Use expand() to show full width, or hide() to go offscreen.
<k-aside main='push' state='offscreen'>
<nav>
<h3>Menu</h3>
<a href='#'>Dashboard</a>
<a href='#'>Settings</a>
</nav>
</k-aside>
<button onclick='aside.expand()'>Expand</button>
<button onclick='aside.collapse()'>Collapse</button>
<button onclick='aside.hide()'>Hide</button>
Use side="right" with push mode to have the sidebar on the right side of the viewport.
<k-aside main='push' side='right' state='offscreen'>
<nav>
<h3>Right Panel</h3>
<a href='#'>Item 1</a>
<a href='#'>Item 2</a>
</nav>
</k-aside>
<button onclick='this.previousElementSibling.toggle()'> Toggle Right Sidebar </button>
Override --width to change the expanded width. Default is 20rem.
<style>
k-aside {
--width: 30rem;
}
</style>
<k-aside state='offscreen'>
<p>This menu is 30rem wide.</p>
</k-aside>
<button onclick='this.previousElementSibling.expand()'> Open Wide Menu </button>
This menu is 30rem wide instead of the default 20rem.
Override --bg to change the background color.
<style>
k-aside {
--bg: var(--c_primary);
}
</style>
<k-aside state='offscreen'>
<nav class='p tc-light'>
<h3>Branded Menu</h3>
<a href='#' class='tc-light'>Home</a>
<a href='#' class='tc-light'>About</a>
</nav>
</k-aside>
<button onclick='this.previousElementSibling.expand()'> Open Branded Menu </button>
Override --collapsed-width to change the width of the narrow strip shown in collapsed state. Default is 3.5rem.
<style>
k-aside {
--collapsed-width: 5rem;
}
</style>
<k-aside main='push' state='offscreen'>
<nav>
<h3>Sidebar</h3>
<a href='#'>Dashboard</a>
<a href='#'>Reports</a>
<a href='#'>Settings</a>
</nav>
</k-aside>
<button onclick='aside.expand()'>Expand</button>
<button onclick='aside.collapse()'>Collapse</button>
<button onclick='aside.hide()'>Hide</button>
Use persistent-id to remember the aside's state across page loads. The state is saved to localStorage under the key aside-persistent-id-{id} and restored when the element is connected. Works with "expanded", "collapsed", and "offscreen" states.
<k-aside main='push' state='offscreen' persistent-id='my-nav'>
<nav>
<p>Sidebar Content</p>
</nav>
</k-aside>
<button onclick='this.previousElementSibling.expand()'>Expand</button>
<button onclick='this.previousElementSibling.collapse()'>Collapse</button>
<button onclick='this.previousElementSibling.hide()'>Hide</button>
Sidebar Content
Toggle the state and reload the page — it will be restored.
Use k-aside-item, k-aside-label, and k-aside-spacer inside a push-mode aside for a navigation panel with icons and text. Set --aside_padding: 0; on the aside so the sub-components control their own spacing.
Items and labels automatically react to the aside's collapsed/expanded state.
<k-aside main="push" state="expanded" style="--aside_padding: 0;">
<k-aside-toggle><h5 class="m-0">Kempo</h5></k-aside-toggle>
<k-aside-item icon="cards" href="#" active>Dashboard</k-aside-item>
<k-aside-item icon="check" href="#">Tasks</k-aside-item>
<k-aside-item icon="label" href="#">Email</k-aside-item>
<k-aside-label>Projects</k-aside-label>
<k-aside-item icon="folder" href="#">Figma Design</k-aside-item>
<k-aside-item icon="folder" href="#">Static Mania</k-aside-item>
<k-aside-spacer></k-aside-spacer>
<k-aside-item icon="settings" href="#">Settings</k-aside-item>
<k-aside-item icon="account-circle" href="#">Profile</k-aside-item>
</k-aside>
<k-main>
<h2>Main Content</h2>
<p>Content adjusts when panel opens/closes.</p>
</k-main>
Use k-aside-menu for collapsible sub-menus with an icon and label. When the aside is collapsed, clicking a menu icon expands the aside (unless no-expand is set).
<k-aside main="push" state="expanded" style="--aside_padding: 0;">
<k-aside-toggle><h5 class="m-0">Kempo</h5></k-aside-toggle>
<k-aside-item icon="cards" href="#">Dashboard</k-aside-item>
<k-aside-menu icon="folder" label="Projects">
<k-aside-item href="#">Website Redesign</k-aside-item>
<k-aside-item href="#">Mobile App</k-aside-item>
</k-aside-menu>
<k-aside-menu icon="settings" label="Settings">
<k-aside-item href="#">General</k-aside-item>
<k-aside-item href="#">Security</k-aside-item>
</k-aside-menu>
</k-aside>
The aside_state_change event fires on both the element and on window whenever the state changes. The event detail contains { aside, state, main }.
<k-aside id='myAside' state='offscreen'>
<p>Open and close me to see events.</p>
</k-aside>
<button onclick='myAside.expand()'>Open Menu</button>
<div id='log'></div>
<script>
myAside.addEventListener('aside_state_change', e => {
log.textContent = 'state: ' + e.detail.state;
});
</script>
Open and close me to see events.
new Aside()<k-main> so push-mode asides can shift the layout.state: stringThe current state. "expanded" (default) shows the full aside, "collapsed" shows a narrow strip (width set by --collapsed-width), "offscreen" hides it. Syncs to state attribute.
side: stringWhich side of the viewport to anchor to. "left" (default) or "right". Syncs to side attribute.
main: stringHow the aside interacts with page content. "overlay" (default) renders a backdrop and focus trap without affecting layout. "push" dispatches events so <k-main> adjusts its margins. Syncs to main attribute.
overlayClose: booleanWhether clicking the overlay backdrop closes the aside. Defaults to true. Syncs to overlay-close attribute.
escClose: booleanWhether pressing the ESC key closes the aside. Defaults to true. Syncs to esc-close attribute.
persistentId: string | nullWhen set, the aside's state is saved to localStorage under aside-persistent-id-{id} on every change, and restored when the element connects. Defaults to null. Syncs to persistent-id attribute.
aside_state_changeDispatched on the element and on window whenever state changes. Detail: { aside, state, main }.
expand(): voidSets state to "expanded".
collapse(): voidSets state to "collapsed".
hide(): voidSets state to "offscreen".
toggle(): voidToggles between "expanded" and "offscreen".
--widthWidth of the aside when expanded. Default 20rem.
--collapsed-widthWidth of the aside when collapsed. Default 3.5rem.
--bgBackground color. Default var(--c_bg).
--borderColor of the inner border. Default var(--c_border).
A navigation link that reacts to the parent aside's collapsed/expanded state. Shows icon + text when expanded, icon-only when collapsed.
| Attribute | Type | Default | Description |
|---|---|---|---|
icon | string | "" | Icon name (renders k-icon). Shows a dot when collapsed if no icon set. |
href | string | "#" | Link URL. |
active | boolean | false | Highlights the item with the primary color. |
no-expand | boolean | false | Prevents clicking a collapsed item from expanding the aside. |
hide-when-collapsed | boolean | false | Hides the item entirely when collapsed. |
A section label. Displays text when expanded, an <hr> divider when collapsed.
No additional attributes beyond automatic collapsed state syncing.
An expandable sub-menu that toggles open/closed. When the aside is collapsed, clicking the menu icon expands the aside.
| Attribute | Type | Default | Description |
|---|---|---|---|
icon | string | "" | Icon name for the menu header. |
label | string | "" | Text label for the menu header. |
open | boolean | false | Whether the sub-menu is expanded. |
no-expand | boolean | false | Prevents clicking a collapsed menu from expanding the aside. |
hide-when-collapsed | boolean | false | Hides the menu entirely when collapsed. |
Slot: Place k-aside-item elements inside for sub-menu links.
A flexible spacer (flex: 1) that pushes subsequent items to the bottom of the aside. No attributes.
A header with a collapse/expand toggle button. Renders an arrow icon that flips direction based on state. Place content (e.g. a logo) in the default slot; it hides when collapsed.
No additional attributes. Automatically syncs with the parent aside's state.