Accordion component, written in VueJS. The animations are done with GSAP.
A Pen by Takane Ichinose on CodePen.
Accordion component, written in VueJS. The animations are done with GSAP.
A Pen by Takane Ichinose on CodePen.
| #app | |
| zz-accordion(v-bind:contents.sync="contents") |
| Vue.component('zz-accordion', { | |
| props: ['contents'], | |
| data: function() { | |
| return { | |
| } | |
| }, | |
| methods: { | |
| expand: function(e, i) { | |
| e.preventDefault(); | |
| let el = this.$refs['accordion-body-' + i][0]; | |
| if (this.contents[i].active === false) { | |
| this.contents[i].active = true; | |
| TweenLite.to(el, 1, { | |
| height: el.scrollHeight, | |
| ease: Elastic.easeOut.config(1, 0.3) | |
| }); | |
| } else { | |
| this.contents[i].active = false; | |
| TweenLite.to(el, 0.5, { | |
| height: 0, | |
| ease: Bounce.easeOut | |
| }); | |
| } | |
| } | |
| }, | |
| template: ` | |
| <div class="accordion"> | |
| <div | |
| class="accordion-item" | |
| v-for="content, i in contents" | |
| v-bind:class="{ 'accordion-active': content.active }" | |
| > | |
| <div class="accordion-header"> | |
| <a href="#" v-on:click="expand(event, i)"> | |
| <div class="accordion-header-div">{{ content.title }}</div> | |
| <div class="accordion-header-div"> | |
| <div class="accordion-caret"></div> | |
| </div> | |
| </a> | |
| </div> | |
| <div class="accordion-body" v-bind:ref="'accordion-body-' + i"> | |
| <div class="accordion-content">{{ content.description }}</div> | |
| </div> | |
| </div> | |
| </div> | |
| ` | |
| }); | |
| // ---------- | |
| var app = new Vue({ | |
| el: '#app', | |
| data: { | |
| contents: [{ | |
| title: 'Lorem ipsum dolor sit amet', | |
| description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.', | |
| active: false | |
| }, { | |
| title: 'Ut enim ad minim veniam', | |
| description: 'Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.', | |
| active: false | |
| }, { | |
| title: 'Duis aute irure dolor in reprehenderit', | |
| description: 'Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur', | |
| active: false | |
| }, { | |
| title: 'Excepteur sint occaecat cupidatat non proident', | |
| description: 'Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.', | |
| active: false | |
| }] | |
| } | |
| }); |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.min.js"></script> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/2.1.3/TweenMax.min.js"></script> |
| $base-color: #727272; | |
| $base-width: 320px; | |
| $base-time: 200ms; | |
| $app-background-color: #82dfff; | |
| $app-padding: 2rem; | |
| $accordion-background-color: #ffffff; | |
| $accordion-max-width: $base-width; | |
| $accordion-padding: 2rem 1rem; | |
| $accordion-border-radius: 0.5rem; | |
| $accordion-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.3); | |
| $accordion-header-font-size: 1.2rem; | |
| $accordion-header-height: 2rem; | |
| $accordion-header-padding: 1rem 1rem 1rem 1rem; | |
| $accordion-header-border-radius: 0.6rem; | |
| $accordion-header-transition: background-color $base-time ease-in-out; | |
| $accordion-header-hover-background-color: #efefef; | |
| $accordion-caret-color: $base-color; | |
| $accordion-caret-background-image: linear-gradient( | |
| to top right, | |
| transparent 50%, | |
| $accordion-caret-color 50% | |
| ); | |
| $accordion-caret-width: 0.5rem; | |
| $accordion-caret-height: 0.5rem; | |
| $accordion-caret-transform: rotate(-45deg); | |
| $accordion-caret-transforming: scale(1.5) rotate(45deg); | |
| $accordion-caret-active-transform: rotate(135deg); | |
| $accordion-body-content-padding: 1rem; | |
| @import url("https://fonts.googleapis.com/css?family=Montserrat:400,400i,700"); | |
| html, body, #app { | |
| color: $base-color; | |
| font-family: Montserrat, sans-serif; | |
| font-size: 14px; | |
| width: 100%; | |
| height: 100%; | |
| padding: 0; | |
| margin: 0; | |
| } | |
| #app, | |
| .accordion, | |
| .accordion-item, | |
| .accordion-header, | |
| .accordion-body { | |
| font-family: inherit; | |
| } | |
| #app { | |
| background-color: $app-background-color; | |
| display: flex; | |
| box-sizing: border-box; | |
| } | |
| .accordion { | |
| background-color: $accordion-background-color; | |
| width: 100%; | |
| max-height: 100%; | |
| max-width: $accordion-max-width; | |
| padding: $accordion-padding; | |
| margin: auto; | |
| box-sizing: border-box; | |
| overflow: auto; | |
| box-shadow: $accordion-box-shadow; | |
| } | |
| .accordion-item.accordion-active { | |
| .accordion-caret { | |
| animation: accordion-is-active $base-time linear forwards; | |
| } | |
| } | |
| .accordion-header { | |
| color: inherit; | |
| font-size: $accordion-header-font-size; | |
| font-weight: bold; | |
| position: relative; | |
| a { | |
| color: inherit; | |
| text-decoration: none; | |
| width: 100%; | |
| height: 100%; | |
| display: flex; | |
| justify-content: space-between; | |
| box-sizing: border-box; | |
| border-radius: $accordion-header-border-radius; | |
| transition: $accordion-header-transition; | |
| &:not(.accordion-active):hover { | |
| background-color: $accordion-header-hover-background-color; | |
| } | |
| } | |
| } | |
| .accordion-header-div { | |
| padding: $accordion-header-padding; | |
| &:last-child { | |
| padding-left: 0; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| } | |
| } | |
| .accordion-caret { | |
| background-image: $accordion-caret-background-image; | |
| width: $accordion-caret-width; | |
| height: $accordion-caret-height; | |
| transform: $accordion-caret-transform; | |
| animation: accordion-is-inactive $base-time linear forwards; | |
| } | |
| .accordion-body { | |
| height: 0; | |
| overflow: hidden; | |
| } | |
| .accordion-content { | |
| padding: $accordion-body-content-padding; | |
| } | |
| @keyframes accordion-is-inactive { | |
| 0% { transform: $accordion-caret-transform; } | |
| 50% { transform: $accordion-caret-transforming; } | |
| 100% { transform: $accordion-caret-active-transform; } | |
| } | |
| @keyframes accordion-is-active { | |
| 0% { transform: $accordion-caret-active-transform; } | |
| 50% { transform: $accordion-caret-transforming; } | |
| 100% { transform: $accordion-caret-transform; } | |
| } | |
| @media screen and (min-width: $base-width) { | |
| #app { | |
| padding: $app-padding; | |
| overflow: auto; | |
| } | |
| .accordion { | |
| max-height: none; | |
| border-radius: $accordion-border-radius; | |
| } | |
| } |