---
+## Off-canvas Scrollbox
+
+Placing scrollable elements within an off-canvas if `contentScroll: false` is tricky because on touch devices it may become difficult to scroll those elements due to stopped event propagation. There's no continous touch move possible.
+
+However you can still achieve this when you add `data-off-canvas-scrollbox` to the scrollable elements.
+Once you've reached the start/end of a scrollbox (while touch moving) the off-canvas will continue scrolling the off-cannvas element. You can optionally use a wrapper with `data-off-canvas-scrollbox-outer` which gets scrolled instead of the off-canvas element. This is useful when you nest your scrollable elements into other scrollable elements or work with fix heights.
+
+```html_example
+<div class="off-canvas-wrapper">
+ <div class="off-canvas-content" data-off-canvas-content style="min-height: 300px;">
+ <div class="grid-x">
+ <div class="cell">
+ <div class="primary callout">
+ You have to view this example on a touch device or use e.g. the chrome dev tools with touch emulation.
+ </div>
+ <button type="button" class="button" data-toggle="offCanvasScrollbox">
+ Open Scrollbox Off-canvas
+ </button>
+ </div>
+ </div>
+ <div class="off-canvas-absolute position-left" id="offCanvasScrollbox" data-off-canvas data-content-scroll="false">
+ <div style="padding: 0 1rem;">
+ <article data-off-canvas-scrollbox style="max-height: 290px; overflow: auto; padding: 0.5rem 0; margin-bottom: 1rem; box-shadow: inset 0 -10px 10px -10px rgba(0,0,0,0.65);">
+ <p>The 1st list supports continuous touchmove</p>
+ <ul>
+ <li>bullet 01</li>
+ <li>bullet 02</li>
+ <li>bullet 03</li>
+ <li>bullet 04</li>
+ <li>bullet 05</li>
+ <li>bullet 06</li>
+ <li>bullet 07</li>
+ <li>bullet 08</li>
+ <li>bullet 09</li>
+ <li>bullet 10</li>
+ </ul>
+ </article>
+ <article style="max-height: 290px; overflow: auto; padding: 0.5rem 0; margin-bottom: 1rem; box-shadow: inset 0 -10px 10px -10px rgba(0,0,0,0.65);">
+ <p>The 2nd list doesn't support continuous touchmove</p>
+ <ul>
+ <li>bullet 01</li>
+ <li>bullet 02</li>
+ <li>bullet 03</li>
+ <li>bullet 04</li>
+ <li>bullet 05</li>
+ <li>bullet 06</li>
+ <li>bullet 07</li>
+ <li>bullet 08</li>
+ <li>bullet 09</li>
+ <li>bullet 10</li>
+ </ul>
+ </article>
+ <article style="padding: 0.5rem 0;">
+ <p>The 3rd list is regular content</p>
+ <ul>
+ <li>bullet 01</li>
+ <li>bullet 02</li>
+ <li>bullet 03</li>
+ <li>bullet 04</li>
+ <li>bullet 05</li>
+ <li>bullet 06</li>
+ <li>bullet 07</li>
+ <li>bullet 08</li>
+ <li>bullet 09</li>
+ <li>bullet 10</li>
+ </ul>
+ </article>
+ </div>
+ </div>
+ </div>
+</div>
+```
+
+---
+
+ ## Sticky
+
+ By default an element with `position: fixed` disappears when opening an off-canvas with push transition. The reason for this is the transform property of the off-canvas content container what causes a `position: absolute` behavior for the fixed element.
+
+ The good news: we've added the possibility to preserve the fixed appearance!
+ You only have to add the attribute `data-off-canvas-sticky` to every sticky / fixed element that is supposed to remain fixed after opening the off-canvas.
+
+ <div class="callout warning">
+ Please note that using this attribute will force the option `contentScroll: false`
+ </div>
+
+ ```html
+ <div class="top-bar sticky" data-sticky data-off-canvas-sticky>
+ Sticky top bar that will remain sticky after having opened an off-canvas
+ </div>
+ ```
+
+ ---
+
## Off-canvas Sizes
In v6.4.2 the type of the off-canvas size variables has changed from number to map. This lets you define breakpoint specific sizes instead of one value for all.
this.$triggers.attr('aria-expanded', 'false');
- if (this.options.trapFocus === true) {
- this.$content.removeAttr('tabindex');
- Keyboard.releaseFocus(this.$element);
- }
- // Listen to transitionEnd and add class when done.
- this.$element.one(transitionend(this.$element), function(e) {
- _this.$element.addClass('is-closed');
- _this._removeContentClasses();
+ // Listen to transitionEnd: add class, re-enable scrolling and release focus when done.
+ this.$element.one(transitionend(this.$element), (e) => {
+
+ this.$element.addClass('is-closed');
+ this._removeContentClasses();
+
+ if (this.options.transition === 'push') {
+ this._unfixStickyElements();
+ }
+
+ // If `contentScroll` is set to false, remove class and re-enable scrolling on touch devices.
+ if (this.options.contentScroll === false) {
+ $('body').removeClass('is-off-canvas-open').off('touchmove', this._stopScrolling);
+ this.$element.off('touchstart', this._recordScrollable);
+ this.$element.off('touchmove', this._stopScrollPropagation);
++ this.$element.off('touchstart', '[data-off-canvas-scrollbox]', this._recordScrollable);
++ this.$element.off('touchmove', '[data-off-canvas-scrollbox]', this._stopScrollPropagation);
+ }
+
+ if (this.options.trapFocus === true) {
+ this.$content.removeAttr('tabindex');
+ Keyboard.releaseFocus(this.$element);
+ }
+
/**
- * Fires when the off-canvas menu is closed.
+ * Fires when the off-canvas menu close transition is done.
* @event OffCanvas#closed
*/
- _this.$element.trigger('closed.zf.offCanvas');
+ this.$element.trigger('closed.zf.offCanvas');
});
}