Basic Sidebar
A static navigation column - brand, icon-and-label links, and one clearly marked current page.
6 個のフレームワーク初級
A sidebar that animates between 15rem and 4rem, hiding its labels and leaving the icons behind.
<aside class="csidebar" data-collapsed="false">
<div class="csidebar__head">
<span class="csidebar__brand">Adysre</span>
<button
class="csidebar__toggle"
type="button"
aria-expanded="true"
aria-controls="csidebar-nav"
aria-label="Collapse sidebar"
>
<svg class="csidebar__chevron" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
<path d="M15 18l-6-6 6-6" />
</svg>
</button>
</div>
<nav class="csidebar__nav" id="csidebar-nav" aria-label="Sidebar">
<ul class="csidebar__list">
<li>
<a class="csidebar__link" href="/dashboard" aria-current="page">
<svg class="csidebar__icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
<rect x="3" y="3" width="7" height="7" rx="1" />
<rect x="14" y="3" width="7" height="7" rx="1" />
<rect x="14" y="14" width="7" height="7" rx="1" />
<rect x="3" y="14" width="7" height="7" rx="1" />
</svg>
<span class="csidebar__label">Dashboard</span>
</a>
</li>
<li>
<a class="csidebar__link" href="/projects">
<svg class="csidebar__icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
<path d="M3 7a2 2 0 0 1 2-2h3l2 2h9a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2Z" />
</svg>
<span class="csidebar__label">Projects</span>
</a>
</li>
<li>
<a class="csidebar__link" href="/team">
<svg class="csidebar__icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
<circle cx="9" cy="8" r="3" />
<path d="M3 20a6 6 0 0 1 12 0" />
<path d="M16 5.5a3 3 0 0 1 0 5" />
<path d="M18 20a6 6 0 0 0-2-4.5" />
</svg>
<span class="csidebar__label">Team</span>
</a>
</li>
</ul>
</nav>
</aside>
<script>
document.querySelectorAll('.csidebar').forEach(function (root) {
var toggle = root.querySelector('.csidebar__toggle');
toggle.addEventListener('click', function () {
var expanded = toggle.getAttribute('aria-expanded') === 'true';
toggle.setAttribute('aria-expanded', String(!expanded));
toggle.setAttribute('aria-label', expanded ? 'Expand sidebar' : 'Collapse sidebar');
root.dataset.collapsed = String(expanded);
});
});
</script>| Prop | 型 | デフォルト | 説明 |
|---|---|---|---|
items必須 | SidebarItem[] | - | レンダリングする項目の配列。 |
pathname必須 | string | - | 現在のパス。一致する項目が現在のページとして示されます。 |
title | string | 'Adysre' | カードの見出しテキスト。 |
duration | number | 200 | アニメーションの長さ(秒)。 |
className | string | - | ルート要素にマージされる追加クラス。 |
The toggle is a real button with `aria-expanded` and `aria-controls` - the chevron rotation hangs off `aria-expanded` too, so the arrow physically cannot point the wrong way. The labels hide with `invisible` *and* `opacity-0`, never `opacity-0` alone: a label that is merely transparent is still read aloud and still counted by a screen reader, so the collapsed rail would announce four names it does not show. `visibility` also rides the same transition, which `display: none` cannot. Width animates via `transition-[width]` rather than `transform`, because the page content beside it must actually reflow - a transform would slide the sidebar over the content instead of making room. `motion-reduce:transition-none` lands on the end state instantly for anyone who asked for less motion; the collapse still works, it just does not travel. Persist the state to `localStorage` if you want it to survive a reload.