Created
October 28, 2021 12:34
-
-
Save JamieCurnow/ebd7f4991f9434824f3a1d5eb62b503e to your computer and use it in GitHub Desktop.
Tailwind vue header with nice transitions
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<template> | |
<div id="header" :class="headerClasses" class="z-40 w-full"> | |
<div class="sticky top-0 inset-0 z-40"> | |
<div class="max-w-7xl mx-auto flex justify-between items-center px-4 py-5 sm:px-6 sm:py-4 lg:px-8 md:justify-start md:space-x-10"> | |
<div class="flex-1 flex flex-row items-center justify-between"> | |
<nav class="flex flex-col sm:flex-row sm:space-x-10"> | |
<a id="whyIsItNeeded" href="#joinTheMovement" v-smooth-scroll class="text-base font-medium"> | |
Why is it needed? | |
</a> | |
<a id="faqs" href="#questions" v-smooth-scroll class="text-base font-medium"> | |
FAQs | |
</a> | |
</nav> | |
<div class="flex items-center md:ml-12"> | |
<button type="button" id="goCarbonFree1" class="hoverLinkButton text-base font-medium w-full sm:w-56 px-8 py-3 rounded-md bg-secondary-600 text-primary-800 hover:text-primary-700 flex justify-between items-center shadow-md" aria-label="Go Carbon Free - Opens Newsletter Sign-Up Modal" @click="$nuxt.$emit('showMailChimpForm')"> | |
Go carbon-free | |
</button> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
</template> | |
<script> | |
export default { | |
data: () => ({ | |
// the window scroll position | |
scrollY: 0, | |
// the about of change needed before toggling slide-down/up nav bar | |
buffer: 100, | |
// height of the nav | |
navHeight: 80, | |
// the current direction of scroll | |
currentDirection: 'down', | |
// the scroll position on direction change | |
scrollYBeforeDirectionChange: 0, | |
// nav toggle | |
navState: 'transparent' // 'slide-down' || 'slide-up' || 'initial-up' | |
}), | |
computed: { | |
headerClasses() { | |
const { navState } = this | |
// transparent top state | |
if (navState === 'transparent') { | |
return ['absolute bg-transparent text-white transition duration-300 ease-in-out'] | |
} | |
// shared slide-up/down state | |
const shared = ['transform', 'fixed', 'bg-white', 'text-primary-500'] | |
const sharedTransitions = ['transition duration-300 ease-in-out '] | |
// initial up state | |
if(navState === 'initial-up') { | |
return ['transition-none', ...shared, '-translate-y-20'] | |
} | |
// slide up | |
if (navState === 'slide-up') { | |
return [...sharedTransitions, ...shared, '-translate-y-20'] | |
} | |
// slide down | |
if (navState === 'slide-down') { | |
return [...sharedTransitions, ...shared, 'translate-y-0'] | |
} | |
} | |
}, | |
watch: { | |
navState(v, old) { | |
console.log({v, old}) | |
}, | |
scrollY(v, old) { | |
if(v === 0) return (this.navState = 'transparent') | |
const { currentDirection, buffer } = this | |
const newDirection = v > old ? 'down' : 'up' | |
if(currentDirection !== newDirection) this.scrollYBeforeDirectionChange = v | |
this.currentDirection = newDirection | |
const { navState, scrollYBeforeDirectionChange } = this | |
if (scrollYBeforeDirectionChange - v > buffer) { | |
this.navState = 'slide-down' | |
} | |
if (v - scrollYBeforeDirectionChange > buffer) { | |
this.navState = navState === 'transparent' ? 'initial-up' : 'slide-up' | |
} | |
} | |
}, | |
mounted() { | |
this.onScroll() | |
window.addEventListener('scroll', this.onScroll) | |
}, | |
unmounted() { | |
window.removeEventListener('scroll', this.onScroll) | |
}, | |
methods: { | |
onScroll() { | |
this.scrollY = window.scrollY | |
} | |
} | |
} | |
</script> | |
<style> | |
</style> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment