How to Add unique classes to Drupal menus
- 7 Comments
- Latest Comment
Sometimes you want to be able to style menu items individually. For example you may want to use image replacement to display icons instead of the text, or you may want to make one menu item stand out from the rest.
Drupals Primary and Secondary links allow you to do this because they print a class on the li that includes the mlid, so its easy to target a particular link doing something like:
li.menu-123 a {font-weight: bold;}But, in normal Drupal menus, the ones that appear in blocks, no such classes appear, which leaves them all with the same style.
There is a very good module for getting around this called Menu Attributes, which allows you to specify additional attributes for menu items such as id, name, class, style, and rel. The problem here is that you need an additional module, and if like us, you’re building themes for clients sites you don’t really want to rely on 3rd party modules to be installed and maintained, not for trivial design aspects such as few classes on menu items in any case.
The solution is to override theme_menu_item_link, and add the mlid to the actual link.
Drop this snippet into your template.php file and as per usual, replace themeName with your themes name.
<?php
function themeName_menu_item_link($link) {
if (empty($link['localized_options'])) {
$link['localized_options'] = array();
}
if (empty($link['localized_options']['attributes']['class'])) {
$link['localized_options']['attributes']['class'] = 'menu-'. $link['mlid'];
}
else {
$link['localized_options']['attributes']['class'] .= ' menu-'. $link['mlid'];
}
return l($link['title'], $link['href'], $link['localized_options']);
}
?>Drupal Version:
Drupal Development:
Drupal:
Technology:
Social Tags:
Comments
#3 ....
[..]menu links are not going to be changed[..]
Yes but how does this technique fix that? And how would this work if I removed and then added the menu link back, the styling wouldn’t apply and it isn’t clear on the menu UI as to why.
I like Chris’ solution considerably better as it doesn’t rely on the mlid
We often take the name of the menu item, run it through some kind of text replacement to strip out all special characters, and use that for the attribute ID
#5 And you can also use (and improve) the module :)
Daniel from Linnovate released the menuclass module that does the exact same thing.
All non coders can check it out at http://www.drupal.org/project/menuclass
#6 how about the whole menu tree?
Today I ran into a problem. I needed to add “first” and “last” class names to the first and the last menu items in a menu and I couldn’t find a solution yet (I only spent one hour searching for a solution, and I guess there is one, but I hope you can point me in the right direction). My menu is a “nice_menus” generated one. I guess I should create a function in my template.php file inside my theme folder, but I couldn’t find a solution yet. Any ideas?
#7 Worked Great
OK, Well I think this is really helfpful and I appreciate it a lot.
I have a question. Why check for localized options? we would not want to write different css for each location… or would we?
i’m guessing you use class instead of node b/c a user might have an instance of the menu in more than one spot?






#1 It’s a nice solution, but if
It’s a nice solution, but if it’s unique, it should be an id, rather than a class. We often take the name of the menu item, run it through some kind of text replacement to strip out all special characters, and use that for the attribute ID. That way, when you look back over your CSS, you know which statement refers to which menu element.