Clear & Float

Navigation from Scratch

Our goal with this tutorial is to build a simple navigation bar from scratch. The navigation will need to be 50px high while containing four links and the title of the website.

We will start with a vanilla HTML document structure

1 <!DOCTYPE html>
2     <html>
3         <head>
4     	    <title>Navigation Example</title>
5         </head>
6         <body>
7 	        
8         </body>
9     </html>

Then add in the necessary elements to build our navigation off of.

 1 <!DOCTYPE html>
 2     <html>
 3       <head>
 4         <title>Navigation Example</title>
 5       </head>
 6       <body>
 7         <nav>
 8           <h1>Navbar Example</h1>
 9           <ul>
10             <li>
11               <a href="#">Home</a>
12             </li>
13             <li>
14               <a href="#">About</a>
15             </li>
16             <li>
17               <a href="#">Services</a>
18             </li>
19             <li>
20               <a href="#">Contact</a>
21             </li>
22           </ul>
23         </nav>
24       </body>
25     </html>
The Result:

View the result 


Although this is a working navigation layout, it is not ideal for what we are trying to build. Let's start adding some classes to our DOM elements.

 1 <!DOCTYPE html>
 2     <html>
 3       <head>
 4         <title>Navigation Example</title>
 5       </head>
 6       <body>
 7         <nav class="navbar">
 8           <span class="brand">Navbar Example</span>
 9           <ul>
10             <li>
11               <a href="#">Home</a>
12             </li>
13             <li>
14               <a href="#">About</a>
15             </li>
16             <li>
17               <a href="#">Services</a>
18             </li>
19             <li>
20               <a href="#">Contact</a>
21             </li>
22           </ul><!-- .nav-wrap -->
23         </nav><!-- .navbar -->
24       </body>
25     </html>

Now that our DOM is all set up and ready for us to target with some selectors, we can start writing some CSS.

We know that we want the navbar to span the width of the page, and will have a height of 50 pixels. We also know that we do not want the navbar to scroll down the page with the user.

1 .navbar {
2       display:block;
3       position:relative;
4       width:100%;
5       height:50px;
6     }

We also need to remove the ugly list styling, padding & margin attached to our <ul> by default.

 1 .navbar {
 2       display:block;
 3       position:relative;
 4       width:100%;
 5       border-bottom:1px solid #ccc;
 6       box-shadow:0px 0px 5px 0px rgba(0, 0, 0, .5);
 7     }
 8     .navbar ul {
 9       list-style:none;
10       padding:0;
11       margin:0;
12     }
The Result:

View the result 


You can now see we have our working area clearly defined, and we have removed our unsightly dots next to our list-items. We have also added a little bit of box-shadow and border-color to the bottom of the navbar, giving us a clear definition between that and the rest of the page.

Now let's work on getting our .nav-item's lined up on the right side of the page.

 1 .navbar {
 2       display:block;
 3       position:relative;
 4       width:100%;
 5       border-bottom:1px solid #ccc;
 6       box-shadow:0px 0px 5px 0px rgba(0, 0, 0, .5);
 7     }
 8     .navbar ul {
 9       list-style:none;
10       padding:0;
11       margin:0;
12       float:right;
13     }
14     .navbar ul li {
15       float:left;
16     }
The Result:

View the result 


We have added a float:right declaration to our .navbar ul selector, and a float:left to the individual .nav-item's. Using a float:left on <li>'s always produces a left-to-right layout of each item, making the code and product nicely readable. This has placed our navigation items neatly on the right side of the page, just where we want them.

Next we are going to want to start setting the width and height of the individual navigation elements, and prepare them for more styling. We will start by adding some padding & some height to our <li>'s. Take notice that our specification was to build a navigation bar that is 50 pixels high, but we have only specified a height of 40 pixels in our <li>'s height property. That is because of the CSS 2.0 box-sizing. Before the onset of CSS 3.0 property box-sizing, we were left to compute the total width of an element based on the totals of its width, padding & border properties.

