The Quest for a Better Category List – Part the First: A Basic CSS/JavaScript Popup Menu
One of the reasons I switched from Blogger to WordPress is wp’s category system, which would allow far easier access to anything of intrest I post. The category list is nice and all, and with a little tweaking displays in a nice hierarchal view.
However, a after a bit of thought I realised with my resolve to put everything in ‘child’ categories, the number of categories could rapidly rise. With that, the category list would become behemothian and as such all but useless. What I need is a way to restrict the categories shown, so that the user would only see what information they needed at the time.
Popup Lists
The Popup List technique allows for lists that display only when the ‘parent’ element is hovered over. In this example the parent shall be a <li></li> in another list that is id’d as ‘list’. The popup list will remain visible so long as the curser is over it, or it’s parent.
By default, the popup list will be absolutely positioned way off the screen, for, as we know, if it was set to display:none or visibilty: hidden the popup list mightn’t be read by screenreaders. Then again, maybe that would be preferable.
When the parent <li></li> is hovered over, the popup list’s position will be set to static, bringing it to it’s normal position in the document, shuffling other things out of the way to fit. The CSS is:
#list li ul {
position: absolute;
left: -5000px;
}
#list li:hover > ul {
position: static;
}
The first rule states that a unordered list inside a list item inside the container ‘list’ should be positioned well away from the window. The second rule states that when a list item inside ‘list’ is hovered then an unordered list that is the direct child of said list item should be positioned normally, as opposed to absolutely, for example. These two together achieve the desired effect.
An example of the code in action.
There is a catch, however. Internet Explorer 6 doesn’t recognise :hover on anything but an <a></a>, nor does it recognise any of the more contorted CSS selectors that would make it otherwise possible to use this technique. What to do, what to do… Ah-ha! JavaScript.
Add a little JavaScript
The JavaScript getElementById() method returns the HTML element of the ID given. I want to modify a HTML element — the child ul. As such, I examined the W3Schools HTML DOM Reference.
The DOM , or Document Object Model is a way of referring to many of the parts of the document object, such as the HTML elements within. We already use this to call up form inputs so we can get their value. However, we can do more than just read off data. We can acually change the existing elements on the screen. In this case I’ll change the style.
On W3Schools I found the code snippet:
document.getElementById("id").style.property="value"
This little piece of code would let me call up an element and change a property of it’s style. Using onMouseOver() and onMouseOut events would let me change the style to make it visible on the hover and then hide it again when the curser leaves.
The styles applied would be something like:
#hiddenlist {
position: absolute;
left: 5000px;
margin-bottom:0px;
}
Again, this tells the popup list to hide.
then the javascript functions:
The first of these two function reveals the popup list, the second hides it again.
And the HTML:
<ul>
<li>
Hover Over Me
<ul>
<li>Lookit Me!</li>
</ul>
</li>
</ul>
The two JavaScript events in the HTML call the showList() function when the cursor is over the <li></li> and call the hideList() funtion when the cursor leaves. As the popup list is within the <li></li> it stays open when the cursor is over it.
An example of the code in action.
The Road Goes Ever On
Well it looks like it works, so job’s done, time to apply it to the category list. All it would take is giving each of the lists a unique id and having a copy of each function to match. …or not. You see, the list is automatically generated by a wordpress function, so there is no easy way for me to add ids. And I dont wan’t to have repeated code apout the place and besides, if I add new parent categories in the future I don’t want to have to go back and edit the template again. Also, it may be more useful to have clickable toggles than roll over effects…
And so the quest continues. I’ll be looking at the hierarchy of the DOM in the near future, and maybe I’ll end up writing a custom category list function in PHP.
Great stuff Adam! Showing excellent problem solving skills there by figuring out how to do this on your own… This was one of the next things we’re all going to look into (expanding sections using CSS and Javascript), but now I can just point everyone to your blog
I like the way you’ve used the actual positioning (static or absolute) to toggle whether the sub parts are displayed. I’ve always used the display property instead (none or block).
In case you haven’t seen it, you might also enjoy Suckerfish Dropdowns (CSS-based, with Javascript for IE hack).
But as for the original problem of “categorising your categories”, I know how you feel… the programmer in you wants to put everying under it’s rightful category
. But lately I keep finding categories too restrictive, and not very user friendly for navigating. I really like the idea of tags instead. There’s some great plugins for Wordpress that will allow you to use tags instead, and even display a tag-cloud of your tags…