Creating a CSS Driven Drop Down Menu using CMenu

[CMenu] offers great functionality and the ability to customize just about every aspect of the output. There are many times when I need to create a drop down menu or simply modify the look to make the designers happy. Because this seems to be a common task for me, I figured I would share my code to create a very simple drop down menu that other people could use.

There are many ways to approach this but I wanted to start out very simply so we are going to accomplish this using nothing but CSS.

Here is our desired output:

<div id="menu-top"> 
  <ul id="yw1">
    <li id="itemCompany"><a id="menuCompany" href="/company/index">Company</a>
      <ul>
        <li class="active"><a href="/company/index">Our Mission</a></li>
        <li><a href="/company/aboutUs">About Us</a></li>
        <li><a href="/company/careers">Careers</a></li>
        <li><a href="/company/contactUs">Contact Us</a></li>
        <li><a href="/company/storeLocator">Store Locator</a></li>
      </ul>
    </li>
    <li><a id="menuBlog" href="/blog/post/index">Blog</a></li>
    <li id="itemChange"><a id="menuChange" href="/change/index">Change</a>
      <ul>
        <li><a href="/change/index">Community Involvement</a></li>
        <li><a href="/change/ecoPolicy">Eco Responsibility</a></li>
        <li><a href="/change/responsibility">Responsibility</a></li>
      </ul>
    </li>
    <li><a id="menuBuy" href="/shop">Shop</a></li>
  </ul>
</div> 

And here is the code we are going to use to create this output:

<div id="menu-top">
<?php
$this->widget('zii.widgets.CMenu',array(
  'activeCssClass'=>'active',
  'activateParents'=>true,
  'items'=>array(
    array(
      'label'=>'Company',
	  'url'=>array('/company/index'),
	  'linkOptions'=>array('id'=>'menuCompany'),
      'itemOptions'=>array('id'=>'itemCompany'),
      'items'=>array(
        array('label'=>'Our Mission', 'url'=>array('/company/index')),
        array('label'=>'About Us', 'url'=>array('/company/aboutUs')),
        array('label'=>'Careers', 'url'=>array('/company/careers')),
        array('label'=>'Contact Us', 'url'=>array('/company/contactUs')),
        array('label'=>'Store Locator', 'url'=>array('/company/storeLocator')),
      ),
    ),
    array(
	  'label'=>'Blog',
	  'url'=>array('/blog/post/index'),
	  'linkOptions'=>array('id'=>'menuBlog')
    ),
    array(
      'label'=>'Change',
	  'url'=>array('/change/index'),
	  'linkOptions'=>array('id'=>'menuChange'),
      'itemOptions'=>array('id'=>'itemChange'),
      'items'=>array(
        array('label'=>'Community Involvement', 'url'=>array('/change/index')),
        array('label'=>'Eco Responsibility', 'url'=>array('/change/ecoPolicy')),
        array('label'=>'Responsibility', 'url'=>array('/change/responsibility')),
      ),
    ),
    array(
      'label'=>'Shop',
      'url'=>array('/shop'),
      'linkOptions'=>array('id'=>'menuBuy')
    ),
  ),
)); ?>
</div>

Let's dig into the code to see what is happening here.

[CMenu::activeCssClass] is simply the CSS class that will be assigned to the active menu item. The active menu item simply indicates the current page you are viewing by adding some style to that menu link. [CMenu::activateParents] means that when a child item is activated, the parent of that item will be given the 'active' css class assignment as well.

You will notice that the 'Company' item has another [CMenu::items] array set under it that will be the items that show up in the drop down when a user hovers over 'Company' in the menu.

Also, in the parent items ( Company, Blog, Affecting Change, Shop ) you will see that we take advantage of the [CMenu::linkOptions] property in order to add an ID to tag that Yii will output wrapping the label. I needed to do this because the menu I am creating uses sprites which means I need an ID for each menu item to specify the background-position property of each item independently.

Ok so now that we have our PHP setup, let's dig into the CSS part. I am also not going to include the code for the sprites to keep things simple.

[css]
#menu-top ul { list-style: none; margin: 0; padding: 0; position: relative; height: 30px; }

#menu-top ul li { display: block; height: 28px; float: left; overflow: visible; }
#menu-top ul li:hover > ul { display: block; }

#menu-top ul li a { float: left; display: block; }

#menu-top ul li ul { display: none; position: absolute; top: 100%;
					background: #000; color: #fff; height: auto;
}

#menu-top ul li ul li a { color: #ccc; padding: 4px 14px; display: block; }

#menu-top ul li ul li.active a,
#menu-top ul li ul li a:hover { color: #fff; }

An important part to pay attention to is setting the overflow to visible on the '#menu-top ul li' elements. Otherwise, when you mouseover an parent item, the child items will not be visible.

The line that does all the magic is:

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

This simply means that when a user hovers over a parent item ( ul li ), take any child ul elements and switch them from 'display: none;' to 'display: block;' making them visible.

Once you put this all together, you should have a nice little drop down menu with active highlighting.

19 1
26 followers
Viewed: 90 059 times
Version: 1.1
Category: How-tos
Written by: blindMoe
Last updated by: blindMoe
Created on: Jun 23, 2011
Last updated: 6 years ago
Update Article

Revisions

View all history

Related Articles