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