Search code examples
vuejs2navbaroverlayfullscreenconditional-rendering

building a overlay fullscreen navbar in vue.js, by toggle navbar height from 0% to 100%


Trying to implement the overlay fullscreen menu with Vue.js, html/css/js is [this solution]https://www.w3schools.com/howto/tryit.asp?filename=tryhow_js_overlay2

But stuck with how to toggle div height from 0% to 100%. I did create 2 classes,

  • 'navbar'
  • 'navbar_open'

but I am not sure how to toggle between them in Vue. I could see that once @click triggered, the class="navbar navbar_open"

<div id="myNav" class="navbar navbar_open">
  <div class="closebtn">
    <i class="fa fa-times"></i>
  </div>
  <div class="navbar-content">
  <a>Home</a><a>Contact</a>
  </div>
</div>

below is the App.vue file,

<template>
  <div id="app">
    <!-- Banner/Header -->
    <!-- Hamburger -->
    <div id="myNav" class="navbar" :class="{ navbar_open: showNavbar }">
      <div class="closebtn" v-on:click="showNavbar = !showNavbar">
        <i class="fa fa-times"></i>
      </div>

      <div class="navbar-content">
        <a>Home</a>
        <a>Contact</a>
      </div>
    </div>

    <div class="openbtn">
      <i class="fa fa-bars" v-on:click="showNavbar = !showNavbar"></i>
    </div>

    <router-view />
  </div>
</template>

<script>
export default {
  data() {
    return {
      showNavbar: false
    };
  },
  methods: {
    toggleNavbar() {
      this.showNavbar = !showNavbar;
    },
    setHeightValue(showNavbar) {
      const heightValue = this.showNavbar ? '100%' : '0%';
      return heightValue;
    }
  },
  created() {
    this.setHeightValue();
  }
};
</script>

<style>
@import url('https://use.fontawesome.com/releases/v5.9.0/css/all.css');

.navbar_open {
  width: 100%;
  height: 100%;
  position: fixed;
  z-index: 1;
  top: 0;
  left: 0;
  background-color: rgb(0, 0, 0);
  background-color: rgba(0, 0, 0, 0.9);
  overflow-y: hidden;
  transition: 0.5s;
  background-color: #2b4c72;
}

.navbar {
  width: 100%;
  height: 0%;
  position: fixed;
  z-index: 1;
  top: 0;
  left: 0;
  background-color: rgb(0, 0, 0);
  background-color: rgba(0, 0, 0, 0.9);
  overflow-y: hidden;
  transition: 0.5s;
  background-color: #2b4c72;
}

.navbar-content {
  position: relative;
  top: 25%;
  width: 100%;
  text-align: center;
  margin-top: 30px;
}

.navbar a {
  padding: 8px;
  text-decoration: none;
  font-size: 36px;
  color: #818181;
  display: block;
  transition: 0.3s;
}

.navbar a:hover,
.navbar a:focus {
  color: #f1f1f1;
}

.navbar .closebtn {
  position: absolute;
  top: 20px;
  left: 45px;
  font-size: 60px;
  color: white;
  cursor: pointer;
}

.openbtn {
  font-size: 30px;
}

@media screen and (max-height: 450px) {
  .navbar {
    overflow-y: auto;
  }
  .navbar a {
    font-size: 20px;
  }
  .navbar .closebtn {
    font-size: 40px;
    top: 15px;
    right: 35px;
  }
}
</style>

Solution

  • I see that you have unused method toggleNavbar. You call setHeightValue only when your component is created and then never again (I think you can remove this method). This menu is not 100% height probably because you embedded this component in another container (<div id="app:...) which has smaller height so height: 100% will be 100% height of parent container. Instead of 100% you can use 100vh (vh - is a viewport unit and it will always take 100% viewport height [if 50vh then 50% of total viewport height]). You should also apply only navbar_open but now you are applying bot classes if your navbar is open: navabar navbar_open so you should add this classes conditionally:

    :class="{ 'navbar_open': showNavbar, 'navbar': !showNavbar }"
    

    You have also Two different buttons responsible for two different actions:

    • closebtn -> close navigation
    • openbtn -> open navigation

    So you should create two different methods openNavigation closeNavigation

      <div id="app">
        <!-- Banner/Header -->
        <!-- Hamburger -->
        <div id="myNav" :class="{ 'navbar_open': showNavbar, 'navbar': !showNavbar }">
          <div class="closebtn" @click="closeNavigation">
            <i class="fa fa-times"></i>
          </div>
    
          <div class="navbar-content">
            <a>Home</a>
            <a>Contact</a>
          </div>
        </div>
    
        <div class="openbtn">
          <i class="fa fa-bars" @click="showNavigation"></i>
        </div>
    
        <router-view />
      </div>
    </template>
    
    <script>
    export default {
      data() {
        return {
          showNavbar: false
        };
      },
      methods: {
        openNavigation() {
          this.showNavbar = true;
        },
        closeNaviagation() {
          this.showNavbar = false;
        }
      }
    };
    </script>
    <style>
     ...
    .navbar_open {
      width: 100%;
      height: 100vh; // <--- 100vh instead of 100%
      position: fixed;
      ...
    </style>