Lesson 15 - Bootstrap - Navigation
In the previous lesson, Bootstrap - Dropdowns, we discussed dropdown buttons. In today's tutorial, we're going to dive into the depths of the Bootstrap CSS framework and describe how to style the navigation.
Navigation
Whenever we need a navigation in our web presentation, we don't have to
search for too long. Bootstrap has already prepared for us both the navigation
and the mobile version of it with a sliding menu. In today's lesson, we're going
to discuss the navigation itself for which we are provided with the
.nav
class.
Example
As first, let's have a look at what does the component look like. We'll use list items to represent the navigation items.
<ul class="nav"> <li class="nav-item"> <a class="nav-link" href="#">About the company</a> </li> <li class="nav-item"> <a class="nav-link" href="#">Products</a> </li> <li class="nav-item"> <a class="nav-link disabled" href="#">Pricing</a> </li> <li class="nav-item"> <a class="nav-link" href="#">Contact</a> </li> </ul>
The result in the browser:
We assign the .nav-link
class to the navigation items. The
navigation does not support the .active
class in any way but we can
use .disabled
to disable some of the items.
The <nav>
element and
alignment
Next to lists, we can use simple links without any other elements as well,
wrapped inside the <nav>
element with the .nav
class again. Let's have a look at how to align the navigation items
horizontally. Because the whole navigation is built on flexbox, we're going to
use the familiar flexbox utilities, specifically the
.justify-content-center
class to center it.
The HTML code:
<nav class="nav justify-content-center"> <a class="nav-link" href="#">About the company</a> <a class="nav-link" href="#">Products</a> <a class="nav-link disabled" href="#">Pricing</a> <a class="nav-link" href="#">Contact</a> </nav>
And the result:
To align the items to the right we'd use the
.justify-content-end
class.
Vertical navigation
If we wanted to style the navigation as vertical, we can use the
.flex-column
class. The vertical navigation usually succeeds on
smaller screens; we would simply style the navigation as horizontal on desktops
and vertical on mobile phones. We'd use e.g. the .flex-sm-row
class
for this purpose.
<ul class="nav flex-column"> <li class="nav-item"> <a class="nav-link" href="#">About the company</a> </li> <li class="nav-item"> <a class="nav-link" href="#">Products</a> </li> <li class="nav-item"> <a class="nav-link disabled" href="#">Pricing</a> </li> <li class="nav-item"> <a class="nav-link" href="#">Contact</a> </li> </ul>
The result:
We'd achieve the opposite behavior using the .flex-sm-column
class, making the navigation vertical on desktops and horizontal on mobile
phones. Next, we could use responsive classes like .text-sm-center
which we'd assign to the items, centering them on desktops and leaving them
aligned left, as a vertical list, on mobile phones where the navigation is
vertical.
Tabs
We can easily style the navigation as tabs by assigning the
.nav-tabs
class. In this case the .active
class is
also supported. To keep the full functionality the Bootstrap's JavaScript plugin
needs to be linked.
Notice that a dropdown button is used in one of the tabs as well.
Pills
Similarly, we can make "pills" out of the links by assigning the
.nav-pills
class. We can have a look on the usage of other class,
.nav-fill
, which stretches the navigation content to fill the whole
width. Similarly, there's also the nav-justified
class which should
stretch the navigation content while setting the same size to each item.
However, I wasn't able to make this class work, it's probably a Bootstrap
bug.
If we used the <nav>
element and the
<a>
links to define the navigation, the shortened version
without a list, we'd also assign the .nav-item
class to each link.
Let's have a look at this example:
If we also wanted to add a Dropdown, we'd proceed similarly as with tabs and used a list to define the navigation.
Semantics
Ideally, we should also assign the role="navigation"
attribute
for screen readers to the navigation made by the <ul>
list or
wrap the navigation into the the <nav>
semantic element. We
do NOT write values such as tablist
, tab
or
tabpanel
in the role
attribute, even when we're
actually using tabs in the navigation, because these roles are meant for dynamic
content which the tabs switch between. We shouldn't combine dynamic tabs with
Dropdowns because it can be confusing that the "activating" button isn't visible
right away but it'll be hidden together with the tab. Above that, there's
currently no way to tell screen readers using ARIA attributes how to control
such a component system.
Dynamic tabs
Since we've already mentioned dynamic tabs a few times before, let's have a look at how to bind them to the navigation. Don't forget to link the JavaScript.
<ul class="nav nav-tabs" id="navigation" role="tablist"> <li class="nav-item"> <a class="nav-link active" id="about-company-tab" data-toggle="tab" href="#about-company" role="tab" aria-controls="about-company" aria-selected="true">About the company</a> </li> <li class="nav-item"> <a class="nav-link" id="products-tab" data-toggle="tab" href="#products" role="tab" aria-controls="products" aria-selected="false">Products</a> </li> <li class="nav-item"> <a class="nav-link" id="contact-tab" data-toggle="tab" href="#contact" role="tab" aria-controls="contact" aria-selected="false">Contact</a> </li> </ul> <div class="tab-content" id="navigation-content"> <div class="tab-pane fade show active" id="about-company" role="tabpanel" aria-labelledby="about-company-tab">The About the company tab contents...</div> <div class="tab-pane fade" id="products" role="tabpanel" aria-labelledby="products-tab">The Products tab contents...</div> <div class="tab-pane fade" id="contact" role="tabpanel" aria-labelledby="contact-tab">The Contact tab contents...</div> </div>
The result:
Notice the usage of the classes .fade
and .show
to
show an animation. A simplified version with the <nav>
element follows:
We can also create a navigation with dynamic tabs using pills, we just assign
the .nav-pills
class instead of the .nav-tabs
class.
Ideally, we should also change the data-toggle
data attribute value
from tab
to pill
. We can even place the tabs
vertically, let's have a look:
A responsive grid which we're going to explain in depth further in the course, is used in the example.
JavaScript
Like most of the components, we can change the behavior of the navigation via
JavaScript as well. As always, we can change the behavior either by data
attributes or by accessing the properties from JavaScript. The properties in
JavaScript are named the same as thr data attributes (without the
data-
prefix). It's the data-toggle
data attribute
with the value of tab
or pill
.
Without data attributes, we'd initialize tabs in JavaScript like this:
$('#tabs a').on('click', function (e) { e.preventDefault(); $(this).tab('show'); });
Methods
We can pass 2 string values as the parameter of the tab()
method:
"show"
- Shows the tab"dispose"
- Removes the tabnavigation bar.
We use a regular jQuery selector to active a particular tab:
$('#tabs a[href="#products"]').tab('show') // Opens a tab by name $('#tabs a:first').tab('show') // Opens the first tab $('#tabs a:last').tab('show') // Opens the last tab $('#tabs li:eq(3) a').tab('show') // Opens the forth tab (the indexes are zero-based)
The methods are asynchronous and pass the control flow before the tab is actually switched! The reason is the animation in progress. If the animation (transition) is ongoing, all method calls will be ignored.
Events
We can handle the following events in JavaScript:
hide.bs.tab
- Is called on the currently active tab, right when a new tab is about to show.show.bs.tab
- Is called on the tab which is about to show but before it's actually shown.hidden.bs.tab
- Is called on the tab which was active previously, after being switched.shown.bs.tab
- Is called on the tab which has just been shown.
Handling an event could look like this:
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) { e.target // in this property we can find the current tab e.relatedTarget // in this property we can find the tab that was previously active })
In the next lesson, Bootstrap - Navigation bar, we'll have a look at how to use the knowledge from today when creating a responsive