Since discussing the differences between CSS 2.0 & 3.0 are beyond the scope of this tutorial, and many people still have to work with Internet Explorer 7, we will not include any more box-sizing discussion. But, feel free to go read up more on Paul Irish's Blog.

 1 .navbar {
 2       display:block;
 3       position:relative;
 4       width:100%;
 5       border-bottom:1px solid #ccc;
 6       box-shadow:0px 0px 5px 0px rgba(0, 0, 0, .5);
 7     }
 8     .navbar ul {
 9       list-style:none;
10       padding:0;
11       margin:0;
12       float:right;
13     }
14     .navbar ul li {
15       float:left;
16       padding:0px 10px;
17       height:50px;
18     }

View the result 


You can see that the individual nav items have collected their styles appropriately, but notice that two parents up in the DOM, our .navbar is not inheriting the height of it's children. This is a clear example of floated elements wreaking havoc in your designs.

There are a couple of ways you can approach fixing this problem, and it will involve using our .clearfix method from earlier.

We could entirely copy our .clearfix code from the previous example, include that in our CSS, and add the element in at the proper portion of the DOM to achieve our desired behavior, but we don't necessarily have to add a new element into our code. Lets take a look at our HTML & CSS with the .clearfix element added to the DOM.

 1 .clearfix {
 2      clear: both;
 3     }
 4     .navbar {
 5       display:block;
 6       position:relative;
 7       width:100%;
 8       border-bottom:1px solid #ccc;
 9       box-shadow:0px 0px 5px 0px rgba(0, 0, 0, .5);
10     }
11     .navbar ul {
12       list-style:none;
13       padding:0;
14       margin:0;
15       float:right;
16     }
17     .navbar ul li {
18       float:left;
19       padding:0px 10px;
20       height:50px;
21     }
 1 <!DOCTYPE html>
 2     <html>
 3       <head>
 4         <title>Navigation Example</title>
 5       </head>
 6       <body>
 7         <nav class="navbar">
 8           <span class="brand">Navbar Example</span>
 9           <ul>
10             <li>
11               <a href="#">Home</a>
12             </li>
13             <li>
14               <a href="#">About</a>
15             </li>
16             <li>
17               <a href="#">Services</a>
18             </li>
19             <li>
20               <a href="#">Contact</a>
21             </li>
22           </ul><!-- .nav-wrap -->
23           <div class="clearfix"></div>
24         </nav><!-- .navbar -->
25       </body>
26     </html>

View the result 



This shows that the .clearfix method is effective at clearing the floats specified on the <ul> & <li>'s used to build the navigation. However adding a new element into the DOM is not necessary. Targeting the :after pseudo-selector of our .navbar element, we will be able to achieve the save effect with a little bit of CSS magic.

 1 .navbar {
 2       display:block;
 3       position:relative;
 4       width:100%;
 5       border-bottom:1px solid #ccc;
 6       box-shadow:0px 0px 5px 0px rgba(0, 0, 0, .5);
 7     }
 8     .navbar:after {
 9       content:"";
10       display:block;
11       clear:both;
12     }
13     .navbar ul {
14       list-style:none;
15       padding:0;
16       margin:0;
17       float:right;
18     }
19     .navbar ul li {
20       float:left;
21       padding:0px 10px;
22       height:50px;
23     }
 1 <!DOCTYPE html>
 2     <html>
 3       <head>
 4         <title>Navigation Example</title>
 5       </head>
 6       <body>
 7         <nav id="mainNav" class="navbar">
 8           <span class="branded">Navbar Example</span>
 9           <ul class="nav-wrap">
10             <li class="nav-item">
11               <a class="nav-link" href="#">Home</a>
12             </li>
13             <li>
14               <a class="nav-link" href="#">About</a>
15             </li>
16             <li>
17               <a class="nav-link" href="#">Services</a>
18             </li>
19             <li>
20               <a class="nav-link" href="#">Contact</a>
21             </li>
22           </ul><!-- .nav-wrap -->
23         </nav><!-- .navbar -->
24       </body>
25     </html>

View the result 



This is considered the clear :after hack, and is an excellent alternative to using a .clearfix element every time you need to clear a float. Details and further reading on what this method is, and how to use it can be found here.


