<< Return to Labs Page

Prelab 2 : Web Coding In Style

Lab Overview

The purpose of this prelab is to get you more comfortable with using CSS for styling your webpages. Here we'll use some more presentational aspects than we saw in Lab 1. This also builds toward the Lab 2 assignment of combining several different CSS 'tricks' into one interesting application.

A Drop-Down Menu

You've started out simple so far and probably created just 1 or 2 webpages so far. But what if you had a lot of content to post on the web? How could you easily allow people browsing your website to get to many different webpages? A drop-down navigational menu might be the answer. We'll try creating one in this prelab and will hopefully learn more about CSS along the way.


An example drop-down menu is given above. If you hover your mouse over one of the 4 items - and if your using a standards compliant browser - then you should see a sub-menu appear. Clicking one of the main items, like Item B, or one of the sub-menu items, like item 3, should take you to the location that the link specifies. Of course, this only works if you're using a standards compliant browser like Firefox or Safari. Unfortunately, Internet Explorer (IE) is a little behind the times and doesn't support as many CSS features. There are tricks to get the menu to work in IE, but to keep things simple just develop your code to work in a browser like Firefox for now.

To start out, we first need the HTML code that our CSS will style. This turns out to be quite simple: nested lists. You already created a list of items for the first lab and now those "items" just happen to be lists themselves. Here's the code:

The Code

<html>
<head>
<style type="text/css">
/* CSS code will go here */
</style>
</head>
	
<body>
<div class="menu">


<ul>
   <li><a>Item A</a>
      <ul>
         <li><a>item 1</a></li>
         <li><a>item 2</a></li>
         <li><a>item 3</a></li>
      </ul>
   </li>
   <li><a>Item B</a>
      <ul>
         <li><a>item 1</a></li>
         <li><a>item 2</a></li>
         <li><a>item 3</a></li>
      </ul>
   </li>
</ul>

</div>
</body>
</html>

The Result

This gives a few top list item, then several sub-list items below each of those as you might expect. The specific code that made just the nested list is highlighted in red. I've only included 2 main list items with 3 sub-items each. You can add as many as you like or have as many layers of nested lists as you like.

Also, for this example all of my <a> tags are missing the href attribute for specifing the url for some link. That's only done to make this example code easier to read. You'll obviously need to include those href attributes to make these list items work as links. Finally, notice that I've got a <div> element with the class name menu enclosing all of my lists. This may be unnecessary, but it helps to separate my CSS rules for this menu from any other lists or links I might have in my webpage.

A Styl'n Menu

First Steps

Now that we've got the HTML basis for our menu, we can start styling it with CSS. The first thing I'm going to do is remove the points from the front of my list items. I'm also going to set a width and background color for the overall <div> so that it's easier to see where our elements start and end. In the CSS code examples that follow I'll usually only give the CSS code and assume that you know to put it in the <style> tag, which goes inside the <head> tag.

The Code

<style type="text/css">
/* CSS code will go here */

.menu{
   width: 350px;
   background-color: #fcc;
}
.menu ul {
   list-style-type: none;
}
</style>

The Result

Note that I'll start all of my CSS rules with .menu to say that I only want to affect elements contained within some larger element that has the class name menu. In this case, that larger element is the >div< that I mentioned earlier. With that first big of styling done, I'm now going to give my list items everything they need to look good. Here I'm deciding to make all of my items the same width and give them a slight border to separate them from each other. To get the width property to change, I'll need to set the display property to block. As you may recall, the other major display style is inline which doesn't allow us to set exact the exact width or height of an element.

What else? Well one important aspect is that I'm making these changes to the <a> elements inside of list items instead of to the <li> list items themselves. Why? This way the <a> links take up all of the space inside of the list items and so we can hover over a larger area to click the link. Otherwise the text (or image, if we had an image inside of the link) would be the only area for the link. Last thing: links usually are underlined, have blue text, and that text is usually left-justified. I'm going to change all of that, but like so many things with webpages, what you change and exactly how you change it is a personal preference.

The Code

<style type="text/css">
/* CSS code will go here */
.menu{
   width: 350px;
   background-color: #fcc;
}
.menu ul {
   list-style-type: none;
}

.menu ul li a {
   display:block;
   width:104px; 
   border:1px solid #fff;
	
   text-align:center; 
   text-decoration:none;

   color:#000; 
   background-color:#79c;
}
</style>

