npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@components-1812/offcanvas

v0.0.3

Published

A web component for custom offcanvas, lateral panel

Readme

Offcanvas custom element

Examples

Installation

NPM

npm install @components-1812/offcanvas

CDN

Load the component bundle directly from a CDN — this will automatically register the element and inject styles:

<!-- Classic script -->
<script src="https://cdn.jsdelivr.net/npm/@components-1812/[email protected]/dist/index.min.js"></script>

<!-- ES module -->
<script type="module">
  import "https://cdn.jsdelivr.net/npm/@components-1812/[email protected]/dist/index.min.js";
</script>

Alternatively, you can manually import, load the styles, and define the element yourself:

<script type="module">
  import Offcanvas from "https://cdn.jsdelivr.net/npm/@components-1812/[email protected]/src/Offcanvas.min.js";

  // Load the stylesheet from a CDN
  Offcanvas.stylesSheets.links.push(
    "https://cdn.jsdelivr.net/npm/@components-1812/[email protected]/src/Offcanvas.min.css"
  );

  //Define with the default tag
  Offcanvas.define();
</script>

Usage

Vite Ecosystem

If you are using Vite or a Vite-based framework such as Astro, you can import the component in a client-side script:

import '@components-1812/offcanvas';

and use it in your HTML:

<custom-offcanvas open variant="right global" handle-button>

    <!-- Panel content -->
    <div slot="header">Header</div>

    <div>
        <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam, quod.</p>
    </div>

    <div slot="footer">Footer</div>

    <!--Custom icons -->
    <div slot="close-button">❌</div>
    <div slot="handle-button" data-rotate-icon>➡️</div>

    <!-- Backdrop content -->
    <div slot="backdrop" style="position: absolute; top: 0; left: 0;">
        <p>This is the backdrop content.</p>
        <p>You can add any content here.</p>
    </div>
</custom-offcanvas>

Other Frameworks

If you are using a builder or framework that does not support importing with ?raw,

you can load and register the component using the bundle version in dist/index.min.js, which includes all CSS injected via CSS-in-JS and AdoptedStyleSheets:

import '@components-1812/offcanvas/dist/index.min.js';

