pandora beads
pandora bracelets
pandora charms
pandora
The Site-Shack Blog — Shack Blog

WordPress 3 Dynamic Menu: a Pure CSS Drop-down

A few days ago, I had the opportunity to code up the navigation of a web site that included a secondary, drop-down menu system and was asked to have it completed in the next couple days.

“Pffft, no problem”, I thought. I’ll knock it out before lunch, and move on to the next thing. I’ve built hundreds of Nav/sub-nav systems before – typically relying on Javascript to create the drop-down event. Then I discovered that this particular nav system was destined to go into a Wordpress 3 CMS based web site for use as Wordpress 3’s new, built-in dynamic menu, and that I had just two IDs or Classes that I could use in order to work with the existing Wordpress Style sheet. Then came the pièce de résistance, this was to be a pure CSS drop-down. No Javascript allowed.  Oh-oh!

If you are anything like me, you probably know some of the basics of creating a purely CSS driven drop-down sub-menu; it uses the CSS pseudo-class “hover” to make the drop-down menu appear, but at least in my case, the exact details have been elusive. So after what turned out to be a six hour learning process, I now have discovered a working method for achieving what was once the Holy Grail of web site navigation. Let me see if I can share what I’ve learned.

Okay, so the plan is to build a horizontal main navigation row with a single sub-menu that drops down from the parent and will contain our secondary navigation links. Viewed from a search engine optimized, semantically correct point of view the series of links making up the main navigation of a web page is really a list of items which happen to be anchor tags. So our first step is to build an “unordered list”, or in HTML, more commonly viewed as the “UL” tag. Here’s our simple Nav row of three items.

<ul id="nav">
    <li><a href="#">Link One</a></li>
    <li><a href="#">Link Two</a></li>
    <li><a href="#">Link Three</a></li>
</ul>

Our sub-menus will be two more unordered lists positioned as children of the second and third list-items in “nav”. I’ll drop them in there now.

<ul id="nav">
   <li><a href="#">Link One</a></li>
   <li><a href="#">Link Two</a>
      <ul>
         <li><a href="#">Sub One</a></li>
         <li><a href="#">Sub Two</a></li>
      </ul>
   </li>
   <li><a href="#">Link Three</a>
      <ul>
         <li><a href="#">Sub One</a></li>
         <li><a href="#">Sub Two</a></li>
     </ul>
   </li>
</ul>

Working with the two identifiers available to us from the Wordpress stylesheet, I’ve given our main navigation an ID of “nav”. I’ve chosen to use an ID in this case rather than a Class because our main navigation will be the only thing like it on the page. An ID is a unique identifier and should be used when there is only one of a certain item on a page. An ID also has greater specificity than a Class, meaning its styles will take precedence over the styles of items given a Class within the same page. Our drop-downs will be child elements of list-items within “nav” and there will be more than one, so I’m giving them both a Class called “sub-menu”.

If we were to view what we have so far in a web page we’d just have a typical bullet list like so:

  • Link One
  • Link Two
    • Sub One
    • Sub Two
  • Link Three
    • Sub One
    • Sub Two

But we want this to be a horizontal navigation with boxes for links, and the sub-links hidden from view until we mouse-over them. Guess we’re going to have to build a Cascading Style Sheet.

You probably just said, “Well, Duh! How else would we do this?” Obvious next step, yes, but the reason I mention that we need a CASCADING style sheet is just to point out that we are working with just two identifiers in order to make all our styles for this menu system; the ID #nav, and the Class .sub-menu. Due to the specificity of #nav, its styles will directly cascade down to .sub-menu, which in some ways we want to happen, and in others, we definitely do not. In order for us to make the links in our drop-down menu have a different look and characteristics from the main navigation, my choice (if I had my way) would be to use an ID for top-level <ul> tag and a class for the top-level <li> tags, then have a another ID for the secondary <ul> tags and another class for the secondary <li> tags – this would keep everything separated and make life much easier, but given our restraints we will have to rely on listing our elements in the style sheet by descendants in order to control style inheritance.

