Navigation Menus
Here is an HTML and CSS example of a webpage containing a navigation menu. The href
attribute of the individual standalone menu item links and the nested menu item links should be replaced with their actual destination.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="main.css">
</head>
<body>
<header>
<h1>Website Title</h1>
<nav>
<ul>
<li>
<a href="#!">Menu item 1</a>
<ul>
<li><a href="#!">Sub-menu item 1.1</a></li>
<li><a href="#!">Sub-menu item 1.2</a></li>
<li><a href="#!">Sub-menu item 1.3</a></li>
</ul>
</li>
<li>
<a href="#!">Menu item 2</a>
<ul>
<li><a href="#!">Sub-menu item 2.1</a></li>
<li><a href="#!">Sub menu item 2.2</a></li>
</ul>
</li>
<li>
<a href="#!">Menu item 3</a>
<ul>
<li><a href="#!">Sub-menu item 3.1</a></li>
<li><a href="#!">Sub-menu item 3.2</a></li>
<li><a href="#!">Sub-menu item 3.3</a></li>
<li><a href="#!">Sub-menu item 3.4</a></li>
</ul>
</li>
<li><a href="#!">Menu item 4</a></li>
</ul>
</nav>
</header>
<main>
<p>Main content</p>
</main>
</body>
</html>
body { margin: 0; font-family: sans-serif; }
body>header>nav ul {
margin: 0;
padding: 0;
color: White;
background-color: DimGray;
list-style-type: none;
}
body>header>nav a {
display: block;
padding: 1em;
color: White;
text-decoration: none;
}
body>header>nav>ul>li:hover>a,
body>header>nav>ul>li:focus-within>a,
body>header>nav>ul>li>ul>li>a:hover,
body>header>nav>ul>li>ul>li>a:focus {
background-color: SteelBlue;
}
body>header>nav>ul>li {
position: relative;
display: inline-block;
}
body>header>nav>ul>li>ul {
display: none;
}
body>header>nav>ul>li:hover>ul,
body>header>nav>ul>li:focus-within>ul {
position: absolute;
display: block;
z-index: 1;
white-space: nowrap;
}
body>main {
padding: 1em;
}
The resulting webpage rendering:
Here's main.css with some commentary to help you understand the code:
body { margin: 0; font-family: sans-serif; }
/*
* Some default styling associated with unordered lists are reset:
* list item indenting removed and the bullets removed. The menu
* is set to a gray background color.
*/
body>header>nav ul {
margin: 0;
padding: 0;
color: White;
background-color: DimGray;
list-style-type: none;
}
/*
* Block display links are clickable anywhere within their container.
* Some default link styling such as blue text and underlining are reset/removed.
*/
body>header>nav a {
display: block;
padding: 1em;
color: White;
text-decoration: none;
}
/*
* Here we want the menu items to be blue when hovered or focused, but
* we want them to stay blue while their sub-menu items are hovered or
* focused while making the sub-menu items become blue when hovered
* or focused too.
*/
body>header>nav>ul>li:hover>a,
body>header>nav>ul>li:focus-within>a,
body>header>nav>ul>li>ul>li>a:hover,
body>header>nav>ul>li>ul>li>a:focus {
background-color: SteelBlue;
}
/*
* Any element whose position property is not static is considered
* to be a "positioned element". A relatively positioned element,
* in addition to being a positioned element, can have it's position
* modified from it's original position by setting the left, right,
* bottom, and top properties. Here we make the menu items into
* positioned elements without modifying their locations.
* inline-block makes the menu items appear horizontally.
*/
body>header>nav>ul>li {
position: relative;
display: inline-block;
}
/* All sub-menus in the navigation menu are initially hidden */
body>header>nav>ul>li>ul {
display: none;
}
/*
* When a top-level menu item is hovered over from a cursor or
* when a link inside of it receives focus from keyboard tabbing:
* display it's sub-menu. An absolutely positioned element's
* location is relative to it's nearest positioned ancestor element;
* in this case, the sub-menu is positioned relative to
* it's containing menu item. z-index set to 1 will ensure
* that the sub-menu appears on top of all other content, and
* white-space set to nowrap disables the line breaks that happen
* when the text in the sub-menu items reach a width equal to the
* width of the containing menu item.
*/
body>header>nav>ul>li:hover>ul,
body>header>nav>ul>li:focus-within>ul {
display: inline-block;
position: absolute;
z-index: 1;
white-space: nowrap;
}
/* Not important */
body>main {
padding: 1em;
}