The Bartik theme doesn't support drop down menus as standard and there are various ways of addressing this, mostly using modules such as superfish.

Here's a way of adding them to a Bartik sub-theme, using a couple of theme function overrides and some CSS.

We will:

  • Add the built in main menu block in the header region
  • Remove Bartik’s main menu implementation
  • Apply some CSS to turn the menu into a drop down menu

No additional modules required! (I've also documented this with pictures on my personal site.)

Add main menu block to header region

We will start by adding the main menu block to the header region. Go to admin/structure/block and add the Main menu block to the header region. Add some children to some of the menu items and make sure the parent item is expanded.

When we refresh the page we should see another menu, albeit expanded, in the header.

Remove existing menu

First create a sub-theme of Bartik. In this example I've called our sub-theme Bartik Drop Down (machine name bartikdropdown).

We can see that in page.tpl.php of Bartik (bartik/templates/page.tpl.php) there’s a line

<?php print theme('links__system_main_menu', ...

which renders a list of links. Currently this invokes the core function theme_links (includes/theme.inc) but we’ll define our own theme hook which returns null:

function bartikdropdown_links__system_main_menu() {return null;}

Add this to template.php of the sub-theme. Refresh the page (clearing the caches if necessary) and the Bartik menu should disappear.

Restyle the new menu

Looking at Bartik’s page.tpl.php, the menu is an unordered list element with id main-menu-links so we’ll try adding the same id to the our new menu and hopefully it’ll take on the Bartik style!

We can do this by adding

function bartikdropdown_menu_tree__main_menu($variables) {
  return '<ul id="main-menu-links" class="menu clearfix">'.$variables['tree'].'</ul>';
}

to template.php in our sub-theme. This overrides theme_menu_tree, adding the main-menu-links id.
If we check the page again we'll see that it isn't quite right and it requires some CSS to deal with the block-related styling around the menu:

.region-header {clear: both; float: none; margin: 0;} /* move menu back into block flow */
.region-header .block-menu {font-size: 1em; width: auto; margin: 0; border: 0;} /* move menu back into block flow. The 1em is to reset the region-header block 0.857em */ 
.region-header .block-menu li a {border-bottom: 0;}

The menu should now look pretty much like the original Bartik menu, except the drop down elements are visible and not in the correct positions.

We now need to add some styling for the drop down menu:

/* dropdown stuff */
#main-menu-links a {
  float: none;
}
#main-menu-links ul {
  padding: 0;
  position: absolute;
  left: -1000px;
}
#main-menu-links li:hover ul {
  left: auto;
  z-index: 1000;
}
#main-menu-links ul li {
  float: none;
  margin: 0;
  padding: 0;
}
#main-menu-links ul li:hover a {
  background: rgba(240, 240, 240, 1);
}

#main-menu-links ul a {
  background: #ccc;
  background: rgba(200, 200, 200, 0.7);
  width: 150px;
  -khtml-border-radius-topleft: 0px;
  -khtml-border-radius-topright: 0px;
  -moz-border-radius-topleft: 0px;
  -moz-border-radius-topright: 0px;
  -webkit-border-top-left-radius: 0px;
  -webkit-border-top-right-radius: 0px;
  border-top-left-radius: 0px;
  border-top-right-radius: 0px;
}

/* active link */
#main-menu-links li.active-trail a {
  background: #ccc;
  background: rgba(200, 200, 200, 0.7);
}
#main-menu-links li.active-trail>a {
  background: #ffffff;
}

Check the page again (clearing caches if necessary) and you should have working drop down menus!

Comments

brayo4’s picture

as easy as A B C....thanks for your help.................

fbastage’s picture

thanks. this is totally what I wanted and needed.

bsarchive’s picture

I'm struggling to get this to work. The main menu is recreated in the right place OK but I can't see the second level drop down menu items. I've followed the steps religiously (I think!) and put second level menu items in the Main Menu links. Any ideas?

susan5in7’s picture

I have replied late but I hope you have solved this problem within these days.

Please check you have select "show as expanded" while creating parent Menus. It is the most common error users do.

szopler’s picture

Please add names of files which we need to change or even better - please publish whole files with changes. Thank you!

tami.allen’s picture

The files you need to work with are page.tpl.php (remove existing menu), template.php (restyle new menu), and layout.css (for css to remove block-related styling and add styling for the drop-down).

11bananas’s picture

i'm having problems with this, i cannot seem to remove the existing bartik menu...
in your instructions you don't say anything about altering the page.tpl.php file, you simply refer to it -- is there a change that needs to be made in this file? (as you are implying by this last comment)

