<div id="app">
  <div
    class="navbar"
    :class="{ 'hidden-navbar': !showNavbar }"
  ></div>
  <transition name="fade">
    <div class="message" key="down" v-if="showNavbar">
      <div class="text">
        Scroll Down to Hide Navbar
      </div>
      <svg class="arrow" viewBox="0 0 24 24">
        <path fill="#000000" d="M9,4H15V12H19.84L12,19.84L4.16,12H9V4Z" />
      </svg>
    </div>
    <div class="message" key="up" v-else>
      <div class="text">
        Scroll Up to Show Navbar
      </div>
      <svg class="arrow" viewBox="0 0 24 24">
        <path fill="#000000" d="M14,20H10V11L6.5,14.5L4.08,12.08L12,4.16L19.92,12.08L17.5,14.5L14,11V20Z" />
      </svg>
    </div>
  </transition>
</div>
* {
  box-sizing: border-box;
}

body {
  padding: 0;
  margin: 0;
}

#app {
  width: 100vw;
  height: 500vh;
  background: hsl(200, 50%, 90%)
}

.navbar {
  height: 60px;
  width: 100vw;
  background: hsl(200, 50%, 50%);
  position: fixed;
  box-shadow: 0 2px 15px rgba(71, 120, 120, 0.5);
  transform: translate3d(0, 0, 0);
  transition: 0.1s all ease-out;
}

.navbar.hidden-navbar {
  box-shadow: none;
  transform: translate3d(0, -100%, 0);
}

.message {
  position: fixed;
  left: 50vw;
  top: calc(50vh + 60px);
  transform: translate(-50%, -50%);
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-size: 5vw;
  text-align: center;
  color: hsl(200, 50%, 60%);
  font-weight: bold;
}

.arrow {
  width: 7.5vw;
  height: 7.5vw;
}

.arrow path {
  fill: hsl(200, 50%, 50%);
}

.fade-enter-active, .fade-leave-active {
  transition: 0.1s all ease-out;
}

.fade-enter, .fade-leave-to {
  opacity: 0;
}

@media (max-width: 900px) {
  .message {
    font-size: 7vw;
  }

  .arrow {
    width: 10vw;
    height: 10vw;
  }
}

@media (max-width: 600px) {
  .message {
    width: 90vw;
    font-size: 10vw;
  }

  .arrow {
    width: 15vw;
    height: 15vw;
  }
}
const OFFSET = 60
new Vue({
  el: '#app',
  data () {
    return {
      showNavbar: true,
      lastScrollPosition: 0,
      scrollValue: 0
    }
  },

  mounted () {
    this.lastScrollPosition = window.pageYOffset
    window.addEventListener('scroll', this.onScroll)
    const viewportMeta = document.createElement('meta')
    viewportMeta.name = 'viewport'
    viewportMeta.content = 'width=device-width, initial-scale=1'
    document.head.appendChild(viewportMeta)
  },

  beforeDestroy () {
    window.removeEventListener('scroll', this.onScroll)
  },

  methods: {
    onScroll () {
      if (window.pageYOffset < 0) {
        return
      }
      if (Math.abs(window.pageYOffset - this.lastScrollPosition) < OFFSET) {
        return
      }
      this.showNavbar = window.pageYOffset < this.lastScrollPosition
      this.lastScrollPosition = window.pageYOffset
    }
  }
})

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.6/vue.min.js