Alright, let’s get that style sheet built starting with the top-level <ul>. We want the links to be block-level elements rather than inline elements, and we want them to float next to each other rather than be stacked as they are in the bulleted list above. While we’re at it, let’s unload those bullets too.

ul#nav  {
 position: relative;
 width: 384px;
 height: 30px;
 padding: 0 8px;
 border-top: 1px solid #000000;
 border-bottom: 1px solid #000000;
}

Let’s look at what I’ve done so far. First off, a UL element is a block-level object – it has height and width values and can have margins. In contrast, an inline object takes up no more space on a page then the length of the string of text and the line-height of the font used. So in our case, #nav is the container for the whole navigation system. I give it a relative position on the page which will become necessary later in order to contain our .sub-nav object. For my desired appearance, I’ve set the width value to 384px and height to 30px. I want 1px solid black borders on the top and bottom, and 8px padding on the right and left, but none on the top and bottom.

ul#nav li  {
 display: block;
 float: left;
 height: 30px;
 width: 128px;
 overflow: hidden;
 list-style-type: none;
 background-color: #efefff;
}

Now our list-items are children of the parent object, #nav. Contrary to the default setting for Li objects, we need these to be block-level elements because they will be what triggers our .sub-nav menu when the user hovers their mouse over a link contained within the list-item. We want the navigation links to line-up horizontally across the page so I float them to the left. I want the <li> to be the full 30px height of the container, and I’m giving them a width of 128px. The Overflow property is initially set to “hidden” because we do not want the .sub-nav objects to be visible until the user hovers their mouse over the target area. “List-style-type: none;” makes the bullets go away, and lastly, I’ve set a background-color on my <li> just temporarily so that I can verify that it’s behaving the way I want. I’ll remove the background-color later since it’s not really part of my final design.

ul#nav li a {
 display: block;
 width: 126px;
 height: 20px;
 margin-top: 5px;
 font: normal 11px/20px Verdana, Geneva, sans-serif;
 text-align: center;
 text-decoration: none;
 color: #000000;
 border-left: 1px solid #000000;
 background-color: #ffffaa;
}

ul#nav li:first-child a {
 border: none;
}

Our next step is to style the top level anchor tags which are the actual links in our navigation. Here again, we want the anchor tags to be block level elements so that they produce a box which will provide more clicking area for the user than an inline element will. An interesting thing to note here is that in my font style I’ve set a line-height of 20px – that’s the same value as the height of my anchor tag. This will result in my text being centered vertically in the link object.  The last part of this I’ll mention is that I have set a 1px solid border-left to all the anchor elements to act as a visual divider between each of the links in the navigation. However, I don’t want a line before the first link which is what we would have with this style rule, so by using the “first-child” pseudo-class I can target just the first anchor element which is a child of the list-items within #nav and set its border value to “none”. Now this is what displays on our web page:

So far, so good. We have our three top level links with text centered vertically and horizontally in their boxes. Again, the background color is just a visual aid at this time. The gray area is our block-level <li> elements, and the yellow shows us the block-level <a> elements. The second level links are successfully hidden on page load as planned, so our next step is to style them and make them appear on command.

Boom! Here it is all at once:

ul#nav li:hover {
 overflow: visible;
}
ul#nav ul.sub-menu {
 margin-top: 5px;
 padding: 30px 0;
 background-color: #dfdfdf;
 border-top: 1px solid #000000;
 overflow: hidden;
}
ul#nav ul.sub-menu li {
 height: 15px;
 font: normal 11px/15px Verdana, Geneva, sans-serif;
 background-color: transparent;
}
ul#nav ul.sub-menu li a {
 display: block;
 padding-left: 15px;
 width: 111px;
 height: 15px;
 margin-top: 0;
 font: normal 11px/15px Verdana, Geneva, sans-serif;
 text-align: left;
 text-decoration: none;
 color: #000000;
 background-color: transparent;
 border: none;
}

ul#nav ul.sub-menu li a:hover {
 text-decoration: underline;
}

 

