CSS menus and columns

Often times, web developers need to match JavaScript and table extended sites with a different toolbox. The tools are, of course, CSS classes.

Multi level pure CSS menus

The old tried and true method for this is basically the :hover attribute on list items. It can work for one, two or as many as you need (though I’d keep the number under 5).

This trick involves selectively displaying one menu while selectively hiding it’s children’s children. That is, you want an item’s sub-menu displayed while hiding that sub-menu’s own sub-menues.

First, the basic menu structure :

<ul class="nav">
   <li><a href="">Home</a></li>
   <li><a href="">Item with submenues</a>
      <ul>
         <li><a href="">Level 1 Item 1</a></li>
         <li><a href="">Level 1 Item 2</a></li>
         <li><a href="">Level 1 Item with submenu</a>
            <ul>
               <li><a href="">Level 2 Item 1</a></li>
               <li><a href="">Level 2 Item 2</a></li>
               <li><a href="">Level 2 Item with submenu</a>
                  <ul>
                     <li><a href="">Level 3 Item 1</a></li>
                     <li><a href="">Level 3 Item 2</a></li>
                     <li><a href="">Level 3 Item 4</a></li>
                     <li><a href="">Level 3 Item 5</a></li>
                     <li><a href="">Level 3 Item 6</a></li>
                  </ul>
               </li>
               <li><a href="">Level 2 Item 4</a></li>
               <li><a href="">Level 2 Item 5</a></li>
               <li><a href="">Level 2 Item 6</a></li>
            </ul>
         </li>
         <li><a href="">Leve 1 Item 4</a></li>
         <li><a href="">Leve 1 Item 5</a></li>
         <li><a href="">Leve 1 Item 6</a></li>
      </ul>
   </li>
</ul>

As you can see, this menu example has three levels. The middle item in the first two sub levels have another menu inside them.

Now the basic CSS for the menu:


/* This will be the menu bar container */
div.nav
{
   min-height:29px;
   background:#333;
}

/* We want our lists to be "clean" */
ul.nav, ul.nav li, ul.nav li ul
{
   margin:0;
   padding:0;
   list-style:none;
}

/* A background color or image is required 
or the menu will disappear on a hover */
ul.nav, ul.nav ul li a
{
   background:#333;
}

/* This is for the menu bar */
ul.nav li
{
   float:left;
   position:relative;
   display:block;
}

/* The dropdown list. This is set to 200px wide */
ul.nav li ul
{
   display:none;
   position:absolute;
   width:200px;
   top:25px;
   left:0;
}

/* Override the styles above since we want 
the dropdown to behave as a list */
ul.nav li ul li
{
   position:relative;
   float:none;
   display:block;
}

Notice how the <ul> inside the menu bar (the first level dropdown) is set to display:none;. This is how we keep the dropdown menu hidden until they are needed.

The next step is to stagger the menus so they appear out of the way of the parent menu. In this case, we’re moving it 200px to the left. The exact width of the menu.


ul.nav li ul li ul
{
   left:200px;
   top:0;
}

Now comes the fun part…

We want to make sure that a menu deploys only when the cursor is over the parent item. But we don’t want all of the sub menus within that item to show up.


/* Open the sub menu on mouseover */
ul.nav li:hover ul, ul.nav li ul:hover
{
   display:block;
}

/* Keep child sub menus from deploying */
ul.nav li:hover ul li ul, ul.nav li ul:hover li ul
{
   display:none;
}

From now on it’s just a matter of maintaining the same pattern throughout your CSS. Except, you add a li ul part to the end and move the :hover part back.

Here’s the CSS for the next level…
Modifications in red.


ul.nav li ul li:hover ul, ul.nav li ul li ul:hover
{
   display:block;
}
	
ul.nav li ul li:hover ul li ul, ul.nav li ul li ul:hover li ul
{
   display:none;
}

And follow the pattern…


ul.nav li ul li ul li:hover ul, ul.nav li ul li ul li ul:hover
{
   display:block;
}

Now we style the links inside the lists…


ul.nav li a
{
   padding:5px 10px 7px 10px;
   display:block;
   color:#ccc;
   min-width:60px;
   text-align:center;
   text-decoration:none;
}

ul.nav li ul li a
{
   padding:5px 10px;
   text-align:left;
}

ul.nav li a:hover
{
   color:#333;
   background:#dde;	
}

Now, our menu bar is compelete. We’ll take a look at what that looks like.

It’s getting a bit hard to discern where the menu belongs. Most people can tell where the sub menu originates, but I’d like to include a nice helper to act as a “breadcrumb”. We can use a small arrow image to get this effect.

Modify the CSS as follows


ul.nav li ul li ul
{
   left:200px;
   top:0;
   background:transparent;
   padding: 0 0 0 16px;
}

And now for the arrow image :


ul.nav li:hover ul, ul.nav li ul:hover
{
   display:block;
   background:url('img/rarrow.png') top left no-repeat;
}

Let’s see the results of the modifications.

Now if you want to switch from left flowing to right flowing menus, you can override the above styles. I would recommend creating a seperate stylesheet for this so you can easily switch from right to left.

ul.nav li ul li ul
{
   left:0;
   margin: 0 0 0 -216px;
   padding: 0 16px 0 0;
}

ul.nav li:hover ul, ul.nav li ul:hover
{
   background:url('img/larrow.png') top right no-repeat;
}

Now we can see what that looks like.

And now we can move on to the rest of the layout…

CSS Columns

Short explanation:
As of CSS 2.1, there’s no actual provision for columns in HTML documents. So we’ll have to use an image to “simulate” a column.

Long explanation.
We’re going to float the main content to the left and the sidebar to the right. Then, we’re going to seperate the two with a repeating image vertically at exactly where the two content blocks are seperated.

This is actually a very simple step. Modify and append to the CSS as follows…


div.body
{
   clear:both;
   background:url('img/dbg.png') 70% repeat-y;
}

div.main, div.sidebar
{
   float:left;
}

div.main
{
   width:70%;
}

div.sidebar
{
   width:30%;
}

/* This will clear the content and force 
the columns to extend to their full height.
You will need to add this right after the sidebar 
div in your HTML */
hr
{
   background:#fff;
   color:#fff;
   height:1px;
   clear:both;
   margin:0;
}

We’ve basically placed the vertically repeating background image at exactly the same width as the “main” div. This gives the illusion of columns.

The result is as follows.

It doesn’t have to look as ugly as it does now. With some other additions, you can make it look like a presentable theme
And adding in the above modification for the right handed menu, you can even switch positions.

Of course, you don’t have to stop there.
By adding another stylesheet, you can override the navigation and footer images and bring about more changes.

About these ads

One thought on “CSS menus and columns

  1. Pingback: How can I switch the right and left column of a wordpress theme?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s