How to Create a Responsive Website Header - Part 2
In this detailed web development tutorial, I'll teach you how to create two responsive website headers, one with a modal navigation menu and one with an accordion navigation menu, using HTML, CSS, and JavaScript.
This article, which is part 2 of a 5-part series of Web Development tutorials, will guide you through the process of creating a website header. We'll use HTML, CSS, and JavaScript to construct a header layout with two styles of navigation menu that open and close as needed - Modal Navigation Menu and Accordion Navigation Menu. With each example, we'll examine a complete web page demonstration before taking a detailed look at the concepts and code that bring it to life.
This article builds upon topics discussed in How to Create a Responsive Website Layout.
In this article, we'll use our standard HTML Document Structure and CSS Naming Convention.
Skip Ahead
Looking for something specific? Select a topic in this article to read more:
Modal Navigation Menu
In our first example, we'll build upon our Multiple-Line Top Header design to include a modal navigation menu that opens and closes as needed:
A modal navigation menu allows more of the main content area to be shown above the scroll by initially closing the navigation menu. A menu icon (commonly called a "hamburger" icon) is added to the title area to allow visitors to open and close the navigation menu on small screens. When opened, the modal navigation menu fades in to hide the content area. When closed, the modal navigation menu fades out to show the content area.
Header Structure and Style
First, we create our header area.
The construction of the header area is similar to our Multiple-Line Top Header design. But we add:
- CSS to allow the modal behavior
Let's start with the HTML used to create the header area for our responsive modal navigation menu design:
HTML
<!-- Header -->
<header class="header>
<!-- Title -->
...
<!-- Navigation -->
...
</header>
Here we create our header area using the
<header>
element and assign it:
-
The
class="header"
attribute to control the layout of the header area
Next the CSS:
CSS
* {
box-sizing: border-box;
margin: 0;
border: 0;
padding: 0;
}
html {min-height: 100vh;}
body {
min-height: 100vh;
position: relative;
}
/* Page */
.page {
max-width: 640px;
margin: 0 auto;
}
@media (min-width: 960px) {
.page {max-width: 960px;}
}
/* Header */
.header {
font-size: 0;
text-align: center;
}
First, we create a CSS rule to control the default layout and style of all elements (unless otherwise specified). This rule applies the "border box" sizing model and resets margins, borders, and padding to 0.
Next we create a CSS rule to control the layout of the
html
element.
We include:
-
The
min-height: 100vh;
property to specify that thehtml
element is at least the full height of the screen
Then, we create a CSS rule to control the layout of the
body
element.
We include:
-
The
min-height: 100vh;
property to specify that thebody
element is at least the full height of the screen -
The
position: relative;
property to allow the navigation area to be positioned relative to thebody
element
Next we create the
.page
CSS rule to control the layout of our page areas so that:
- The maximum width is 640px on small and medium screens
- The maximum width is 960px on large screens
Finally, we create the
.header
CSS rule to control the layout of our header area.
We include:
-
The
font-size: 0;
property to prevent browsers from adding undesirable whitespace around and between the title heading and navigation menu items (font size is redefined later so that all text is rendered to the correct size)
Title Structure and Style
The first item inside the header area is our title area.
The construction of the title area is similar to our Multiple-Line Top Header design. But we add:
- HTML and CSS to create the button used to open the navigation menu
Let's start with the HTML used to create the title area for our responsive modal navigation menu design:
HTML
<!-- Title -->
<div class="title">
<div class="page title_container">
<h1 class="title_heading">
<a href="#home"
class="title_heading_link">
My Website</a></h1>
<button type="button"
onclick="navToggle()"
class="title_button">
<i class="title_button_icon fa fa-bars"></i></button>
</div>
</div>
First, we create our title area using the
<div>
element and assign it:
-
The
class="title"
attribute to control the style of the title area
Inside the title area we create our title container using the
<div>
element and assign it:
-
The
class="page title_container"
attribute to control the layout of the title container
The first item inside the title container is our title heading.
We create this item using the
<h1>
element and assign it:
-
The
class="title_heading"
attribute to control the style of the title heading
Inside the title heading we use the
<a>
element to create a title heading link that directs visitors to our home page when clicked.
We assign it:
-
The
href="#home"
attribute to specify the destination of the title heading link -
The
class="title_heading_link"
attribute to control the style of the title heading link
The second item inside the title container is the title button that opens our modal navigation menu on small screens.
We create this item using the
<button>
element and assign it:
-
The
onclick="navToggle()"
attribute to execute the JavaScript function that opens the modal navigation menu when clicked -
The
class="title_button"
attribute to control the layout and style of the title button
Inside the title button we create our title button icon using the
<i>
element and assign it:
-
The
class="title_button_icon fa fa-bars"
attribute to control the style of the title button icon
Next the CSS:
CSS
/* Title */
.title {background: #4040BF;}
.title_container {
position: relative;
padding: 0 56px;
}
.title_heading {
display: inline-block;
font: bold 24px / 1.5 sans-serif;
}
.title_heading_link {
display: block;
padding: 16px;
text-decoration: none;
color: #FFFFFF;
}
.title_button {
display: none;
width: 56px;
height: 68px;
position: absolute;
right: 0;
top: 0;
padding: 16px;
font: 24px / 1.5 sans-serif;
color: #FFFFFF;
background: transparent;
cursor: pointer;
}
.title_button_icon {width: 24px;}
First, we create the
.title
CSS rule to control the style of our title area.
Next we create the
.title_container
CSS rule to control the layout of our title container.
We include:
-
The
position: relative;
property to allow the title button to be positioned relative to the title container -
The
padding: 0 56px;
property to prevent the title heading and title button from overlapping
Then, we create the
.title_heading
CSS rule to control the style of our title heading.
Next we create the
.title_heading_link
CSS rule to control the style of our title heading link.
Then, we create the
.title_button
CSS rule to control the layout and style of our title button.
We include:
-
The
display: none;
property to hide the title button on devices that are not JavaScript-enabled -
The
position: absolute; right: 0; top: 0;
properties to position the title button in the top-right corner of the title container
Finally, we create the
.title_button_icon
CSS rule to control the style of our title button icon.
Navigation Structure and Style
The second item inside the header area is our navigation area.
The construction of the navigation area is similar to our Multiple-Line Top Header design. But we add:
- HTML and CSS to create the button used to close the navigation menu
- CSS to allow the modal behavior
Let's start with the HTML used to create the navigation area for our responsive modal navigation menu design:
HTML
<!-- Navigation -->
<nav class="nav">
<div class="page nav_container">
<button type="button"
onclick="navToggle()"
class="nav_button">
<i class="nav_button_icon fa fa-times"></i></button>
<ul>
<li class="nav_menu_item">
<a href="#home"
class="nav_menu_link">
Home</a></li>
<li class="nav_menu_item">
<a href="#about"
class="nav_menu_link">
About</a></li>
<li class="nav_menu_item">
<a href="#products"
class="nav_menu_link">
Products</a></li>
<li class="nav_menu_item">
<a href="#services"
class="nav_menu_link">
Services</a></li></ul>
</div>
</nav>
First, we create our navigation area using the
<nav>
element and assign it:
-
The
class="nav"
attribute to control the style of the navigation area
Inside the navigation area we create our navigation container using the
<div>
element and assign it:
-
The
class="page nav_container"
attribute to control the layout of the navigation container
The first item inside the navigation container is the navigation button that closes our modal navigation menu on small screens.
We create this item using the
<button>
element and assign it:
-
The
onclick="navToggle()"
attribute to execute the JavaScript function that closes the modal navigation menu when clicked -
The
class="nav_button"
attribute to control the layout and style of the navigation button
Inside the navigation button we create our navigation button icon using the
<i>
element and assign it:
-
The
class="nav_button_icon fa fa-times"
attribute to control the style of the navigation button icon
The second item inside the navigation area is our navigation menu.
We create this item using the
<ul>
element.
Inside the navigation menu we create our navigation menu items using the
<li>
element and assign each:
-
The
class="nav_menu_item"
attribute to control the layout and style of the navigation menu item
And inside each navigation menu item we use the
<a>
element to create a navigation menu link that directs visitors to the corresponding page when clicked.
We assign each:
-
The
href="..."
attribute to specify the destination of the navigation menu link -
The
class="nav_menu_link"
attribute to control the style of the navigation menu link
Next the CSS:
CSS
/* Navigation */
.nav {background: #000000;}
.nav.modal {
width: 100%;
position: absolute;
top: 0;
z-index: 1;
overflow: hidden;
transition: opacity 0.25s;
}
.nav_container {
position: relative;
padding: 68px 0 0 0;
}
.nav_menu_item {
display: block;
font: 16px / 1.5 sans-serif;
}
.nav_menu_link {
display: block;
padding: 16px;
text-decoration: none;
color: #FFFFFF;
}
.nav_button {
display: none;
width: 56px;
height: 68px;
position: absolute;
right: 0;
top: 0;
padding: 16px;
font: 24px / 1.5 sans-serif;
color: #FFFFFF;
background: transparent;
cursor: pointer;
}
.nav_button_icon {width: 24px;}
@media (min-width: 480px) {
.nav_container {padding: 0;}
.nav_menu_item {display: inline-block;}
}
First, we create the
.nav
CSS rule to control the style of our navigation area.
To produce the modal behavior, we create the
.modal
CSS rule.
On small screens, our JavaScript function will add this CSS rule to the navigation area.
On medium and large screens, our JavaScript function will remove this CSS rule from the navigation area.
When added, this CSS rule applies:
-
The
width: 100%;
property to specify that the modal navigation menu expands the full width of the screen -
The
position: absolute; top: 0; z-index: 1;
properties to position the modal navigation menu along the top of the screen and in front of all other page content -
The
overflow: hidden;
property to hide the content of the modal navigation menu when it is closed -
The
transition: opacity 0.25s;
property to allow the opacity of the modal navigation menu to change smoothly over a 0.25-second duration
Next we create the
.nav_container
CSS rule to control the layout of our navigation container.
We include:
-
The
position: relative;
property to allow the navigation button to be positioned relative to the navigation container -
The
padding: 68px 0 0 0;
property to prevent the navigation menu and navigation button from overlapping
Note that the navigation container padding is set to 0 on medium and large screens.
Then, we create the
.nav_menu_item
CSS rule to control the layout and style of our navigation menu items.
Note that the navigation menu items are displayed vertically (as blocks) on small screens and horizontally (as inline blocks) on medium and large screens.
Next we create the
.nav_menu_link
CSS rule to control the style of our navigation menu links.
Then, we create the
.nav_button
CSS rule to control the layout and style of our navigation button.
We include:
-
The
display: none;
property to hide the navigation button on devices that are not JavaScript-enabled -
The
position: absolute; right: 0; top: 0;
properties to position the navigation button in the top-right corner of the navigation container
Finally, we create the
.nav_button_icon
CSS rule to control the style of our navigation button icon.
Function
To complete our modal navigation menu design, we use JavaScript to add functionality to our layout. Keeping aligned with the principle of "progressive enhancement", our navigation menu remains fully functional for visitors without JavaScript-enabled devices. But for visitors with JavaScript-enabled devices, the modal behavior is added to our navigation menu to provide an improved user experience.
To produce this functionality, we add the modal behavior on small screens and initially close the navigation menu by setting its opacity to 0. We also show the buttons required to toggle the navigation menu. When the button is clicked to open the navigation menu, its opacity is set to 1. When the button is clicked to close the navigation menu, its opacity is set back to 0.
However, even with the opacity set to 0, the transparent navigation menu continues to cover the main content area and prevents visitors from accessing the interactive elements beneath. We solve this problem by also collapsing the height of the navigation menu so that it no longer covers the main content area. To allow the fade-out transition to complete, we collapse the height of the navigation menu after a brief time delay.
Let's take a look at a step-by-step breakdown of how we want the JavaScript to function:
When the page is loaded or resized:
- Clear time-delayed navigation collapse
-
If screen size is small:
- Add modal behavior to navigation
- Collapse navigation
- Fade out navigation
- Show open navigation button
- Show close navigation button
-
If screen size is medium or large:
- Remove modal behavior from navigation
- Expand navigation
- Fade in navigation
- Hide open navigation button
- Hide close navigation button
When navigation is toggled:
-
If navigation is closed
- Clear time-delayed navigation collapse
- Expand navigation
- Fade in navigation
-
If navigation is open
- Collapse navigation after time delay
- Fade out navigation
Now the JavaScript that makes it happen:
JavaScript
var screenSize = window.matchMedia("(max-width: 479px)");
// Navigation Variables
var nav = document.getElementsByClassName("nav");
var navButtonOpen = document.getElementsByClassName("title_button");
var navButtonClose = document.getElementsByClassName("nav_button");
var navTime;
// Initial Setup of Navigation
function navInitial() {
// Initial Setup of Navigation
clearTimeout(navTime);
// If Screen Size is Small
if (screenSize.matches) {
// Initial Setup of Navigation
nav[0].classList.add("modal");
nav[0].style.height = "0";
nav[0].style.opacity = "0";
navButtonOpen[0].style.display = "block";
navButtonClose[0].style.display = "block";
}
// If Screen Size is Medium or Large
else {
// Initial Setup of Navigation
nav[0].classList.remove("modal");
nav[0].style.height = "auto";
nav[0].style.opacity = "1";
navButtonOpen[0].style.display = "none";
navButtonClose[0].style.display = "none";
}
}
// Toggle Navigation
function navToggle() {
// If Navigation is Closed
if (nav[0].style.height === "0px") {
// Open Navigation
clearTimeout(navTime);
nav[0].style.height = "100%";
nav[0].style.opacity = "1";
}
// If Navigation is Open
else {
// Close Navigation
navTime = setTimeout(function() {
nav[0].style.height = "0";
}, 250);
nav[0].style.opacity = "0";
}
}
// When Page is Loaded
window.onload = navInitial;
// When Page is Resized
window.onresize = navInitial;
And there you have it! A responsive modal navigation menu.
The demonstration provided expands upon this code to show the header in a complete web page environment. It also includes extra features like tooltips and hover states.
To see it in action, open the demonstration at the beginning of this example in a new window. View the source code in your web browser to see how the page is constructed.
To customize the demonstration, first save a local copy of the document on your computer. Then, open the file in your text editor to add, remove, and modify code to create your own web design masterpiece.
Accordion Navigation Menu
In our second example, we'll build upon our Multiple-Line Top Header design to include an accordion navigation menu that opens and closes as needed:
An accordion navigation menu allows more of the main content area to be shown above the scroll by initially closing the navigation menu. A menu icon (commonly called a "hamburger" icon) is added to the title area to allow visitors to open and close the navigation menu on small screens. When opened, the accordion navigation menu expands its height to push down the content area. And when closed, the accordion navigation menu collapses its height to pull up the content area.
Header Structure and Style
First, we create our header area.
The construction of the header area is identical to our Multiple-Line Top Header design.
Let's start with the HTML used to create the header area for our responsive accordion navigation menu design:
HTML
<!-- Header -->
<header class="header">
<!-- Title -->
...
<!-- Navigation -->
...
</header>
Here we create our header area using the
<header>
element and assign it:
-
The
class="header"
attribute to control the layout of the header area
Next the CSS:
CSS
* {
box-sizing: border-box;
margin: 0;
border: 0;
padding: 0;
}
/* Page */
.page {
max-width: 640px;
margin: 0 auto;
}
@media (min-width: 960px) {
.page {max-width: 960px;}
}
/* Header */
.header {
font-size: 0;
text-align: center;
}
First, we create a CSS rule to control the default layout and style of all elements (unless otherwise specified). This rule applies the "border box" sizing model and resets margins, borders, and padding to 0.
Next we create the
.page
CSS rule to control the layout of our page areas so that:
- The maximum width is 640px on small and medium screens
- The maximum width is 960px on large screens
Finally, we create the
.header
CSS rule to control the layout of our header area.
We include:
-
The
font-size: 0;
property to prevent browsers from adding undesirable whitespace around and between the title heading and navigation menu items (font size is redefined later so that all text is rendered to the correct size)
Title Structure and Style
The first item inside the header area is our title area.
The construction of the title area is similar to our Multiple-Line Top Header design. But we add:
- HTML and CSS to create the button used to open and close the navigation menu
Let's start with the HTML used to create the title area for our responsive accordion navigation menu design:
HTML
<!-- Title -->
<div class="title">
<div class="page title_container">
<h1 class="title_heading">
<a href="#home"
class="title_heading_link">
My Website</a></h1>
<button type="button"
onclick="navToggle()"
class="title_button">
<i class="title_button_icon fa fa-bars"></i></button>
</div>
</div>
First, we create our title area using the
<div>
element and assign it:
-
The
class="title"
attribute to control the style of the title area
Inside the title area we create our title container using the
<div>
element and assign it:
-
The
class="page title_container"
attribute to control the layout of the title container
The first item inside the title container is our title heading.
We create this item using the
<h1>
element and assign it:
-
The
class="title_heading"
attribute to control the style of the title heading
Inside the title heading we use the
<a>
element to create a title heading link that directs visitors to our home page when clicked.
We assign it:
-
The
href="#home"
attribute to specify the destination of the title heading link -
The
class="title_heading_link"
attribute to control the style of the title heading link
The second item inside the title container is the title button that opens and closes our accordion navigation menu on small screens.
We create this item using the
<button>
element and assign it:
-
The
onclick="navToggle()"
attribute to execute the JavaScript function that opens and closes the accordion navigation menu when clicked -
The
class="title_button"
attribute to control the layout and style of the title button
Inside the title button we create our title button icon using the
<i>
element and assign it:
-
The
class="title_button_icon fa fa-bars"
attribute to control the style of the title button icon
Next the CSS:
CSS
/* Title */
.title {background: #4040BF;}
.title_container {
position: relative;
padding: 0 56px;
}
.title_heading {
display: inline-block;
font: bold 24px / 1.5 sans-serif;
}
.title_heading_link {
display: block;
padding: 16px;
text-decoration: none;
color: #FFFFFF;
}
.title_button {
display: none;
width: 56px;
height: 68px;
position: absolute;
right: 0;
top: 0;
padding: 16px;
font: 24px / 1.5 sans-serif;
color: #FFFFFF;
background: transparent;
cursor: pointer;
}
.title_button_icon {width: 24px;}
First, we create the
.title
CSS rule to control the style of our title area.
Next we create the
.title_container
CSS rule to control the layout of our title container.
We include:
-
The
position: relative;
property to allow the title button to be positioned relative to the title container -
The
padding: 0 56px;
property to prevent the title heading and title button from overlapping
Then, we create the
.title_heading
CSS rule to control the style of our title heading.
Next we create the
.title_heading_link
CSS rule to control the style of our title heading link.
Then, we create the
.title_button
CSS rule to control the layout and style of our title button.
We include:
-
The
display: none;
property to hide the title button on devices that are not JavaScript-enabled -
The
position: absolute; right: 0; top: 0;
properties to position the title button in the top-right corner of the title container
Finally, we create the
.title_button_icon
CSS rule to control the style of our title button icon.
Navigation Structure and Style
The second item inside the header area is our navigation area.
The construction of the navigation area is similar to our Multiple-Line Top Header design. But we add:
- CSS to allow the accordion behavior
Let's start with the HTML used to create the navigation area for our responsive accordion navigation menu design:
HTML
<!-- Navigation -->
<nav class="nav">
<ul class="page">
<li class="nav_menu_item">
<a href="#home"
class="nav_menu_link">
Home</a></li>
<li class="nav_menu_item">
<a href="#about"
class="nav_menu_link">
About</a></li>
<li class="nav_menu_item">
<a href="#products"
class="nav_menu_link">
Products</a></li>
<li class="nav_menu_item">
<a href="#services"
class="nav_menu_link">
Services</a></li></ul>
</nav>
First, we create our navigation area using the
<nav>
element and assign it:
-
The
class="nav"
attribute to control the style of the navigation area
Inside the navigation area we create our navigation menu using the
<ul>
element and assign it:
-
The
class="page"
attribute to control the layout of the navigation menu
Inside the navigation menu we create our navigation menu items using the
<li>
element and assign each:
-
The
class="nav_menu_item"
attribute to control the layout and style of the navigation menu item
And inside each navigation menu item we use the
<a>
element to create a navigation menu link that directs visitors to the corresponding page when clicked.
We assign each:
-
The
href="..."
attribute to specify the destination of the navigation menu link -
The
class="nav_menu_link"
attribute to control the style of the navigation menu link
Next the CSS:
CSS
/* Navigation */
.nav {background: #000000;}
.nav.accordion {
overflow: hidden;
transition: height 0.25s;
}
.nav_menu_item {
display: block;
font: 16px / 1.5 sans-serif;
}
.nav_menu_link {
display: block;
padding: 16px;
text-decoration: none;
color: #FFFFFF;
}
@media (min-width: 480px) {
.nav_menu_item {display: inline-block;}
}
First, we create the
.nav
CSS rule to control the style of our navigation area.
To produce the accordion behavior, we create the
.accordion
CSS rule.
On small screens, our JavaScript function will add this CSS rule to the navigation area.
On medium and large screens, our JavaScript function will remove this CSS rule from the navigation area.
When added, this CSS rule applies:
-
The
overflow: hidden;
property to hide the content of the accordion navigation menu when it is closed -
The
transition: height 0.25s;
property to allow the height of the accordion navigation menu to change smoothly over a 0.25-second duration
Next we create the
.nav_menu_item
CSS rule to control the layout and style of our navigation menu items.
Note that the navigation menu items are displayed vertically (as blocks) on small screens and horizontally (as inline blocks) on medium and large screens.
Finally, we create the
.nav_menu_link
CSS rule to control the style of our navigation menu links.
Function
To complete our accordion navigation menu design, we use JavaScript to add functionality to our layout. Keeping aligned with the principle of "progressive enhancement", our navigation menu remains fully functional for visitors without JavaScript-enabled devices. But for visitors with JavaScript-enabled devices, the accordion behavior is added to our navigation menu to provide an improved user experience.
To produce this functionality, we add the accordion behavior on small screens and initially close the navigation menu by setting its height to 0. We also show the button required to toggle the navigation menu. When the button is clicked to open the navigation menu, its height is set equal to the height of its content. When the button is clicked to close the navigation menu, its height is set back to 0.
Let's take a look at a step-by-step breakdown of how we want the JavaScript to function:
When the page is loaded or resized:
-
If screen size is small:
- Add accordion behavior to navigation
- Collapse navigation
- Show navigation button
-
If screen size is medium or large:
- Remove accordion behavior from navigation
- Expand navigation
- Hide navigation button
When navigation is toggled:
-
If navigation is closed
- Expand navigation
-
If navigation is open
- Collapse navigation
Now the JavaScript that makes it happen:
JavaScript
var screenSize = window.matchMedia("(max-width: 479px)");
// Navigation Variables
var nav = document.getElementsByClassName("nav");
var navButton = document.getElementsByClassName("title_button");
// Initial Setup of Navigation
function navInitial() {
// If Screen Size is Small
if (screenSize.matches) {
// Initial Setup of Navigation
nav[0].classList.add("accordion");
nav[0].style.height = "0";
navButton[0].style.display = "block";
}
// If Screen Size is Medium or Large
else {
// Initial Setup of Navigation
nav[0].classList.remove("accordion");
nav[0].style.height = "auto";
navButton[0].style.display = "none";
}
}
// Toggle Navigation
function navToggle() {
// If Navigation is Closed
if (nav[0].style.height === "0px") {
// Open Navigation
nav[0].style.height = nav[0].scrollHeight + "px";
}
// If Navigation is Open
else {
// Close Navigation
nav[0].style.height = "0";
}
}
// When Page is Loaded
window.onload = navInitial;
// When Page is Resized
window.onresize = navInitial;
And there you have it! A responsive accordion navigation menu.
The demonstration provided expands upon this code to show the header in a complete web page environment. It also includes extra features like tooltips, hover states, toggled icons, and button tabs.
To see it in action, open the demonstration at the beginning of this example in a new window. View the source code in your web browser to see how the page is constructed.
To customize the demonstration, first save a local copy of the document on your computer. Then, open the file in your text editor to add, remove, and modify code to create your own web design masterpiece.
More Parts in This Series
- Part 1 - Side Header, Single-Line Top Header, and Multiple-Line Top Header
- Part 2 - Modal Navigation Menu and Accordion Navigation Menu
- Part 3 - Subnavigation Menus
- Part 4 - Search and Share Bars
- Part 5 - Icon Bar