Let's make a Vuetify-like page!
Tags: html, css, javascript, webdev
Published: 2019-11-21 08:52:11

Hello!
Well, have you ever seen the index page with *Vuetify.js*?
It produces so beautiful CSS designs with simple descriptions like *Bootstrap*. If you want to get the beauties but do not want to use CSS frameworks probably for some special reason, what should you do?
Yes! Let's make a Vuetify-like page!

What we make is a Vuetify-like index page with dark mode. The completion is this:
![Vuetify-like index page](https://thepracticaldev.s3.amazonaws.com/i/5kvxvwic3uykgvwteg2o.png)


###HTML
Firstly, let's see the HTML code!
```html
<head>
  <!-- Import Font Awesome -->
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.1.0/css/all.css" integrity="sha384-lKuwvrZot6UHsBSfcMvOkWwlCMgc0TaWr+30HWe3a4ltaBwTZhyTEggF5tJv8tbt" crossorigin="anonymous">           
</head>
<body style="background-color: #333;">
  <!-- The navigation bar -->
  <div id="NavBar" class="navbar">
    <a href="#" id="menu"><i class="fa fa-bars"></i></a> <!-- The menu icon -->
    <a style="cursor: text;" id="vuetify">Vuetify.js</a>
  </div>
      
  <!-- The Side-navigation -->
  <div id="SideNav" class="sidenav">
    <a href="#" style="background-color: #757575;"><i class="fas fa-th">&emsp;&emsp;Welcome</i></a>      
    <a href="#"><i class="far fa-sun">&emsp;&emsp;Inspire</i></a>
  </div>
 
  <!-- The main content -->
  <div id="main"></div>

  <!-- The footer -->
  <div class="footer">&copy; 2019 Safe Journey</div>
</body>
```
Let me explain the above. We make four parts in the HTML file: the top-fixed navigation bar, the (hidden )side navigation, the main content and the footer. The "cursor: text;" is the mimic of the original index page. The background-color for the text "Welcome" corresponds to the *active page*.
You can use *Font Awesome* for the menu icons. It is imported in the head. But I'm sorry, the above code is for the version 5.1.0. Please import the latest version if you need.

###CSS
Next, let's move on to the CSS code!
The CSS is the linchpin. Fortunately, you can get the design of each part in *W3Schools*.
```css
/* The navigation bar */
.navbar {
  overflow: hidden; /* Hide scrolls */
  background-color: #424242;
  position: fixed; /* Set the navbar to fixed position */
  top: 0; /* Position the navbar at the top of the page */
  left: 0; /* Position the navbar at the left of the page */
  width: 100%;
  box-shadow: 10px 0.5px 10px 1px rgba(0,0,0,0.4); /* Add the shadow under the nabvar */
}

/* Links inside the navbar */
.navbar a {
  float: left;
  display: block;
  color: #f2f2f2;
  text-align: center;
  padding: 14px 16px;
  text-decoration: none;
}

/* Change background on mouse-over */
.navbar a:hover {
  background: #ddd;
  color: black;
}

/* Use this if you want to push the page content to the right when you open the side navigation */
#NavBar {
  transition: margin-left .2s;
}
        
/* The side navigation menu */
.sidenav {
  height: 100%;
  width: 0; /* 0 width - change this with JavaScript */
  position: fixed; /* Stay in place */
  z-index: 1; /* Stay on top */
  top: 0;
  left: 0;
  background-color: #424242;
  overflow-x: hidden; /* Disable horizontal scroll */
  padding-top: 8px; /* Place content 8px from the top */
  transition: 0.2s; /* 0.2 second transition effect to slide in the sidenav */
  border-right: solid 0.5px #616161; /* A thin line at the right side */
}

/* The navigation menu links */
.sidenav a {
  padding: 8px 8px 0px 32px;
  text-decoration: none;
  font-size: 18px;
  color: whitesmoke;
  display: block;
  transition: 0.3s;
}

/* When you mouse over the navigation menu links, change their colour */
.sidenav a:hover{
  background-color: #616161;
}

/* When you mouse over the navigation links, change their colour */
#menu:hover {
  background-color: #616161;
  color: whitesmoke;
  border-radius: 50%;
}

/* When you mouse over the text "Vuetify.js", not change the colour */
#vuetify:hover{
  background-color: transparent;
  color: whitesmoke;
}

/* Style page content - use this if you want to push the page content to the right when you open the side navigation */
#main {
  transition: margin-left .2s;
  padding: 20px;
}
   
/* Style the footer */     
.footer{
  position: fixed;
  bottom: 0; /* Fix the position at the bottom */
  left: 0;
  width: 100%;
  background-color: #212121;
  color: whitesmoke;
  font-size: 14px;
  padding: 4px 0;
  z-index: 2; /* Display the footer in front of the side navigation */
}

/* On smaller screens, where height is less than 450px, change the style of the sidenav (less padding and a smaller font size) */
@media screen and (max-height: 450px) {
  .sidenav {padding-top: 8px;}
  .sidenav a {font-size: 18px;}
}
```
You can design each part following the code above. The tricky points are two: with JavaScript, to make the side navigation slide-in and to push the navigation bar and the main content, you can use *transition*. However, we don't want the side navigation to push the footer. The magic word is *z-index*. z-index denotes a place as a layer. A larger number comes to the more front. The default is one. So, by setting z-index of the footer to two, the side navigation slides-in behind the footer.

###JavaScript
Finally, let's see the JavaScript code!
Actually it is very simple but some tricky points are here.
```javascript
function openNav(){
  document.getElementById("SideNav").style.width = "250px";
  document.getElementById("NavBar").style.marginLeft = "250px";
  document.getElementById("main").style.marginLeft = "250px";
}

function closeNav(){
  document.getElementById("SideNav").style.width = "0";
  document.getElementById("NavBar").style.marginLeft = "0";
  document.getElementById("main").style.marginLeft = "0";
}
        
var flag = 0;
var menu = document.getElementById("menu");
menu.addEventListener("click", function(){
  if(flag == 0){
    openNav();
    flag = 1;
  }else if(flag == 1){
    closeNav();
    flag = 0;
  }
});
```
Our purposes are just two: to open/close the side navigation by clicking the menu icon and to realise them *with just one button*. The former: by the openNav function( and the transition with the CSS) the side navigation pushes the top-fixed navigation and the main content and by the closeNav function the side navigation is hidden.
Well, how about the latter? A tricky point is here. The magic item is a *flag*. Initially, the flag is not flown, namely flag=0. When you click the menu icon, if the flag is not flown, the openNav function is performed and the flag is flown. When you click the menu icon, if the flag is flown, namely the side navigation is opened, the closeNav function is performed, namely the side navigation is closed and the flag is taken down again.

###Comments
The Vuetify-like index page has been completed. But actually, some are different than the original index page. My big mistakes are two.
One is the icon of the Inspire link. I didn't find the similar one.
Two is the animation of the menu icon by clicking it. Actually there is one more animation, which is, the whity colour emits from the centre of the menu icon to the outside. I think that one of the answer is *:active* of CSS. However, it is too difficult for me to implement it over another CSS, *:hover*. So, this is a homework, to you and me.
As I said at the beginning, the Vuetify-like index page is the mimic for the corresponding dark mode. Of course, you can change the colour theme, the behaviours and so on, if you want.
I really hope that this post helps you.
Safe journey!