The Result

Notice that the new set of rules (given in red text above) targeted all of my navigational links. That's because it looked for any a element which happened to be inside a li element which happened to be inside a ul element... which happened to be inside of an element with the class name menu. That works for my top links (Item A, Item B) or for my other links nested further inside (item 1, item 2, item 3). It doesn't matter, for example, if the ul element is directly inside my div having the class name menu or if there are a few elements between the two. So long as the ul element is somehow within that div element, this will work.

Float and Hide

Moving on, I'm now going to make a more drastic change to my list: removing all of the default margin and padding values around my list. It's hard to realize all of the default formatting that browsers give to your HTML code until you start putting in CSS rules to get rid of it. One problem with using the default settings of browsers is that different web browsers can have different default displays. Normally you won't notice these differences, but if you're trying to get your design "just right" then you'll probably want to remove default settings first with something like:

* {margin:0px; padding:0px;}
That line would remove the margins and padding of all HTML elements. You could then set the margin or padding with normal CSS rules below that (which will override this top rule) or use more specific CSS rules to again override this top rule just in the specific cases where you want to do so.

For now, I'm just going to set the margin and padding for <ul> elements to 0. Remember that this works for both my outermost <ul> and the other <ul>'s nested further inside it. Also, for all of my list items I'm going to set them to float: left;. Now, instead of each list item being on a unique line, groups of list items can be kept on the same line. This will allow me to easily make my final menu horizonal or vertical.

The Code

<style type="text/css">
/* CSS code will go here */
.menu{
   width: 350px;
   background-color: #fcc;
}
.menu ul {

   margin: 0;
   padding: 0;
   list-style-type: none;
}

.menu ul li {
   float: left;
}
.menu ul li a {
   display:block;
   width:104px; 
   border:1px solid #fff;
	
   text-align:center; 
   text-decoration:none;

   color:#000; 
   background-color:#79c;
}
</style>

The Result

For my last bit of static presentation, I'm going to make use of another major presentation setting. For my nested lists, instead of setting their displays to block or inline, I'm going to set the display to none. Then my HTML is invisible and other parts of the code act as though it doesn't exist. Why is this useful? Because we can later make it visible in response to actions make by the webpage's user.

The Code

<style type="text/css">
/* CSS code will go here */
.menu{
   width: 350px;
   background-color: #fcc;
}
.menu ul {
   margin: 0;
   padding: 0;
   list-style-type: none;
}
.menu ul li {
   float: left;
}
.menu ul li a {
   display:block;
   width:104px; 
   border:1px solid #fff;
	
   text-align:center; 
   text-decoration:none;

   color:#000; 
   background-color:#79c;
}

.menu ul li ul { display: none;}
</style>

The Result

Hover Magic

Now we're finally ready to make our list react to user actions. This is possible through CSS using the hover pseudo-class. This allows us to set different presentational rules for HTML elements when a computer mouse hovers over them. Another such pseudo-class is active. This works when an HTML element is active, such as when a computer mouse clicks on it.

I'm going to start out reacting to the computer mouse hovering over a list element. Specifically, when the mouse hovers over a <li> list item element then the presentation of any <ul> list element will change. Remember the nested lists that were made invisible? Now they can come back when I set their display property to block.

The Code

<style type="text/css">
/* CSS code will go here */
.menu{
   width: 350px;
   background-color: #fcc;
}
.menu ul {
   margin: 0;
   padding: 0;
   list-style-type: none;
}
.menu ul li {
   float: left;
}
.menu ul li a {
   display:block;
   width:104px; 
   border:1px solid #fff;
	
   text-align:center; 
   text-decoration:none;

   color:#000; 
   background-color:#79c;
}
.menu ul li ul { display: none;}


/* :hover actions that don't work in IE :( */

.menu ul li:hover ul {
   display:block;
}
</style>

The Result

You'll notice that when you hover over List A or List B you'll get the submenu items to appear. Still, this doesn't look like the nice, drop-down menu we want. To do this we'll use a two part trick involving the position property. We'll set the position property of only the nested <ul> elements to absolute, and we'll set the position property of the list items to relative. This makes the submenu items line up directly under their containing item headings. In the example picture below the mouse is hovering over the Item A link, which reveals below the submenu it contains.

The Code

