I’m still doing my best to master the fine points of building a drop down horizontal navigation menu. In my earlier posts on this topic I was building them with divs. Now I’m trying to do my best building them with ordered lists from memory – as in not having to reference W3Schools or some other tutorial/sample to build the menu.
The basic structure for the drop down menu using an ordered list is as follows:
<ul>
<li>Topic A</li>
<li>Topic B</li>
<li>Topic C</li>
</ul>
Then, if you wish for the menu to have submenus then the structure looks like this:
<ul>
<li>Topic A</li>
<li>Topic B
<ul>
<li>Subtopic 1</li>
<li>Subtopic 2</li>
</ul>
<li>Topic C
<ul>
<li>Subtopic 1</li>
<li>Suptopic 2</li>
<li>Suptopic 3</li>
</ul>
</li>
</ul>
STEP 1:
Now with the baseline established lets get on with coding the page. I want this menu to be horizontal drop down menu, fixed to the top of the page. So I start with this:
CSS:
nav {width:100%; position:fixed; top:0; background-color:gray;}
HTML:
<nav> </nav>
STEP 2:
I don’t want any of the items in the ordered list to have any decoration (no numbers, bullets, squares, roman numerals, etc.) so I code this at the start to strip that decoration out:
CSS:
ul {list-style:none;}
STEP 3:
Let’s start building the menu, at least the main menu section. As you can see below the menu will have 5 main sections.
HTML
<nav>
<ul>
<li>Home</li>
<li>About</li>
<li>Visit</li>
<li>Live</li>
<li>UN SPACY</li>
</ul>
</nav>
Right not the menu will display vertically and not horizontally. Next I am going assign the attribute of ‘inline-block’ via a class and the corresponding hyperlinks. Note, the inline-block attribute will make the menu options align horizontally – this also could be done via ‘float’ too.
Step 4:
Click here to review the progress so far, you’ll the menu is still very basic. You might notice that the menu is offset to the right by a few pixels. This can be resolved via the body tag and making the margin equal to zero. We can also begin to set some font characteristics, in the nav tag we can set the font family for the entire menu to be ‘arial.’ The code should look like this now:
CSS:
body {margin: 0;}
nav {width: 100%; position: fixed; top: 0; background-color: gray; font-family: arial; font-size: 16px;}
ul {list-style: none;}
.horizontal {display: inline-block;}
HTML:
<nav>
<ul>
<li class=”horizontal”><a href=”#”>Home</a></li>
<li class=”horizontal”><a href=”#”>About</a></li>
<li class=”horizontal”><a href=”#”>Visit</a></li>
<li class=”horizontal”><a href=”#”>Live</a></li>
<li class=”horizontal”><a href=”#”>UN SPACY</a></li>
</ul>
</nav>
STEP 5:
The menu options are aligned horizontally now, but the options need to be evenly spaced. So next I added a width of 150px to the ‘horizontal’ class. Next I want the text and background color to change when the cursor points to the menu option (text to change from black to white with a black background). Now note, this is where it got very tricky for me!
To achieve this effect you have to code ‘.horizontal a‘ to reference the <a> link inside the horizontal class. See the above code in Step 4 (li class=”horizontal”><a href=”#”>Home</a></li>), here you see how the horizontal class being assigned to the outside <li> tag and the <a> tag inside. So you have to create a new class “.horizontal a” to apply any style to the hyperlinked text in the menu – this was a hard concept for me to grasp at first. Thus your code in your CSS will look like this:
CSS:
.horizontal {display: inline-block; width: 150px;}
.horizontal a {color:#000;}
.horizontal a:hover {color:#fff; background-color:#000;}
Click here to see the progress so far.
STEP 6:
Now its starting to look more like a navigation menu, but there is still a lot more to be done. You should notice when you hover over the menu options it does change the text and background color, but only for the exact area the text covers. It should cover the entire 150px, the area we established to be the width of the text section. To get it cover the area we have to get it to display as a ‘block’ (instead of like a <span>).
To get it to display properly I added ‘display:block’ to the ‘horizontal-a’ class and I added ‘margin:0’ to the ul tag in the CSS, like so:
CSS:
ul {list-style:none; margin:0;}
.horizontal a {color:#000; display:block; text-decoration: none;}
By default there appears to be some margin space added to the <ul> tag, so setting the margin to zero erases that default space. You can also see above I used “text-decoration:none’ to remove the default hyperlink underline of the menu options. You can view the results here.
STEP 7:
Now lets add the submenu options. If you have read my other posts in this Drop Down Menu Series you’ll remember the first thing we’ll need is an empty ‘container’ that will be ‘display: none’ until ‘hover’ changes it to ‘display: block.’ The container will eventually hold the the submenu links.
CSS:
.container {display: none;}
.horizontal:hover .container {display:block;}
HTML:
<li class=”horizontal”><a href=”#”>About</a>
<ul class=”container”>
</ul>
</li>
Note the above isn’t all the HTML, just a snippet to show you where the container class goes in the ordered list. Nothing really visible has happened yet, so we need to add some content (submenu links) inside the container.
STEP 8:
Lets create the submenu links. The links will follow the same format as the ‘horizontal a’ links did in Step 4. First lets show some HTML so you can follow it a bit better:
HTML:
<li class=”horizontal”><a href=”#”>About</a>
<ul class=”container”>
<li><a href=”#”>About Me</a></li>
<li><a href=”#”>About Macross Island</a></li>
</ul>
</li>
Above you can see the new submenu code in orange, you can see it is basically the same format as the HTML is for the ‘About’ link:
- <li class=”ABC”><a>About</a></li>
- <ul class=”XYZ”><li><a>About Me</a></li></ul>
The only difference here is that the structure of the submenu code contains an <li> tag. Just as we coded a new class “.horizontal a” we’ll do the same with “.container li a” for the submenu, and as you can see the only difference is that we must include the <li> tag.
CSS:
.container li a {display:block; background-color:gray; color:yellow;}
.container li a:hover {background-color:yellow; color:#000;}
You can view the progress here.
STEP 9:
As I’m sure you can see in the above link there are some major issues with the drop down submenu. Again to reference my earlier posts in this series about drop down menus you have to remember we needed to assign ‘position: relative’, ‘position: absolute’ and a width to get all the parts to work together properly:
CSS:
.horizontal {display: inline-block; width: 150px; position: relative;}
.container {display: none; position: absolute; width: 100%;}
This improves, but still doesn’t fully resolve, the alignment issues, see here. Remember in Step 6 there was some default margin space that had to be removed from the <ul> tag. There is also default padding that comes with the <ul> tag too, so you have to add ‘padding:o’ to remove it.
CSS:
ul {list-style:none; margin:0; padding:0;}
Now with those changes the menu should work properly, see here.
STEP 10:
The menu works great and is basically done, but I cant resist added a bit more style. I want to add some space to around the text, specifically the top and bottom. To achieve this I’ll use line-height. I also want to add some additional space to the left of the text so that it does not butt up against the edge, I’ll use text-indent to for this. Note I’m also want to add a bottom border to the submenu.
CSS:
nav {width: 100%; position: fixed; top:0; background-color: gray; font-family: arial; font-size: 16px; line-height: 200%; text-indent: 5px;}
.container li a {display:block; background-color:gray; color:yellow; border-bottom: 1px solid black;}
Notice line-height and text indent were both added to the <nav> tag so the effects would be global for the entire menu. See the results here. Padding doesn’t work in this scenario, at least based on what I currently know and understand about CSS and HTML.