Bulma CSS Framework with Angular 6 | Responsive menu and Navbar burger
In Bulma, everything is CSS. This is a fact about this amazing framework. But we need to understand that this refers to the core of the framework and the way it works, where you do not need to import Jquery or any kind of bulma.js file.
In some cases it is necessary to use JavaScript to make things work as expected. One such case is the mobile menu. So, in this post we will show yout how to use the navbar burger to show the menu on mobile devices.
First of all
In order to execute the examples mentioned here you will need to have an Angular app with Bulma already added. If you have not already, see the post on how to do this. After that we can continue.
If you already have Bulma in your Angular app, you can go on.
Step 1: Basic navbar
In our Angular application, we’ve added the following code from the Bulma documentation.
<nav class="navbar" role="navigation" aria-label="main navigation">
<div class="navbar-brand">
<a class="navbar-item" href="https://bulma.io">
<img src="https://bulma.io/images/bulma-logo.png" width="112" height="28">
</a>
<a role="button" class="navbar-burger burger" aria-label="menu" aria-expanded="false" data-target="navbarBasicExample">
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
</a>
</div>
<div id="navbarBasicExample" class="navbar-menu">
<div class="navbar-start">
<a class="navbar-item">
Home
</a>
<a class="navbar-item">
Documentation
</a>
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link">
More
</a>
<div class="navbar-dropdown">
<a class="navbar-item">
About
</a>
<a class="navbar-item">
Jobs
</a>
<a class="navbar-item">
Contact
</a>
<hr class="navbar-divider">
<a class="navbar-item">
Report an issue
</a>
</div>
</div>
</div>
<div class="navbar-end">
<div class="navbar-item">
<div class="buttons">
<a class="button is-primary">
<strong>Sign up</strong>
</a>
<a class="button is-light">
Log in
</a>
</div>
</div>
</div>
</div>
</nav>
We added thisto the app.component.html file. When we execute (with ng serve), we get the following result.
So our navbar is working. Let’s move forward.
Step 2 : Testing mobile
To see how it will look on smaller devices you can simply change the screen size. Another method is to use the browser features to have a better view.
In Google Chrome you can press F12 and click the icon in the upper right corner to change the device. See picture below.
After clicking the icon you can see something similar to what is shown in the image below.
You can see in the previous image that the menu items are now hidden. Our navbar now shows only the logo and an icon with three bars.
This icon is the navbar-burger and serves so that the menu can be expanded when the page is opened on mobile devices that have a smaller screen. But notice that our icon is inactive and when we click nothing happens. In order for this to work we want to preview a little JavaScript. In our case TypeScript since we are using the Angular.
Step 3: Active the navbar-burger
The .navbar-menu, which is where the menu items are, is hidden on devices with width less than 1024px. But the menu is only hidden and to show it just add the .is-active class. The same goes for .navbar-burger, but in that case it’s the way the icon is shown.
When the .is-active class is added to the .navbar-burger the icon changes to an “X” (close icon) and when the class is removed the icon returns to normal.
What we need to do now is to add a .is-active toggle for both .navbar-menu and .navbar-burger. To do this in Vanilla JavaScript you can access the Bulma CSS documentation at
In our case we need a little more. Let’s see how we can do this with Angular.
Step 4: Toogle classes with Angular
First of all we need access to the elements. For this we will create two variables and these will have the @ViewChild decorator. In addition we will add a click event to the navbar burger that will execute the toggle.
Creating variables
To use the @ViewChild decorator we will need to reference the variables in the HTML element, using a view query, and then retrieve them in the Angular Component.
To set a view query on HTML elements you only need to add a “#” key and the variable name, such as a hashtag.
The code snippet below is the same as shown above. But now with the addition of #navBurger and #navMenu view queries.
<nav class="navbar" role="navigation" aria-label="main navigation">
<div class="navbar-brand">
<a class="navbar-item" href="https://bulma.io">
<img src="https://bulma.io/images/bulma-logo.png" width="112" height="28">
</a><a role="button" #navBurger class="navbar-burger burger" aria-label="menu" aria-expanded="false" data-target="navbarBasicExample">
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
</a>
</div><div id="navbarBasicExample" class="navbar-menu" #navMenu>
<div class="navbar-start">
<a class="navbar-item">
Home
</a>
...
</div><div class="navbar-end">
<div class="navbar-item">
<div class="buttons">
<a class="button is-primary">
<strong>Sign up</strong>
</a>
<a class="button is-light">
Log in
</a>
</div>
</div>
</div>
</div>
</nav>
Now it’s time to reference this in the app.component.ts file. For this you need to import the @ViewChild decorator and also the ElementRef class, both of @angular/core.
The ElementRef class allows us to have direct access to the DOM. Our file will look similar to the one shown below:
import { Component, ViewChild, ElementRef } from '@angular/core';@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})export class AppComponent {}
Now we need to define two variables of type ElementRef and with the @ViewChild decorator. We will pass to the decorator the view query defined for each one. Our file will look like this:
import { Component, ViewChild, ElementRef } from '@angular/core';@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})export class AppComponent {
@ViewChild('navBurger') navBurger: ElementRef;
@ViewChild('navMenu') navMenu: ElementRef;
}
Variables created. Let’s get action!
Toggle classes
Let’s create a method called toggleNavbar() and it will be responsible for toggle when a click event occurs in .navbar-burger. Our method will look like this:
import { Component, ViewChild, ElementRef } from '@angular/core';@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})export class AppComponent {
@ViewChild('navBurger') navBurger: ElementRef;
@ViewChild('navMenu') navMenu: ElementRef; toggleNavbar() {
this.navBurger.nativeElement.classList.toggle('is-active');
this.navMenu.nativeElement.classList.toggle('is-active');
}}
You may be thinking: But this code looks a lot like Vanilla JavaScript.
But that’s right! The nativeElement attribute returns the DOM element just as we do with document.querySelector, document.getElementById, and so on.
So you can do toogle using the classList attribute and calling the toggle() method.
Step 5: Adding event
Now we can return to our app.component.html file and add a click event to .navbar-burger. Here’s how:
<nav class="navbar" role="navigation" aria-label="main navigation"
<div class="navbar-brand">
<a class="navbar-item" href="https://bulma.io">
<img src="https://bulma.io/images/bulma-logo.png" width="112" height="28">
</a><a (click)="toggleNavbar()" role="button" #navBurger class="navbar-burger burger" aria-label="menu" aria-expanded="false" data-target="navbarBasicExample">
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
</a></div>...
Ready. We added the click event to .navbar-burger. Now when it is clicked the menu may appear and may disappear too. In addition, the .navbar-burger icon will change. See below:
Our menu is working on mobile!
To access the code see my Github Gist at https://gist.github.com/codesilva/5bfea1cbe33300531470cf6ee47fe063
For more about bulma see the documentation in https://bulma.io/documentation
See ya!