Since I’m sure you’re getting a feel for this, I’m just going to hit the high points now. The first thing to see here is the last style rule we’ll set for #nav — it’s where all the magic happens. The hover pseudo-class for <li>elements in #nav is set to “overflow: visible”, so when the user positions their mouse pointer over a list item, the overflow property switches from hidden to visible and of course the child element, which is our drop-down menu is revealed.

When setting the styles for the .sub-menu, keep in mind that it is a child of #nav and will inherit all styles that have previously been set for #nav which is the parent element. If you want the drop-down to have a different visual style than the top-level links, you will have to restate the styles with their new values in order to over-write previously set styles.

When setting independent styles for child elements, it is crucial that you indicate the descendance of the element. This specifically targets the element you are trying to style and will override earlier styles. This is why my style rules include not just the class name of the element I’m styling, but also the element from which it descends. For example “ul#nav ul.sub-menu li” targets only the <li> which are children of the class “.sub-menu”, which itself is a child of the <ul> “#nav”. If you omit the descendance and just type, “.sub-menu li” and set it’s styles, the .sub-menu list-items will inherit the style of #nav list-items because of their greater specificity and you’ll tear your hair out trying to understand why your styles don’t work. Alright. Enough said about inheritance. Let’s make sure our drop-down menu works the way we are expecting.

What we expect as a visitor to this web page is for a drop-down list of links to display when we run our mouse over the top-level link. We expect the sub-menu to vanish if we move our mouse off the main link, and we expect the sub-menu to persist if we move our mouse vertically down the sub-menu until we either move far enough south, or far enough horizontally to come off the sub-menu links. So we have to make certain there is no gap between the bottom of the main, top-level link, and the top of the first link in the sub-menu. A single pixel gap is too much. In my example, for .sub-menu,  I set a margin-top of 5px which will leave one pixel remaining inside the main menu and the rest extending downward from there. Since I’m overlapping the bottom border of #nav with .sub-menu, I have added an identical 1px border at the top of .sub-menu which will visually replace the segment hidden by the drop-down. So technically, that’s about it. The rest is just styling the appearance that I want for .sub-menu by either adding new style rules or over-writing previous values to get what I want. After removing any background-color I added temporarily to check the position and size of objects, my final navigation menu looks like this:

Hopefully, I touched on enough of the sticking points in my drop-down menu build to give you the clues you’ll need to make your own build a trouble-free experience. So, good luck and happy coding.

Acquia Webinar Lists Top Drupal eCommerce Modules

This morning, Acquia presented a Webinar entitled: “Using Open Source Drupal to Rapidly Deploy New Features for e-Commerce.”  This was a strong presentation chock-full of some very helpful take-aways. One of my favorites was a list of recommended modules for ecommerce *although* a goodly number are designed to work with UberCart and not (it seems) Drupal Commerce — which, btw, got a solid recommendation from the panelists. And yet . . . UberCart is quickly moving toward UC3 for D7: See the UC road map at http://drupal.org/node/696816. As of April 6, 2011, the UC developers were looking for a few good reviewers to break some code. It is a rare day in Open Source when the last chapter is written.

You can find that list right here:

Ubercart – the venerable Drupal eCommerce module. Note that conversation regarding Ubercart’s viability in Drupal 7 was plentiful. Short answer: Drupal Commerce is the one to use if you’re working in D7. DC is in beta as of now. Hang on awhile longer. But I for one still want to test the UC3 roll out.

Speaking of: Drupal Commerce. Yep, recommended by Acquia during the Q&A if you’re going to run D7. All of this a topic unto itself.

Voucher – Othewise known as Ubercart Discount Coupons. Coupons galore and all kinds of ways to implement them. Is there a D7 (another way of saying a UC3) release? Not on the horizon, I think.

Apache Solr – Written in Java, Solr is an open source enterprise search platform from the Apache Lucene project. Its major features include powerful full-text search, hit highlighting, faceted search, dynamic clustering, database integration, and rich document (e.g., Word, PDF) handling. Drupal’s Solr search can be used as a replacement for core content search and boasts both extra features and better performance. D7 release still in dev.

Recommendations – Another UberCart module. From the module page: “The ‘Recommended for you’ block provide personalized products recommendations based on a user’s purchasing history.” D6. Looks like its slowly enroute to D7, presumably meant to work with UC3. Just guessing.