For customizing the component definition or manually loading the stylesheets, see [Defining and Adding Stylesheets Manually](#Defining and Adding Stylesheets Manually).

Node

The dist folder includes minified versions: Offcanvas.min.css and Offcanvas.min.js, which can be used anywhere.

Defining and Adding Stylesheets Manually

If you want to add custom stylesheets to the component or need to load stylesheets from a different path, you can do it like this:

  • AdoptedStyleSheets (recommended)

    Using your builder’s import raw method, CSSStyleSheet, and the component’s AdoptedStyleSheets property:

    import Offcanvas from "@components-1812/offcanvas/Offcanvas.js";
    import OffcanvasRawCSS from "@components-1812/offcanvas/Offcanvas.css?raw";
    
    //Create a CSSStyleSheet and add it to the component
    const OffcanvasCSS = new CSSStyleSheet();
    
    OffcanvasCSS.replaceSync(OffcanvasRawCSS);
    
    Offcanvas.stylesSheets.adopted.push(OffcanvasCSS);
    
    //Define the component with default tag name
    Offcanvas.define();
  • Raw CSS in a <style> tag

    Using a <style> tag inside the shadow root of the component:

    import Offcanvas from "@components-1812/offcanvas/Offcanvas.js";
     
    //Add the raw stylesheet to the component
    const OffcanvasRawCSS = `:host {
        /* ...Offcanvas.css styles... */
    }`;
    
    Offcanvas.stylesSheets.raw.push(OffcanvasRawCSS);
    
    //Define the component custom tag name
    Offcanvas.define('other-custom-tag-name');
  • External CSS files in a <link> tag

    Using a <link> tag inside the shadow root of the component:

    import Offcanvas from "@components-1812/offcanvas/Offcanvas.js";
    
    //Add the url source stylesheets to the component
    Offcanvas.stylesSheets.links.push('https://cdn.example.com/Offcanvas.css');
    
    //Define the component manually
    customElements.define('custom-offcanvas', Offcanvas);

Customization: CSS Variables

--offcanvas-position: absolute;
--offcanvas-z-index: 8010;

/* Panel */
--offcanvas-panel-width: 300px;
--offcanvas-panel-height: 100%;
--offcanvas-panel-padding: 5px;
--offcanvas-panel-transition: margin 0.3s ease-in-out;

--offcanvas-panel-header-padding: 5px;
--offcanvas-panel-body-padding: 5px;
--offcanvas-panel-footer-padding: 5px;

--offcanvas-shadow: 0 1px 3px 0 #3c40434d, 0 4px 8px 3px #3c404326;

--offcanvas-panel-bg: #222;
--offcanvas-panel-color: #fff;
--offcanvas-panel-header-bg: var(--offcanvas-panel-bg);
--offcanvas-panel-header-color: var(--offcanvas-panel-color);
--offcanvas-panel-footer-bg: var(--offcanvas-panel-bg);
--offcanvas-panel-footer-color: var(--offcanvas-panel-color);

--offcanvas-panel-border-width: 1px;
--offcanvas-panel-border-style: solid;
--offcanvas-panel-border-color: #ccc;
--offcanvas-panel-border: var(--offcanvas-panel-border-width) var(--offcanvas-panel-border-style) var(--offcanvas-panel-border-color);

--offcanvas-panel-border-radius: 0px;

/* Backdrop */
--offcanvas-backdrop-bg: #00000080;
--offcanvas-backdrop-color: #fff;
--offcanvas-backdrop-transition: background-color 0.3s ease-in-out;

/* Close button */
--offcanvas-close-button-width: 40px;
--offcanvas-close-button-height: 40px;
--offcanvas-close-button-padding: 10px;

--offcanvas-close-button-bg: transparent;
--offcanvas-close-button-color: #fff;

--offcanvas-close-button-border: none;

--offcanvas-close-button-font-size: 1.5rem;
--offcanvas-close-button-cursor: pointer;

/* Handle button */
--offcanvas-handle-button-width: 50px;
--offcanvas-handle-button-height: 100px;
--offcanvas-handle-button-padding: 5px;

--offcanvas-handle-button-bg: #444;
--offcanvas-handle-button-color: #fff;

--offcanvas-handle-button-border: none;
--offcanvas-handle-button-border-radius: 10px;

--offcanvas-handle-button-cursor: pointer;
--offcanvas-handle-button-font-size: 1rem;
--offcanvas-handle-button-shadow: var(--offcanvas-shadow);

Top and Bottom Offcanvas

--offcanvas-panel-width: 100%;
--offcanvas-panel-height: 300px;

--offcanvas-handle-button-width: 100px;
--offcanvas-handle-button-height: 50px;

--offcanvas-panel-shadow: 1px 0 3px 0 #3c40434d, 4px 0 8px 3px #3c404326;

Responsive Panel

For responsive design, there will be times when you want the panel to occupy the full width of the screen, especially on mobile devices.

You can achieve this by adding a CSS media query like the following:

custom-offcanvas {
            
    @media (width <= 500px) {
        --offcanvas-panel-width: 100%;
    }
}

This will ensure that the offcanvas panel expands to the full screen width on devices with a width of 500px or less.

See the example: 7 - Panel responsive

Open and close

You can open the offcanvas panel using the open attribute:

<custom-offcanvas open></custom-offcanvas>

Via JavaScript, you can use the open property (mirrored attribute):

const offcanvas = document.querySelector('custom-offcanvas');

// Open the panel
offcanvas.open = true;

// Close the panel
offcanvas.open = false;

You can also control the panel with the methods: .show(), .hide(), .toggle()

const offcanvas = document.querySelector('custom-offcanvas');

// Show the panel
offcanvas.show();

// Hide the panel
offcanvas.hide();

// Toggle the panel (switch state)
offcanvas.toggle();         // toggle current state
offcanvas.toggle(true);     // force open
offcanvas.toggle(false);    // force close

Slots

The default slot is reserved for the panel body, which contains the main content.

You can also use the following named slots:

  • slot="header" – for the panel header.

  • slot="footer" – for the panel footer.

<custom-offcanvas open variant="right" handle-button>
    <div slot="header">Header</div>
    <div>
        <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam, quod.</p>
    </div>
    <div slot="footer">Footer</div>
</custom-offcanvas>

Customizing Buttons

You can replace the default icons for the close button and the handle button (if present) using:

  • slot="close-button"

  • slot="handle-button"

para modificar los iconos por defecto del close button y el handle button (si esta) puedes usar slot="close-button" y slot="handle-button"

<custom-offcanvas open variant="right" handle-button>
    <div slot="close-button">❌</div>
    <div slot="handle-button" data-rotate-icon>➡️</div>
</custom-offcanvas>

Note

For the handle button, you can add the attribute data-rotate-icon so that the icon always rotates to point in the correct direction according to the panel position and open/closed state.

To work correctly, the icon must initially point to the right.

Backdrop

The backdrop slot allows you to add custom content positioned around the panel for richer interactions or decorations.

Elements in this slot should use position: absolute;

Since the backdrop changes size when the panel opens or closes, the elements will move together with the panel.

<custom-offcanvas open variant="left" handle-button>

    <!-- Backdrop content -->
    <div slot="backdrop" style="position: absolute; top: 0; left: 0;">
        <p>This is the backdrop content.</p>
        <p>You can add any content here.</p>
    </div>

    <div slot="backdrop" style="position: absolute; bottom: 0; right: 0;">
        <p>This is another backdrop content.</p>
        <p>You can customize the backdrop as needed.</p>
    </div>
</custom-offcanvas>

You can also control the visibility of backdrop elements based on the panel state using attributes like:

  • data-hide-when-closed – hides the element when the panel is closed.

  • data-hide-when-opened – hides the element when the panel is open.

<custom-offcanvas open variant="left" handle-button>

    <!-- Backdrop content -->
    <div slot="backdrop" style="position: absolute; top: 0; right: 0;" data-hide-when-closed>
        <p>This content will hide when the offcanvas is closed.</p>
    </div>

    <div slot="backdrop" style="position: absolute; bottom: 0; left: 0;" data-hide-when-opened>
        <p>This content will hide when the offcanvas is opened.</p>
    </div>
</custom-offcanvas>

See the example: 5 - Backdrop content

Variants

Panel Global and Local Positioning

You can control whether the offcanvas panel is positioned relative to the viewport or inside its container using the variant attribute:

  • local (default) – The panel is positioned absolute relative to its nearest positioned ancestor.

  • global – The panel is positioned fixed relative to the viewport. This is useful for modals or overlays.

<!-- Fixed to the viewport -->
<custom-offcanvas variant="top global"></custom-offcanvas>

<!-- Positioned inside a container -->
<div class="container" style="position: relative;">
    <custom-offcanvas variant="left local"></custom-offcanvas>
</div>

Panel Placement

The variant attribute defines the position of the offcanvas panel: left, right, top, bottom

<custom-offcanvas variant="left"></custom-offcanvas>
<custom-offcanvas variant="right"></custom-offcanvas>
<custom-offcanvas variant="top"></custom-offcanvas>
<custom-offcanvas variant="bottom"></custom-offcanvas>

See the example: 2 - Panel placement

Panel Scroll

By default, the panel does not scroll. You can customize the scroll behavior using the following variants:

  • scroll-full: The entire panel content scrolls.

  • scroll-inner: All content scrolls except the header

  • scroll-body: Only the body scrolls; header and footer remain fixed.

<custom-offcanvas variant="scroll-full"></custom-offcanvas>
<custom-offcanvas variant="scroll-inner"></custom-offcanvas>
<custom-offcanvas variant="scroll-body"></custom-offcanvas>

See the example: 3 - Panel scroll

Handle button

By default, the component does not provide any control to open the panel; you must add it manually.

With the handle-button attribute, the component automatically adds a button inside the backdrop content, centered along the edge of the panel. This button allows users to open and close the panel.

<custom-offcanvas variant="right" handle-button></custom-offcanvas>

Static and Transparent Backdrop

  • backdrop-static: By default, clicking on the backdrop closes the panel.

    You can disable this behavior by adding the backdrop-static variant:

    <custom-offcanvas variant="backdrop-static"></custom-offcanvas>

    With this variant, clicking on the backdrop won’t close the panel, and the page behind it remains interactive while the panel is open.

  • backdrop-transparent

    If you want to hide the backdrop background when the panel is open, you have two options:

    • Override the CSS variable: --offcanvas-backdrop-bg
    • Or, more easily, use the backdrop-transparent variant:
    <custom-offcanvas variant="backdrop-transparent"></custom-offcanvas>

API

Attributes

  • variant: Panel position or visual style.

    • Panel position: left, top, right, bottom
    • Panel scroll: scroll-full, scroll-inner, scroll-body
    • Page position: global, local
  • open (boolean, default false): Whether the panel is open.

  • handle-button (boolean, default false): Whether to show a floating handle button.

Properties

Mirrored

  • variant (string): Panel position or visual style.

  • open (boolean): Whether the panel is open.

  • handleButton (boolean): Whether the handle button is visible.

Methods

show(): Opens the panel (open = true).

hide(): Closes the panel (open = false).

toggle(force?: boolean): Toggles the panel. If force is true or false, sets the panel state accordingly.

Events

  • ready-links: Fired when all external stylesheet links have finished loading. Provides a detail with the results of each stylesheet.

  • ready: Dispatched when the component has finished initializing (end of connectedCallback)

Static properties

  • VERSION (string): Component version (0.0.3).

  • DEFAULT_TAG_NAME (string): Default tag name (custom-offcanvas) use it to define the custom element in index.js and define.js

  • DEFAULT_ICONS (object): Default svg icons for close-button and handle-button.

    Offcanvas.DEFAULT_ICONS = {
        'close-button': `<svg>...</svg>`,
        'handle-button': `<svg data-rotate-icon>...</svg>`
    }
  • stylesSheets (object): Contains links, adopted, and raw stylesheets to apply to the component.

    Offcanvas.stylesSheets = {
        links: [],//string url css source
        adopted: [],//CSSStyleSheet instances
        raw: [],//string raw css
    };
  • define(tagName?, stylesSheets?) (function): Defines the custom element and optionally adds stylesheets if the element is not already registered.

    Offcanvas.define('custom-offcanvas', {
    
        links: ['https://cdn.example.com/Offcanvas.css'],
    
        adopted: [new CSSStyleSheet()],
    
        raw: [':host { /* ...Offcanvas.css styles... */ }'],
    });

    Internally, this method calls window.customElements.define(tagName, Offcanvas)

Slots

  • default: Main content of the panel

  • header: Header content of the panel

  • footer: Footer content of the panel

  • close-button: Icon or content for the close button in the header of the panel

  • handle-button: Icon or content for the handle button if added

  • backdrop: Content inside the backdrop (around the panel)

License

This package is distributed under the MIT license.

Credits

Default icons used in this package are sourced from the Bootstrap Icons project, licensed under the MIT license.
© 2019–2024 The Bootstrap Authors