CSE 322
Fall 2018
CSUSB

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.

menu_example.html

<!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>
main.css

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;
}