thanks..

marcopanichi’s picture

on touchscreen devices you can't rely on hover properties.

Vic_’s picture

Dropdown not working as eariler said in the comments.

I also did exactly as stated above, and the drop-down is not working :) any good ideas on how to take this on.

but thanks for the guide!

Br

sarojbaniya’s picture

Hi! I am not php or css guy but I have done my drop down menu using nice menu. It looks ugly. I want to make it looks like default bartik looks. I know very basic about css. so the given code looks little scary for me. so please some one guide me exactly where and which line should be over written, changed, added or removed.
Thank you.

Sahin’s picture

Your personal site link seems to be changed as:
http://www.prcweb.co.uk/2012/05/adding-a-drop-down-menu-to-drupal-7s-bar...
Better you update the link in the article.

donaldp’s picture

You can remove the default main menu using the theme appearance settings without the code in template.php.

Also using

function bartikdropdown_menu_tree__main_menu($variables) {
  return '<ul id="main-menu-links" class="menu clearfix">'.$variables['tree'].'</ul>';
}

causes invalid HTML as you get the same ID for the main menu and each menu sub-level. This can be fixed using hook_block_view_alter() as follows, where MYTHEME is the your sub-theme name in this case "bartikdropdown":

function MYTHEME_menu_tree__main_menu($variables) {
  return '<ul class="menu clearfix">' . $variables['tree'] . '</ul>';
}

function MYTHEME_menu_tree__main_menu__level1($variables) {
  return '<ul id="main-menu-links" class="menu clearfix">' . $variables['tree'] . '</ul>';
}

/**
* Implements hook_block_view_alter().
*/
function MYTHEME_block_view_alter(&$data, $block) {
  // Check we get the right menu block
  if ($block->delta == 'main-menu') {
    // change the theme wrapper for the first level
    $data['content']['#theme_wrappers'] = array('menu_tree__main_menu__level1');
  }
}
moses_msk’s picture

Hey i am newbie who has come to love drupal very much. i am trying to achieve a drop table menu on my primary menu please check the example on this link www.cssplay.co.uk/menus/drop-table.html
thank you in advance for your help.

pavi_raghu’s picture

Hi,
I did whatever you had suggested, please check i changed these files and the content you gave,

I added to the template.php

function bartikdropdown_links__system_main_menu() {return null;}
and
function bartikdropdown_menu_tree__main_menu($variables) {
return '

';
}

then added to the layout.css

.region-header {clear: both; float: none; margin: 0;} /* move menu back into block flow */
.region-header .block-menu {font-size: 1em; width: auto; margin: 0; border: 0;} /* move menu back into block flow. The 1em is to reset the region-header block 0.857em */
.region-header .block-menu li a {border-bottom: 0;}
and
/* dropdown stuff */
#main-menu-links a {
float: none;
}
#main-menu-links ul {
padding: 0;
position: absolute;
left: -1000px;
}
#main-menu-links li:hover ul {
left: auto;
z-index: 1000;
}
#main-menu-links ul li {
float: none;
margin: 0;
padding: 0;
}
#main-menu-links ul li:hover a {
background: rgba(240, 240, 240, 1);
}
#main-menu-links ul a {
background: #ccc;
background: rgba(200, 200, 200, 0.7);
width: 150px;
-khtml-border-radius-topleft: 0px;
-khtml-border-radius-topright: 0px;
-moz-border-radius-topleft: 0px;
-moz-border-radius-topright: 0px;
-webkit-border-top-left-radius: 0px;
-webkit-border-top-right-radius: 0px;
border-top-left-radius: 0px;
border-top-right-radius: 0px;
}
/* active link */
#main-menu-links li.active-trail a {
background: #ccc;
background: rgba(200, 200, 200, 0.7);
}
#main-menu-links li.active-trail>a {
background: #ffffff;
}

when i refresh the page the header section has main menu in vertical order. how to make it horizontally aligned.

rahul_sankrit’s picture

Hi,

I did exactly as stated above, and the drop-down menu is working now with Bartik Theme.

Thanks.
kumar Rahul Sankrit

roblog’s picture

Works like a charm. Works with the Responsive Bartik theme as well incidentally.

dmjohnston’s picture

I've implemented this in a sub-theme of Responsive Bartik and it works in Chrome and Firefox, but IE looks horrific. Ideas? Website is criticaldissonance.com

RajatK’s picture

Hi,

First of all thanks... Can someone please help to get similar code for Drupal 8.
Feel if the requirement is just to have drop down feature on main menu, probably going with contrib modules will be overkill. Simple update on custom theme will do the wonders..!!.