<style type="text/css">
/* CSS code will go here */
.menu{
   width: 350px;
   background-color: #fcc;
}
.menu ul {
   margin: 0;
   padding: 0;
   list-style-type: none;
}
.menu ul li {
   position: relative;
   float: left;
}
.menu ul li a {
   display:block;
   width:104px; 
   border:1px solid #fff;
	
   text-align:center; 
   text-decoration:none;

   color:#000; 
   background-color:#79c;
}
.menu ul li ul { 
   display: none; 
   position: absolute;
}


/* :hover actions that don't work in IE :( */
.menu ul li:hover ul {

   top: 20px;
   left: 0px;
   display:block;
}
</style>

The Result

Why does this work? Normally the absolute value means that HTML elements are positioned absolutely with respect to the entire webpage. But, and this is a subtle CSS trait that's not found in many beginner tutorials, CSS rules are inherited. So, when we made the <li> elements have relative position that also affected the <ul> list elements that were nested inside <li> elements. Now those <ul> list elements are positioned "absolutely", but with respect to their containing element (here, whichever <li> element it happens to be nested inside). This point is a little bit complicated and not something you need to fully understand. Just know that it worked.

While the use of the position property was tricky, the two other new lines of code are quite simple: top sets the distance that an element is below where it might other wise be absolutely positioned and left sets the distance that element is moved to the right (away from the left). There are, of course, similar properties down and right. Here 20 pixels (20px) worked for the top's value, but you can try other things. In this particular case, the menu might even work without these properties, but they are useful if you were going to change this menu.

Finally, it's important to give the users of your webpage some feedback when they use the mouse to hover over your navigational links. In the new code below I'm changing the background color of the links when the mouse hovers over them. Because of the way these CSS rules apply I'm also having to make a special presentational rule for my submenus as well. In the example picture below the mouse is hovering over the item 2 link, which is in a list contained within the Item A list item. Try tweaking, or removing, parts or all of the CSS code to see what affect each part has. With the CSS code below, you should get a fully functioning drop-down menu of links (provided that you're viewing it in a standards-compliant browser).

The Code

<style type="text/css">
/* CSS code will go here */
.menu{
   width: 350px;
   background-color: #fcc;
}
.menu ul {
   margin: 0;
   padding: 0;
   list-style-type: none;
}
.menu ul li {
   position: relative;
   float: left;
}
.menu ul li a {
   display:block;
   width:104px; 
   border:1px solid #fff;
	
   text-align:center; 
   text-decoration:none;

   color:#000; 
   background-color:#79c;
}
.menu ul li ul { 
   display: none; 
   position: absolute;
}


/* :hover actions that don't work in IE :( */

.menu ul li:hover a { 
   color:#fff; 
   background:#057; 
}
.menu ul li:hover ul li a {
   color:#000; 
   background:#ccf;
}
.menu ul li:hover ul {
   top: 20px;
   left: 0px;
   display:block;
}

.menu ul li ul li:hover a {
   color:#fff; 
   background:#057;
}
</style>

The Result

Grading: What To Turn In

Things to Submit

  1. Flyout menu (or basic dropdown menu if you can't get the flyout to work)
  2. Comments in your HTML code stating your collaborators and resources used.

Description

From the mini-tutorial above, you should have been able to construct a drop-down menu of links that works in Firefox (and other standards-compliant browsers). Create a webpage with such a working menu and save it as prelab2.html in your provided Duke webspace just as you did for your lab 1 assignment.

However, instead of having a drop-down menu, for your prelab2.html file please make it a flyout menu instead. This has the main navigational links listed in a vertical column rather than a horizontal row. An example picture is shown below, and then an important comment about how to create it is given below that.

A "Flyout" Menu

To create this menu you actually only have to change 3 property values in the original drop-down menu described above. So complete the drop-down menu and then try tweaking it to get the flyout menu. If you can create the original menu but not the flyout menu that's fine. Just turn that in and you'll get almost full credit. As for making the flyout menu, the big thing to realize is that the menu headers (the list items) were floated. Floated elements are laid out in a horizontal line as long as there is room inside the width of their containing element. Otherwise, the first floated element that can't fit is wrapped down to the next line and we start again from there. So a simple change might get things stacked vertically, and then you only need to push the submenus a little out away from the left.


The prelab was developed by Sam Slee.