im trying to use preline ui offcanvas, when copy pasting the code given on their website, it works as expected, but since im also using bootstrap i need to use a prefix to avoid conflicts
<button type="button" class="tw-m-1 tw-ms-0 tw-py-3 tw-px-4 tw-inline-flex tw-items-center tw-gap-x-2 tw-text-sm tw-font-medium tw-rounded-lg tw-border tw-border-transparent tw-bg-blue-600 tw-text-white hover:tw-bg-blue-700 focus:tw-outline-none focus:tw-bg-blue-700 disabled:tw-opacity-50 disabled:tw-pointer-events-none" aria-haspopup="dialog" aria-expanded="false" aria-controls="hs-offcanvas-right" data-hs-overlay="#hs-offcanvas-right">
Toggle right offcanvas
</button>
<div id="hs-offcanvas-right" class="tw-hs-overlay hs-overlay-open:tw-translate-x-0 tw-hidden tw-translate-x-full tw-fixed tw-top-0 tw-end-0 tw-transition-all tw-duration-300 tw-transform tw-h-full tw-max-w-xs tw-w-full tw-z-[80] tw-bg-white tw-border-s dark:tw-bg-neutral-800 dark:tw-border-neutral-700" role="dialog" tabindex="-1" aria-labelledby="hs-offcanvas-right-label">
<div class="tw-flex tw-justify-between tw-items-center tw-py-3 tw-px-4 tw-border-b dark:tw-border-neutral-700">
<h3 id="hs-offcanvas-right-label" class="tw-font-bold tw-text-gray-800 dark:tw-text-white">
Offcanvas title
</h3>
<button type="button" class="tw-size-8 tw-inline-flex tw-justify-center tw-items-center tw-gap-x-2 tw-rounded-full tw-border tw-border-transparent tw-bg-gray-100 tw-text-gray-800 hover:tw-bg-gray-200 focus:tw-outline-none focus:tw-bg-gray-200 disabled:tw-opacity-50 disabled:tw-pointer-events-none dark:tw-bg-neutral-700 dark:tw-hover:bg-neutral-600 dark:tw-text-neutral-400 dark:tw-focus:bg-neutral-600" aria-label="Close" data-hs-overlay="#hs-offcanvas-right">
<span class="tw-sr-only">Close</span>
<svg class="tw-shrink-0 tw-size-4" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M18 6 6 18"></path>
<path d="m6 6 12 12"></path>
</svg>
</button>
</div>
<div class="tw-p-4">
<p class="tw-text-gray-800 dark:tw-text-neutral-400">
Some text as placeholder. In real life you can have the elements you have chosen. Like, text, images, lists, etc.
</p>
</div>
</div>
I've replaced every class with the prefix, I have also made sure that the prefix exists in tailwind.config.js and important is set to true.
The problem is multifaceted. Every solution below must be applied to fix your issue.
In the JavaScript initialization for off-canvases, it searches for the hs-overlay
class:
document
.querySelectorAll('.hs-overlay:not(.--prevent-on-load-init)')
.forEach((el: HTMLElement) => {
if (
!window.$hsOverlayCollection.find(
(elC) => (elC?.element?.el as HTMLElement) === el,
)
)
new HSOverlay(el);
});
Hence the class on the off-canvas should be hs-overlay
, not tw-hs-overlay
:
<div id="hs-offcanvas-right" class="hs-overlay …">
hidden
class togglingThe JavaScript assumes we're using unprefixed Tailwind classes:
this.hiddenClass = concatOptions?.hiddenClass || 'hidden';
But the lines before this allow us to override this:
const data = el.getAttribute('data-hs-overlay-options');
const dataOptions: IOverlayOptions = data ? JSON.parse(data) : {};
const concatOptions = {
...dataOptions,
...toggleDataOptions,
...options,
};
So we can configure the overlay as follows using the data-hs-overlay-options
for our prefixed tw-hidden
class instead:
<div
id="hs-offcanvas-right"
class="…"
data-hs-overlay-options='{"hiddenClass":"tw-hidden"}'
>
hs-overlay-open
usageWhen the off-canvas is opened, the open
and opened
classes are added to the element:
this.el.classList.add('open', 'opened');
The hs-overlay-open
variant corresponds to the open
class:
addVariant('hs-overlay-open', [
({ modifySelectors, separator }) => {
modifySelectors(({ className }) => {
return `.open.${e(`hs-overlay-open${separator}${className}`)}`;
});
},
However, with the Tailwind prefix
, Tailwind adds the prefix
string to open
:
.tw-open.hs-overlay-open\:tw-translate-x-0 {
This means these classes won't apply even when the open
class is present. There is no API in Tailwind or Preline to modify this. So we would need to change the hs-overlay-open:
variant usage for perhaps an arbitrary variant that targets the open
class:
<div id="hs-offcanvas-right" class="hs-overlay [&.open]:tw-translate-x-0 …">
Here's a working StackBlitz project with all the above solutions applied.