facebook twitter
Webucator's Free Introduction to CSS Tutorial

Lesson: CSS Lists as Hierarchical Navigation

Welcome to our free Introduction to CSS tutorial. This tutorial is based on Webucator's Introduction to CSS Training course.

In this lesson, you will learn how to style lists to turn them into easy-to-use and dynamic navigation bars.

Lesson Goals

  • Turn CSS lists into horizontal and vertical navigation bars.
  • Use nested lists for multi-level navigation, creating dynamic drop-down and fly-out menus.

As you have seen throughout this course in our demos and exercises, lists of links are often used as navigation bars: Basic List Menu

In this lesson, you will learn how to style these lists to turn them into easy-to-use and dynamic navigation bars.

Basic Horizontal Navigation Bars

Duration: 10 to 20 minutes.

Let's look at how we could turn the basic list menu from the introduction into a stylish horizontal navigation bar, like this: Basic Horizontal Bar

Follow these steps:

  1. Open CssListMenus/Exercises/basic-horizontal-bar-styles.css and CssListMenus/Exercises/basic-horizontal-bar.html in your editor.
  2. Style the body and nav:
    1. Add an aliceblue background to the body.
    2. Add a white background to the nav and left and right margin of -0.5rem (to cancel out the default margin added to the body element and make the nav touch both side of the viewport.
    Basic Horizontal Bar Step 1
  3. Get rid of default ul styles:
    1. Remove bullets by setting list-style (https://developer.mozilla.org/en-US/docs/Web/CSS/list-style) to none.
    2. Set margin and padding to 0.
    Basic Horizontal Bar Step 2
  4. Float the li elements left to line them up horizontally. Basic Horizontal Bar Step 3
  5. Style the links:
    1. Set display to block.
    2. Set padding to 1rem.
    3. Set text-decoration to none.
    4. Change the background when the links are hovered over.
    5. Change the color when the links are clicked.
    Basic Horizontal Bar Step 4
  6. Notice that the white background seems to have disappeared. This is because we took the li elements out of normal flow. To get it back, use the ::after pseudo-element to add a cleared block pseudo-element at the end of the nav element:
    nav::after {
      content: "";
      display: block;
      clear: both;
    }
    Basic Horizontal Bar Step 5

You can see the final code below:

Solution:

CssListMenus/Solutions/basic-horizontal-bar-styles.css
body {
  background: aliceblue;
}

nav {
  background: white;
  margin: 0 -0.5rem;
}

nav::after {
  content: "";
  display: block;
  clear: both;
}

nav ul {
  list-style: none;
  margin: 0;
  padding: 0;
}

nav li {
  float: left;
}

nav a {
  display: block;
  padding: 1rem;
  text-decoration: none;
}

nav a:hover {
  background: rgb(240, 240, 240);
}

nav a:active {
  color: #cce;
}

Solution:

CssListMenus/Solutions/basic-horizontal-bar.html
---- C O D E   O M I T T E D ----

Basic Horizontal Bar

Basic Vertical Navigation Bars

Duration: 10 to 20 minutes.

Let's look at how we could turn the basic list menu from the introduction into a stylish vertical navigation bar, like this: Basic Vertical Bar

We will follow these steps:

  1. Open CssListMenus/Exercises/basic-vertical-bar-styles.css and CssListMenus/Exercises/basic-vertical-bar.html in your editor.
  2. Style the body and nav:
    1. Add an aliceblue background to the body.
    2. Add a white background to the nav and position it absolutely 4rem from the top and give it a left margin of -0.5rem.
    Basic Vertical Bar Step 1
  3. Get rid of default ul styles:
    1. Remove bullets by setting list-style (https://developer.mozilla.org/en-US/docs/Web/CSS/list-style) to none.
    2. Set margin and padding to 0.
    Basic Vertical Bar Step 2
  4. Style the links:
    1. Set display to block.
    2. Set padding to 1rem.
    3. Set text-decoration to none.
    4. Change the background when the links are hovered over.
    5. Change the color when the links are clicked.
    Basic Vertical Bar Step 3

You can see the final code below:

Solution:

CssListMenus/Solutions/basic-vertical-bar-styles.css
body {
  background: aliceblue;
}

nav {
  background: white;
  position: absolute;
  top: 4rem;
  margin: 0 -0.5rem;
}

nav ul {
  list-style: none;
  margin: 0;
  padding: 0;
}

nav a {
  display: block;
  padding: 1rem;
  text-decoration: none;
}

nav a:hover {
  background: rgb(240, 240, 240);
}

nav a:active {
  color: #cce;
}

Solution:

CssListMenus/Solutions/basic-vertical-bar.html
---- C O D E   O M I T T E D ----
<body class="webucator">
<h1>Basic Vertical Bar</h1>
<nav>
  <ul>
    <li><a href="index.html">Home</a></li>
    <li><a href="services.html">Services</a></li>
    <li><a href="products.html">Products</a></li>
    <li><a href="blog.html">Blog</a></li>
    <li><a href="about.html">About</a></li>
    <li><a href="contact.html">Contact</a></li>
  </ul>
</nav>
</body>
</html>

Dynamic Drop-down and Fly-out Navigation Bars

It is often the case that a navigation menu will have nested lists. For example, our basic list menu might have additional options underneath the "About" link: List Menu with Nesting

We probably don't want the nested list to be shown all the time, so we can hide it and make it show up when the user hovers over the "About" link. For a horizontal bar, we will create a drop-down menu and for a vertical bar, we will create a fly-out menu.

Basic Drop-down Menu

Duration: 10 to 20 minutes.

Start with the horizontal navigation bar that we already created, and add a drop-down menu, so that it looks like this:Drop-down Menu

Follow these steps:

  1. Open CssListMenus/Exercises/drop-down-styles.css and CssListMenus/Exercises/drop-down.html in your editor.
  2. First, change the HTML to add the nested list to the "About" li and add a contains class to the "About" li. Drop-down Step 1
  3. Hide the nested ul by setting its display to none. Drop-down Step 2
  4. Display the ul when the "About" li is hovered over. Drop-down Step 3
  5. To keep the "About" li from growing and taking up so much space when its nested list shows up, make the nested list vertical by removing the float. Also make the font size slightly smaller for the nested li elements. Drop-down Step 4
  6. The "About" li is still taking up too much space, so position the nested list absolutely to make it not affect other elements. Drop-down Step 5
  7. This looks okay, but make it match better with the rest of the navigation bar:
    1. Add a white background to the nested list.
    2. Change the link hover rule to a li hover rule, so that when a nested menu item is hovered over, the "About" li is still gray.
    Drop-down Step 6

You can see the final code below:

Solution:

CssListMenus/Solutions/drop-down-styles.css
body {
  background: aliceblue;
}

nav {
  background: white;
  margin: 0 -0.5rem;
}

nav::after {
  content: "";
  display: block;
  clear: both;
}

nav ul {
  list-style: none;
  margin: 0;
  padding: 0;
}

nav li {
  float: left;
}

nav a {
  display: block;
  padding: 1rem;
  text-decoration: none;
}

nav li:hover {
  background: rgb(240, 240, 240);
}

nav a:active {
  color: #cce;
}

li.contains ul {
  display: none;
}

li.contains:hover ul {
  background: white;
  display: block;
  position: absolute;
}

li.contains li {
  float: none;
  font-size: 0.9rem;
}

Solution:

CssListMenus/Solutions/drop-down.html
---- C O D E   O M I T T E D ----
<body class="webucator">
<h1>Drop-down</h1>
<nav>
  <ul>
    <li><a href="index.html">Home</a></li>
    <li><a href="services.html">Services</a></li>
    <li><a href="products.html">Products</a></li>
    <li><a href="blog.html">Blog</a></li>
    <li class="contains"><a href="about.html">About</a>
      <ul>
        <li><a href="about.html#history">Company History</a></li>
        <li><a href="about.html#staff">Our Staff</a></li>
        <li><a href="about.html#press-releases">Press Releases</a></li>
        <li><a href="about.html#investor-info">Investor Information</a></li>
      </ul></li>
    <li><a href="contact.html">Contact</a></li>
  </ul>
</nav>
</body>
</html>

Basic Fly-out Menu

Duration: 10 to 20 minutes.

We will start with the vertical navigation bar that we already created, and add a fly-out menu, so that it looks like this:Fly-out Menu

Follow these steps:

  1. Open CssListMenus/Exercises/fly-out-styles.css and CssListMenus/Exercises/fly-out.html in your editor.
  2. First, change the HTML to add the nested list to the "About" li and add a contains class to the "About" li. Fly-out Step 1
  3. Style the nested list for when it flies out:
    1. Position it absolutely where you want the nested list to show up.
    2. Give it a white background.
    3. Make the font size smaller.
    Fly-out Step 2
  4. Hide the nested ul by setting display to none and make it reappear when "About" is hovered over. Fly-out Step 3
  5. Change the link hover rule to a li hover rule, so that when a nested menu item is hovered over, the "About" li is still gray. Fly-out Step 4

You can see the final code below:

Solution:

CssListMenus/Solutions/fly-out-styles.css
body {
  background: aliceblue;
}

nav {
  background: white;
  position: absolute;
  top: 4rem;
  margin: 0 -0.5rem;
}

nav ul {
  list-style: none;
  margin: 0;
  padding: 0;
  position: relative;
}

nav a {
  display: block;
  padding: 1rem;
  text-decoration: none;
}

nav li:hover {
  background: rgb(240, 240, 240);
}

nav a:active {
  color: #cce;
}

.contains ul {
  background: white;
  display: none;
  font-size: 0.9rem;
  left: 88px;
  position: absolute;
  top: 201px;
  width: 150px;
}

.contains:hover ul {
  display: block;
}

Solution:

CssListMenus/Solutions/fly-out.html
---- C O D E   O M I T T E D ----
<body class="webucator">
<h1>Fly-out</h1>
<nav>
  <ul>
    <li><a href="index.html">Home</a></li>
    <li><a href="services.html">Services</a></li>
    <li><a href="products.html">Products</a></li>
    <li><a href="blog.html">Blog</a></li>
    <li class="contains"><a href="about.html">About</a>
      <ul>
        <li><a href="about.html#history">Company History</a></li>
        <li><a href="about.html#staff">Our Staff</a></li>
        <li><a href="about.html#press-releases">Press Releases</a></li>
        <li><a href="about.html#investor-info">Investor Information</a></li>
      </ul>
    </li>
    <li><a href="contact.html">Contact</a></li>
  </ul>
</nav>
</body>
</html>

CSS List Menus

Duration: 25 to 40 minutes.

In this exercise, you will go back to working on the Runners Home homepage.

  1. Open CssListMenus/Exercises/index.html in your editor. Note that nested lists have been added to the top navigation.
  2. Open CssListMenus/Exercises/styles.css. Feel free to continue working from your own stylesheet.
  3. Using your new knowledge of list menus and navigation bars, restyle the Runners Home navigation. The object of this exercise is to practice creating dynamic navigation bars. See if you can find a way to combine drop-down and fly-out menus.
  4. When you are done, open index.html in your browser to see the results. You are welcome to go back to the code and continue to work.

You can design it however you like, or you can try to make it look something like: List Menus Solution

Solution:

CssListMenus/Solutions/styles.css
---- C O D E   O M I T T E D ----


nav {
  background-color: white;
  border: solid rgb(110, 78, 226) 0.1rem;
  margin: -1rem -0.5rem 1rem;
}

nav ul {
  list-style: none;
  margin: 0;
  padding: 0;
}

nav li {
  float: left;
}

nav::after {
  content: "";
  display: block;
  clear: both;
}

nav a {
  display: block;
  padding: 0.5rem;
  text-decoration: none;
}

nav li:hover {
  background: rgb(230, 230, 230);
}

nav a:active {
  color: red;
}

#resources-li ul {
  background: white;
  border-color: rgb(110, 78, 226);
  border-style: none solid solid;
  border-width: 0.1rem;
  display: none;
  position: absolute;
  top: 40px;
}

#resources-li li {
  float: none;
  font-size: 0.9rem;
}

#blog-li ul {
  border-top: solid rgb(110, 78, 226) 0.1rem;
  position: absolute;
  top: 50px;
  left: 143px;
}

#blog-li ul li {
  font-size: smaller;
}

#resources-li:hover>ul {
  display: block;
}

#blog-li:hover>ul {
  display: block;
}


---- C O D E   O M I T T E D ----

Code Explanation

We omitted all lines in the solution, except those related to the navigation bar.