Upsell – From the module page: “UC Upsell is an advertising / upselling module for Übercart that allows merchants to associate multiple products together. These “related products” can be displayed as a themeable block either at the cart page, on other product detail pages, or both. Since it’s a block, it can be displayed whenever the themed block is called.” No information re a D7 port to UC3.

EUVAT Support – Well, I don’t know that this one would be on my list, necessarily. Anyway, from the module page: “This module provides support for European VAT pricing and regulations in Ubercart 2, allowing your store to show product prices inclusive of VAT. You do not need this module if you only want to charge VAT at checkout.” Longwave commented on the D7 Port page for this module: “I will wait to see what UC3.0 supports before working on a D7 release of uc_vat.”

Rating and Review – Another oldie but goodie. D7 release in development. I’ve never used it (maybe I wanted to avoid the horror of only receiving a single star for something or the other) but it’s always worked well and even sorta a fun thing to offer site visitors and users.

You can find out more about Acquia’s Webinars at www.acquia.com/resources/webinars. And check out Acquia’s upcoming Drupal in a Day events at www.acquia.com/community/resources/events.

SoundCloud full of great Bob M…

SoundCloud full of great Bob Marley mixes: http://bit.ly/i5SKuu. The WWW never ceases to amaze and entertain.

Dinnertime and still online –…

Dinnertime and still online — tweaking player skin for SoundCloud. Feels like I haven’t been offline since 1992 & first saw the WWW.

Worse part of the Flip’s death…

Wores part of the Flip’s death is what we won’t see. What was Cisco thinking!? The Tragic Death of the Flip – http://nyti.ms/f0cTyY

Drupal 6 Nice Menus > A Visual Quick Start Guide

There are many times when I need to explain a concept or process to a client. I often want to do this expeditiously, quickly, clearly — without resorting to setting up a training and driving across town armed with laptop and the rest. Besides, empowering the client to manage his or her own content represents a core component of our business philosophy: the tasks that the client can learn to perform and manage (assuming she wants to do this) regardless of the type of Web site allows the job to be done at the client’s pace, saves dollars and we believe creates client satisfaction. Leaving certain maintenance work with the client also frees up Site Shack to spend valuable time on more essential work, including the continuous tech training that we go through to stay current, or try to stay current.

In 2010, Site Shack created a great Drupal 6 multi-site for Garrison Service Company in Nashville. The site design featured numerous sidebar menus, all of which would need modifying over time. And of course we wanted the folks at Garrison to have the chance to create new menus too. But how to explain the beauty — albeit the somewhat intricate beauty — of Addison Berry’s (okay, I’m pretty sure that Addison Berry created Nice Menus) brilliant Drupal module? I knew the telephone and/or Skype wouldn’t be sufficient for training a Drupal newbie but neither was the car-trip-laptop-training quite warranted (unless I had other training to provide, which I didn’t).

Long way to say: Site Shack created a handy Drupal 6 Nice Menu visual guide to building all the nice menus you or your clients could ever want. So enjoy. I hope it helps someone else out there in Drupal Menu Land.

We like good photos = 8 Secret…

We like good photos = 8 Secrets to Perfect Pet Photos – http://nyti.ms/eLQJfW

The best value a Web developer…

The best value a Web developer will find anywhere online: http://www.lynda.com/

Site Shack moves to Amazon Web…

Site Shack moves to Amazon Web Services EC2. AWS: brilliant logic and well marked paths. Cloud hosting also often so pricey: not this.

Amazon Cloud nice but will mus…

Amazon Cloud nice but will music industry go with? For now: 5GB just for being. There. Nice, actually. More at http://www.amazon.com/.

1518 fatherland street * nashville, tn 37206 * PH 615.228.4757 land * PH 615.275.6708 mobile
www.twitter.com/siteshackdesign * info@site-shack.com
FOR YOUR CONVENIENCE WE TAKE VISA AND MASTERCARD

copyright © 2004 – 2011 Site Shack Web Design Nashville TN and Beyond