Skip to content

Repository files navigation

NPM Version

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 --><scriptsrc="https://cdn.jsdelivr.net/npm/@components-1812/offcanvas@0.0.3/dist/index.min.js"></script><!-- ES module --><scripttype="module">import"https://cdn.jsdelivr.net/npm/@components-1812/offcanvas@0.0.3/dist/index.min.js";</script>

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

<scripttype="module">importOffcanvasfrom"https://cdn.jsdelivr.net/npm/@components-1812/offcanvas@0.0.3/src/Offcanvas.min.js";// Load the stylesheet from a CDNOffcanvas.stylesSheets.links.push("https://cdn.jsdelivr.net/npm/@components-1812/offcanvas@0.0.3/src/Offcanvas.min.css");//Define with the default tagOffcanvas.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-offcanvasopenvariant="right global" handle-button><!-- Panel content --><divslot="header">Header</div><div><p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam, quod.</p></div><divslot="footer">Footer</div><!--Custom icons --><divslot="close-button"></div><divslot="handle-button" data-rotate-icon>➡️</div><!-- Backdrop content --><divslot="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:

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

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

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

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

    importOffcanvasfrom"@components-1812/offcanvas/Offcanvas.js";//Add the url source stylesheets to the componentOffcanvas.stylesSheets.links.push('https://cdn.example.com/Offcanvas.css');//Define the component manuallycustomElements.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:01px3px0#3c40434d,04px8px3px#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:1px03px0#3c40434d,4px08px3px#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-offcanvasopen></custom-offcanvas>

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

constoffcanvas=document.querySelector('custom-offcanvas');// Open the paneloffcanvas.open=true;// Close the paneloffcanvas.open=false;

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

constoffcanvas=document.querySelector('custom-offcanvas');// Show the paneloffcanvas.show();// Hide the paneloffcanvas.hide();// Toggle the panel (switch state)offcanvas.toggle();// toggle current stateoffcanvas.toggle(true);// force openoffcanvas.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-offcanvasopenvariant="right" handle-button><divslot="header">Header</div><div><p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam, quod.</p></div><divslot="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-offcanvasopenvariant="right" handle-button><divslot="close-button"></div><divslot="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-offcanvasopenvariant="left" handle-button><!-- Backdrop content --><divslot="backdrop" style="position: absolute; top: 0; left: 0;"><p>This is the backdrop content.</p><p>You can add any content here.</p></div><divslot="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-offcanvasopenvariant="left" handle-button><!-- Backdrop content --><divslot="backdrop" style="position: absolute; top: 0; right: 0;" data-hide-when-closed><p>This content will hide when the offcanvas is closed.</p></div><divslot="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

Parts

This custom element exposes the following Shadow DOM parts:

  • panel
  • panel-content
  • panel-header
  • panel-body
  • panel-footer
  • close-button
  • handle-button
  • backdrop

These parts can be styled with the ::part() selector, giving you full control over their appearance beyond the provided CSS variables.

For example, you can customize scrollbars inside the panel:

<custom-offcanvasopenvariant="right scroll-full" handle-button></custom-offcanvas><style>custom-offcanvas {
--sb-track-color:#232E33;
--sb-thumb-color:#6BAF8D;
--sb-size:14px;
}
custom-offcanvas::part(panel-content)::-webkit-scrollbar {
width:var(--sb-size);
}
custom-offcanvas::part(panel-content)::-webkit-scrollbar-track {
background:var(--sb-track-color);
border-radius:3px;
}
custom-offcanvas::part(panel-content)::-webkit-scrollbar-thumb {
background:var(--sb-thumb-color);
border-radius:3px;
}
</style>

See the example: 8 - Styling scroll bars

Note

Use panel-content part when styling scrollbars for the scroll-full and scroll-inner variants.

Use panel-body part when styling scrollbars for the scroll-body variant.



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-offcanvasvariant="top global"></custom-offcanvas><!-- Positioned inside a container --><divclass="container" style="position: relative;"><custom-offcanvasvariant="left local"></custom-offcanvas></div>

Panel Placement

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

<custom-offcanvasvariant="left"></custom-offcanvas><custom-offcanvasvariant="right"></custom-offcanvas><custom-offcanvasvariant="top"></custom-offcanvas><custom-offcanvasvariant="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-offcanvasvariant="scroll-full"></custom-offcanvas><custom-offcanvasvariant="scroll-inner"></custom-offcanvas><custom-offcanvasvariant="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-offcanvasvariant="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-offcanvasvariant="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-offcanvasvariant="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 sourceadopted: [],//CSSStyleSheet instancesraw: [],//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: [newCSSStyleSheet()],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)

Parts

  • panel: The panel element

  • panel-content: The panel content

  • panel-header: The header of the panel

  • panel-footer: The footer of the panel

  • panel-body: The main content of the panel

  • close-button: The close button element

  • handle-button: The handle button element

  • backdrop: The backdrop element



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