Now that we have cleared our floats appropriately, and we are inheriting height accordingly, lets move on to styling our navigation text nodes, starting with the links.

 1 .navbar {
 2       display:block;
 3       position:relative;
 4       width:100%;
 5       border-bottom:1px solid #ccc;
 6       box-shadow:0px 0px 5px 0px rgba(0, 0, 0, .5);
 7     }
 8     .navbar:after {
 9       content:"";
10       display:block;
11       clear:both;
12     }
13     .navbar ul {
14       list-style:none;
15       padding:0;
16       margin:0;
17       float:right;
18     }
19     .navbar ul li {
20       float:left;
21       padding:0px 10px;
22       height:50px;
23     }
24     .navbar ul li a {
25       text-decoration: none;
26       color:#555;
27       font-weight:bold;
28       font-family:Arial;
29       line-height: 50px;
30     }

View the result 



Looking better. Let's go ahead and add a small touch of interaction to show when a navigation element is hovered over. The design calls for adding a 5px blue border to the bottom of the navigation, however due to the box-sizing issues we covered earlier, we are unable to add the 5px border to our code without editing some properties to stay under the 50 pixel limit.

Notice in the following example that we have lowered the height of the <li> to 45px, and added in a 5px white border to allow for the space needed to transition colors on hover.

At the end of the snippet we are targeting our :hover pseudo-selector and changing the color of the border, thus adding a user interaction.

 1 .navbar {
 2       display:block;
 3       position:relative;
 4       width:100%;
 5       border-bottom:1px solid #ccc;
 6       box-shadow:0px 0px 5px 0px rgba(0, 0, 0, .5);
 7     }
 8     .navbar:after {
 9       content:"";
10       display:block;
11       clear:both;
12     }
13     .navbar ul {
14       list-style:none;
15       padding:0;
16       margin:0;
17       float:right;
18     }
19     .navbar ul li {
20       float:left;
21       padding:0px 10px;
22       height:45px;
23       border-bottom:5px solid #fff;
24     }
25     .navbar ul li a {
26       text-decoration: none;
27       color:#555;
28       font-weight:bold;
29       font-family:Arial;
30       line-height: 50px;
31     }
32     .navbar ul li:hover {
33       border-bottom:5px solid #39F;
34     }

View the result 



And what if we wanted to make the text color to be the same as the border color on :hover? Let's go ahead and add in the proper styles to make that happen.

 1 .navbar {
 2       display:block;
 3       position:relative;
 4       width:100%;
 5       border-bottom:1px solid #ccc;
 6       box-shadow:0px 0px 5px 0px rgba(0, 0, 0, .5);
 7     }
 8     .navbar:after {
 9       content:"";
10       display:block;
11       clear:both;
12     }
13     .navbar ul {
14       list-style:none;
15       padding:0;
16       margin:0;
17       float:right;
18     }
19     .navbar ul li {
20       float:left;
21       padding:0px 10px;
22       height:45px;
23       border-bottom:5px solid #fff;
24     }
25     .navbar ul li a {
26       text-decoration: none;
27       color:#555;
28       font-weight:bold;
29       font-family:Arial;
30       line-height: 50px;
31     }
32     .navbar ul li:hover {
33       border-bottom:5px solid #39F;
34     }
35     .navbar ul li:hover a {
36       color:#39f;
37     }

View the result 



Lastly, we just need to make our Website Title be a little more presentable to the user.

 1 .navbar {
 2       display:block;
 3       position:relative;
 4       width:100%;
 5       border-bottom:1px solid #ccc;
 6       box-shadow:0px 0px 5px 0px rgba(0, 0, 0, .5);
 7     }
 8     .navbar:after {
 9       content:"";
10       display:block;
11       clear:both;
12     }
13     .navbar ul {
14       list-style:none;
15       padding:0;
16       margin:0;
17       float:right;
18     }
19     .navbar ul li {
20       float:left;
21       padding:0px 10px;
22       height:45px;
23       border-bottom:5px solid #fff;
24     }
25     .navbar ul li a {
26       text-decoration: none;
27       color:#555;
28       font-weight:bold;
29       font-family:Arial;
30       line-height: 50px;
31     }
32     .navbar ul li:hover {
33       border-bottom:5px solid #39F;
34     }
35     .navbar ul li:hover a {
36       color:#39f;
37     }
38     .navbar .brand {
39       padding-left: 10px;
40       font-family: Arial;
41       font-size: 18px;
42       font-weight: bold;
43       line-height: 50px;
44     }

View the result 



And there you have it! A perfectly simple, and functional website navigation bar.