A lightweight, flexible, and dependency-free JavaScript library for creating responsive side panels (drawers/slide menus).
SlideReveal.js is a lightweight, flexible, and dependency-free JavaScript class for creating responsive side panels (drawers/slide menus).
It supports overlays, push-body effects, filters, keyboard accessibility, and full customization through callbacks and options.
Browser support: Edge 12+, Chrome 45+, Firefox 44+, Safari 10+, IE — not supported
Disclaimer:
This library is not affiliated with the original jQuery SlideReveal (author: Natthawat Pongsri, MIT license).
SlideReveal.js is a modern, dependency-free, vanilla JS implementation with extended functionality for contemporary frontend projects.
Note for jQuery-based projects:
If your project already relies heavily on jQuery, you may prefer to use the original jQuery SlideReveal plugin for the best compatibility and integration.
This vanilla JS version is designed for dependency-free projects or for those migrating away from jQuery.
Special thanks to the original author:
Huge thanks to Natthawat Pongsri for the idea and the original jQuery implementation.
The motivation for this rewrite was the move away from jQuery and the need for a universal, lightweight solution.
- Left or right sliding panel (
position: 'left' | 'right'
) - Any width: px, %, vw, rem, em (
width: 320 | '80vw' | '70%' | ...
) - Overlay with configurable color and opacity
- Push body effect (moves content) or overlays content
- Content filter (e.g., blur, grayscale) when open
- Close on the outside click (without an overlay)
- ARIA accessibility support
- Callbacks: onInit, onOpen, onClose, onEscape
- No external dependencies (no jQuery!)
npm install slidereveal-js
Then import in your code:
import SlideReveal from 'slidereveal-js';
- Download
- Uncompressed
slidereveal.js
- Minified
slidereveal.min.js
- Uncompressed
- Add to your project and include via
<script src="slidereveal.min.js"></script>
if not using modules
<button class="toggle-button">Open Menu</button>
<div id="panel">
<h2>My Menu</h2>
<ul>
<li>Item 1</li>
<li>Item 2</li>
</ul>
</div>
const menu = new Slidereveal('#panel', {
position: 'right',
width: 320, // Supports '70vw', '80%', '300', etc.
pushBody: true,
overlay: true,
overlayColor: 'rgba(25,25,25,0.3)',
filter: true,
trigger: '.toggle-button', // CSS selector for open/close trigger
closeOnOutsideClick: true,
speed: 400,
ariaLabel: 'Side Menu',
onInit: () => console.log('Initialized!'),
onOpen: () => console.log('Panel opened!'),
onClose: () => console.log('Panel closed!'),
onEscape: () => console.log('Closed by Escape')
});
Warning: The behavior of the selector option in SlideReveal depends on your page layout.
- If you use a wrapper element selector (for example, #wrapper), only the content inside that container will be pushed or filtered.
- If you use body as the selector, SlideReveal will wrap all content inside (except the panel and overlay) into a wrapper to apply push/filter effects to the whole page.
Mixing different layouts and selectors may affect the appearance and behavior of your panel.
Case 1: Selector is a wrapper container
<!-- selector: #wrapper -->
<body>
<div id="wrapper">
<header>
<button class="toggle-panel">Trigger</button>
</header>
<article>
Any content here!
</article>
</div>
<div id="panel">
<h2>Menu</h2>
<ul>
<li>Item 1</li>
<li>Item 2</li>
</ul>
</div>
<script>
const menu = new SlideReveal('#panel', {
selector: '#wrapper'
});
</script>
</body>
Case 2: Selector is body
<!-- selector: body -->
<body>
<header>
<button class="toggle-panel">Trigger</button>
</header>
<article>
Body content here!
</article>
<div id="panel">
<h2>Menu</h2>
<ul>
<li>Item 1</li>
<li>Item 2</li>
</ul>
</div>
<script>
const menu = new SlideReveal('#panel', {
selector: 'body'
});
</script>
</body>
Best Practice:
Match your selector option to the actual main container of your content.
If your content is already inside a container (like #wrapper), use that selector. If not, use 'body' (default), but be aware that SlideReveal will wrap all body content except the panel and overlay.
Option | Type | Description | Default |
---|---|---|---|
width |
Number/String | Panel width (px , % , vw , rem , etc.) |
300 |
position |
String | 'left' or 'right' |
'right' |
pushBody |
Boolean | Pushes body content instead of overlaying | false |
overlay |
Boolean | Shows overlay under the panel | true |
overlayColor |
String | Overlay color (CSS value) | 'rgba(0,0,0,0.3)' |
filter |
Boolean | Applies CSS filter to page content (blur, etc) | false |
filterStyle |
String | CSS filter value (e.g., 'blur(2px)' ) |
'blur(2px)' |
closeOnOutsideClick |
Boolean | Closes panel when clicking outside (only if no overlay) | false |
selector |
String | Selector for affected content (normally 'body' ) |
'body' |
trigger |
String/HTMLElement | Selector or element for open/close trigger | null |
speed |
Number | Animation duration in ms | 400 |
autoEscape |
Boolean | Closes panel with Escape key | true |
zIndex |
Number | zIndex for panel (default) and body (default - 1) | 1050 |
ariaLabel |
String | ARIA label for accessibility | 'Menu' |
onInit |
Function | Callback after panel initialization | null |
onOpen |
Function | Callback after panel opens | null |
onClose |
Function | Callback after panel closes | null |
onEscape |
Function | Callback after closing by Escape | null |
Method | Description |
---|---|
open() |
Open the panel |
close() |
Close the panel |
toggle() |
Toggle the panel open/closed |
destroy() |
Remove all handlers and DOM changes |
<html>
<body class='slidereveal-open'>
<!-- panel -->
<div class='slidereveal-panel'>
<div class='slidereveal-panel-content'> ... </div>
</div>
<!-- body (selector) content -->
<div class='slidereveal-body'> ... </div>
<!-- overlay -->
<div class='slidereveal-overlay'></div>
</body>
</htmk>
Minimal CSS (if you want to further style or animate):
/* Example: style the overlay */
.slidereveal-overlay {
transition: opacity 0.3s;
/* You may override overlayColor via JS option */
}
/* Panel content styling (if needed) */
.slidereveal-panel-content {
box-sizing: border-box;
/* Add your custom styles */
}
Most styling is handled by JS inline styles; extra CSS is optional.
MIT — free for personal and commercial use.
- Mykhailo Kulyk
- Inspired by Natthawat Pongsri (original jQuery SlideReveal)