Drawer
Side panel using the native HTML <dialog> element. Slides in from the left or right.
Basic drawer
Section titled “Basic drawer”<dialog class="af-drawer" id="my-drawer">
<div class="af-drawer-header">
<h3>
Navigation
</h3>
<button class="af-btn af-btn-icon" aria-label="Close"
onclick="this.closest('dialog').close()">
×
</button>
</div>
<div class="af-drawer-body">
<ul class="af-side-nav">
<li class="af-side-nav-item">
<a href="#" class="af-side-nav-link" aria-current="page">
Dashboard
</a>
</li>
<li class="af-side-nav-item">
<a href="#" class="af-side-nav-link">
Settings
</a>
</li>
<li class="af-side-nav-item">
<a href="#" class="af-side-nav-link">
Account
</a>
</li>
</ul>
</div>
</dialog>
<button class="af-btn"
onclick="document.getElementById('my-drawer').showModal()">
Open Drawer
</button>Preview
Section titled “Preview”Right-side drawer
Section titled “Right-side drawer”Add af-drawer-right to open from the right edge:
<dialog class="af-drawer af-drawer-right" id="filters-drawer">
<div class="af-drawer-header">
<h3>
Filters
</h3>
<button class="af-btn af-btn-icon" aria-label="Close"
onclick="this.closest('dialog').close()">
×
</button>
</div>
<div class="af-drawer-body">
<div class="af-stack af-gap-md">
<div class="af-field">
<label class="af-label" for="filter-status">
Status
</label>
<select id="filter-status" class="af-select">
<option>
All
</option>
<option>
Active
</option>
<option>
Archived
</option>
</select>
</div>
<div class="af-field">
<label class="af-label" for="filter-date-range">
Date range
</label>
<input id="filter-date-range" class="af-input" type="date">
</div>
<button class="af-btn">
Apply Filters
</button>
</div>
</div>
</dialog>
<button class="af-btn"
onclick="document.getElementById('filters-drawer').showModal()">
Open Filters
</button>Same as dialog. Open with showModal(), close with close().
const drawer = document.getElementById('my-drawer');
drawer.showModal();
drawer.close();| Class | Purpose |
|---|---|
af-drawer | The <dialog> element. Opens from the left by default. |
af-drawer-right | Modifier. Opens from the right instead. |
af-drawer-header | Header row with title and close button |
af-drawer-body | Scrollable content area |
Closing on backdrop click
Section titled “Closing on backdrop click”drawer.addEventListener('click', (e) => {
if (e.target === drawer) drawer.close();
});Accessibility
Section titled “Accessibility”Same accessibility model as dialog. Native <dialog> with showModal() marks the page as inert and provides ESC key and body scroll lock. Focus trapping and focus restoration require supplemental JS for full cross-browser reliability.