Good afternoon,
I have a need to create HTML/CSS/JS accordion. Requirements: accordion container's height must be fixed (100% body's height) and if panel's content overflows, scrollbar must be inside panel's content div and not inside accordion container itself!
I have created a pen: https://codepen.io/lotrmj/pen/bGJEzrp to show general idea. Everything works as intended, but there is no animation...
Is it possible to create animation for expand/collapse action similar to: https://vuetifyjs.com/en/components/expansion-panels/#variant ? Or is it impossible as panel headers and corresponding contents do not have fixed height? If it is possible, could somebody of you help me a bit?
I have done that before with jQuery UI library and it was working, but I am searching for more modern solutions/libraries..
I tried looking for examples but didn't find any with similar problem.
<template>
<div id="nav">
<template v-for="i in 5">
<div class="panel-header">
<span>PANEL {{i}}</span>
<button @click="expandOrCollapse(i)">{{i == activePanel ? "Collapse" : "Expand"}}</button>
</div>
<div class="panel-content" v-if="i == activePanel">
<div class="content">
Very long panel {{i}} content with scrollbar...
</div>
</div>
</template>
</div>
<div id="main">MAIN DIV</div>
</template>
<script>
export default {
data() {
return {
activePanel: 2
};
},
methods: {
expandOrCollapse(i) {
if (i == this.activePanel) {
this.activePanel = undefined;
} else {
this.activePanel = i;
}
}
}
};
</script>
<style>
html, body {
height: 100%;
margin: 0;
}
body {
display: flex;
}
#app {
flex-grow: 1;
display: flex;
}
#nav {
width: 400px;
border-right: 1px solid #ccc;
overflow: auto;
display: flex;
flex-direction: column;
}
#main {
flex-grow: 1;
display: flex;
align-items: center;
justify-content: center;
}
.panel-header, .panel-content {
border-bottom: 1px solid #ddd;
padding: 5px;
}
.panel-header span {
padding-right: 3px;
}
.panel-content {
overflow: auto;
flex-grow: 1;
}
.content {
height: 1000px;
}
</style>
Using
v-ifmeans the element is removed from the DOM, which does not give any chance to show an animation.You could consider using a CSS grid layout, where each panel header and content occupy a grid row. Then, CSS transition between
0frand1frto hide or show the panel content respectively. We'd also need to remove thepadding-topandpadding-bottomfor the content too when hidden.