This is a follow up from this question. Now, I am using the solution from this question in my Vue component, updated the collapse part and now it's a nested collapse with some collapse elements inside.
The issue now is that if I put !overflow-visible
on the main collapse, overriding it, the elements inside of it are not hidden anymore and they're overflowing from the collapse despite it being closed.
How can I solve this behaviour? I tried adding overflow-hidden
to the children of the collapse but because of inheritance, the overflow-hidden
doesn't do anything. Also one thing I noticed is that even though the collapse with the dropdown has a z-index
of 99
, it's not showing above everything else which it should do.
<template>
<div
v-for="index in 3"
tabindex="0"
class="collapse !overflow-visible collapse-plus z-0 rounded-lg border border-base-content bg-base-100 shadow-md md:w-[48.75%]"
:class="collapse ? 'collapse-open' : 'collapse-close'"
>
<div
class="collapse-title !overflow-hidden flex items-center text-lg font-medium"
:class="collapse ? 'bg-primary' : 'bg-base-100'"
@click="OnClick"
>
<div
class="mr-3 grid h-[58px] !overflow-hidden w-[62px] place-content-center rounded-lg"
:class="collapse ? 'bg-base-100' : 'bg-primary'"
></div>
<div
class="flex flex-col gap-1"
:class="collapse ? 'text-base-100' : 'text-primary'"
>
Test
<div class="badge badge-success rounded-[4px]">Active</div>
</div>
</div>
<div class="collapse-content bg-base-200 !p-0 text-accent">
<div
tabindex="0"
class="collapse collapse-open border border-base-300 bg-red-200 !overflow-visible"
>
<div class="collapse-title text-xl font-medium">
I have collapse-open class
</div>
<div class="collapse-content !overflow-visible">
<h2>HELLLERGLERL</h2>
<h2>HELLLERGLERL</h2>
<h2>HELLLERGLERL</h2>
<h2>HELLLERGLERL</h2>
<h2>HELLLERGLERL</h2>
<h2>HELLLERGLERL</h2>
<details class="dropdown dropdown-end z-[99]">
<summary class="m-1 btn">open or close</summary>
<ul
class="p-2 shadow menu dropdown-content z-[98] bg-base-100 rounded-box w-52"
>
<li><a>Item 1</a></li>
<li><a>Item 2</a></li>
<li><a>Item 1</a></li>
<li><a>Item 2</a></li>
<li><a>Item 1</a></li>
<li><a>Item 2</a></li>
</ul>
<div
tabindex="0"
class="collapse collapse-open border border-base-300 bg-blue-200 !overflow-visible"
>
<div class="collapse-title text-xl font-medium">
I have collapse-open class
</div>
<div class="collapse-content">
<details class="dropdown">
<summary class="m-1 btn">open or close</summary>
<ul
class="p-2 shadow menu dropdown-content z-[99] bg-base-100 rounded-box w-52"
>
<li><a>Item 1</a></li>
<li><a>Item 2</a></li>
<li><a>Item 1</a></li>
<li><a>Item 2</a></li>
<li><a>Item 1</a></li>
<li><a>Item 2</a></li>
<li><a>Item 1</a></li>
<li><a>Item 2</a></li>
<li><a>Item 1</a></li>
<li><a>Item 2</a></li>
<li><a>Item 1</a></li>
<li><a>Item 2</a></li>
<li><a>Item 1</a></li>
<li><a>Item 2</a></li>
<li><a>Item 1</a></li>
<li><a>Item 2</a></li>
<li><a>Item 1</a></li>
<li><a>Item 2</a></li>
<li><a>Item 1</a></li>
<li><a>Item 2</a></li>
</ul>
</details>
</div>
</div>
</details>
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { ref } from "vue";
const collapse = ref(false);
function OnClick() {
collapse.value = !collapse.value;
}
</script>
You could consider using the <Teleport>
built-in to render the drop-down menu outside the collapsible elements. This then negates the need to juggle overflow: visible/hidden
. You would need to manually position the dropdowns yourself however, since they will no longer be inside the same parent as the dropdown buttons.
Here is a naïve example that demonstrates the concept:
const { createApp, ref } = Vue;
const dropdown = {
setup() {
const open = ref(false);
const button = ref();
const style = ref({});
const toggle = () => {
open.value = !open.value;
if (open.value) {
const rect = button.value.getBoundingClientRect();
style.value.top = `${rect.top + window.scrollY}px`;
style.value.left = `${rect.left + window.scrollX + rect.width}px`;
}
};
return { open, toggle, button, style };
},
template: '#dropdown',
};
createApp({
components: {
dropdown,
},
setup() {
const collapse = ref(false);
function OnClick() {
collapse.value = !collapse.value;
}
return { collapse, OnClick };
}
}).mount('#app')
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/3.3.13/vue.global.prod.min.js" integrity="sha512-dJsT2VK9KxehzZYzxzUELznI6velu2pAOwpkL5jj4TQQhTNGXZUMup7aLqgqNwVPSUF/Ntcdfla3BEcfC7zwCw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/full.min.css" rel="stylesheet" type="text/css" />
<script src="https://cdn.tailwindcss.com/3.4.0"></script>
<div id="app">
<div
v-for="index in 3"
tabindex="0"
class="collapse collapse-plus z-0 rounded-lg border border-base-content bg-base-100 shadow-md md:w-[48.75%]"
:class="collapse ? 'collapse-open' : 'collapse-close'"
>
<div
class="collapse-title flex items-center text-lg font-medium"
:class="collapse ? 'bg-primary' : 'bg-base-100'"
@click="OnClick"
>
<div
class="mr-3 grid h-[58px] w-[62px] place-content-center rounded-lg"
:class="collapse ? 'bg-base-100' : 'bg-primary'"
></div>
<div
class="flex flex-col gap-1"
:class="collapse ? 'text-base-100' : 'text-primary'"
>
Test
<div class="badge badge-success rounded-[4px]">Active</div>
</div>
</div>
<div class="collapse-content bg-base-200 !p-0 text-accent">
<div
tabindex="0"
class="collapse collapse-open border border-base-300 bg-red-200"
>
<div class="collapse-title text-xl font-medium">
I have collapse-open class
</div>
<div class="collapse-content">
<h2>HELLLERGLERL</h2>
<h2>HELLLERGLERL</h2>
<h2>HELLLERGLERL</h2>
<h2>HELLLERGLERL</h2>
<h2>HELLLERGLERL</h2>
<h2>HELLLERGLERL</h2>
<dropdown>
<ul
class="p-2 shadow menu dropdown-content z-[98] bg-base-100 rounded-box w-52"
>
<li><a>Item 1</a></li>
<li><a>Item 2</a></li>
<li><a>Item 1</a></li>
<li><a>Item 2</a></li>
<li><a>Item 1</a></li>
<li><a>Item 2</a></li>
</ul>
<template v-slot:content>
<div
tabindex="0"
class="collapse collapse-open border border-base-300 bg-blue-200"
>
<div class="collapse-title text-xl font-medium">
I have collapse-open class
</div>
<div class="collapse-content">
<dropdown>
<ul
class="p-2 shadow menu dropdown-content z-[99] bg-base-100 rounded-box w-52"
>
<li><a>Item 1</a></li>
<li><a>Item 2</a></li>
<li><a>Item 1</a></li>
<li><a>Item 2</a></li>
<li><a>Item 1</a></li>
<li><a>Item 2</a></li>
<li><a>Item 1</a></li>
<li><a>Item 2</a></li>
<li><a>Item 1</a></li>
<li><a>Item 2</a></li>
<li><a>Item 1</a></li>
<li><a>Item 2</a></li>
<li><a>Item 1</a></li>
<li><a>Item 2</a></li>
<li><a>Item 1</a></li>
<li><a>Item 2</a></li>
<li><a>Item 1</a></li>
<li><a>Item 2</a></li>
<li><a>Item 1</a></li>
<li><a>Item 2</a></li>
</ul>
</dropdown>
</div>
</div>
</template>
</dropdown>
</div>
</div>
</div>
</div>
</div>
<template id="dropdown">
<details class="dropdown dropdown-end z-[99]">
<summary class="m-1 btn" @click="toggle" ref="button">open or close</summary>
<Teleport to="body" v-if="open">
<div class="absolute" :style="style">
<slot></slot>
</div>
</Teleport>
<slot name="content"></slot>
</div>
</details>
</template>