Table2CSS logo Table2CSS is a tool that can convert your table-based websites to tableless layouts, replace deprecated HTML tags with modern CSS and reformat your HTML code. Click here for more information

How to create a horizontal CSS drop-down menu that is search-engine friendly

In this article we will show you how to create a horizontal drop-down menu in CSS. We also use a tiny bit of JavaScript code in order to get the menu to work on Internet Explorer 6. The CSS menu will work just fine even without the JavaScript helper file on any version of Firefox and Opera and on Internet Explorer 7+. However in order to use the menu on IE6 we also need the JavaScript file.

Why use CSS to create a drop-down menu and not use one of the existing JavaScript menu scripts?

Most search engines like Google are able to find text content that is embedded inside the HTML code. This HTML content can be either contained statically in the HTML code of the web page or it can be generated by a server-side script. However search engines are quite bad at indexing dynamic content generated by client-side scripts. JavaScript menus run in the clients' browsers which means that none of the text content in these menus will be found by search engines. Additionally, search engines are unable to discover any HTML links in JavaScript generated menus, which further damages the search-engine friendliness of pages that use JavaScript-only menus.

Our drop-down menu on the other hand has all of its content embedded statically in the HTML code of the page, which means that search engines are able to find and index that text content. We use some JavaScript code in our solution but that JavaScript is not used to generate any menus and menu items. The purpose of that JavaScript is just to help IE6 pull up and down the CSS menus. The above means that our JavaScript code does not hurt the search engine friendliness of our CSS menu.

A live demonstration of our CSS drop-down menu

Below is a live demo of our drop-down menu.

Please note that the color, font styles and other properties of the drop-down menu are fully customizable through the menu CSS file. The actual number of drop-down menu items as well as their titles (captions) are customizable by editing the actual HTML code of the menu.

How to install the menu on your web page and how to customize it?

In order to install the drop-down menu on your website, follow these steps:

  • Download these two files and place them in the root directory of your website or in a subdirectory where they would be accessible by client's web browsers.


  • Add the following two lines to the <head> section of your web page:
    <link type="text/css" rel="stylesheet" media="all" href="css_horizontal_menu.css" />
    <script type="text/javascript" src="css_horizontal_menu.js"></script>
  • Insert the actual HTML content for your menu into the <body> section of your web page. In our sample demo we used the following HTML code:
    <ul class="css_menu" style="margin: 30px auto; width: 496px;">
    		<a href="#">Fruits</a>
    			<li><a href="#">Apples</a></li>
    			<li><a href="#">Oranges</a></li>
    			<li><a href="#">Pineapples</a></li>
    		<a href="#">Vegetables</a>
    			<li><a href="#">Tomatoes</a></li>
    			<li><a href="#">Potatoes</a></li>
    			<li><a href="#">Cauliflower</a></li>
    	<li><a href="#">Other</a></li>

After you make these changes you probably will want to adjust the menu items in the CSS menu as well as its look. In order to adjust the menu items and their captions, just edit the sample HTML code that we provided above. The <ul> tags in our code wrap blocks of menu items and the <li> tags wrap separate menu items. Most likely you will want to change the URLs pointed at by the separate menu items. To do that edit the <a href="#"> tags for the corresponding menu items and replace the # sign with the actual URL which should be visited when the user clicks on the menu item.

In order to modify the look of your drop-down menu, edit the css_menu.css file. there are comments delimiting the two main groups of definitions in that file - the definitions of the horizontal (top) menu items and the definitions for the vertical drop-down boxes of the sub-menus.

Internal details of the implementation of our horizontal drop-down menu

For the implementation of our menus we are using HTML unordered lists (the <ul> and <li> tags). Each <ul> tag encloses a complete menu - either the horizontal top menu or one of its submenus. The <li> tags are used to enclose separate menu items. We could have chosen a single tag like <span> or <div> for both the menus and menu items, but this would mean that we wouldn't be able to differentiate between menus and menu items by the tag name of the container. We would have had to attach different CSS class names to the menu and menu item containers and then would have had to use these class names in our CSS rules, which would bring additional class attributes to our HTML code. That is why we decided to use different HTML tags for the menus and menu items. After that we had to choose two tags that would allow unlimited nesting into each other. This requirement excluded DIV and SPAN from the possible options, because the HTML grammar does not allow nesting of a DIV (a block element) inside of a SPAN (an inline element). That is how the UL/LI elements turned out to be the natural choice for our CSS menu - these two elements allow unlimited nesting like this

<ul> ... <li> ... <ul> ... <li> ... </li> ... </ul> ... </li> ... </ul>

Another problem that has to be solved is the method of submenu activation when the mouse pointer is over the corresponding top menu item. We wanted to avoid using JavaScript since our drop-down menu should function even when JavaScript is disabled in the browser. That is why we use the :hover pseudo-class, which is the CSS way of detecting mouse hovering over an HTML element. There is one limitation of the :hover method, though - IE6 supports :hover only for <a> elements, for any other element the :hover pseudo-class doesn't match. On the other hand we couldn't use a:hover in our rules, since then we would have to embed the <ul> submenu into our <a> elements and that is not allowed by the HTML document type definition. So we had to use li:hover instead, since embedding <ul> in <li> is perfectly legal. However this meant that we have to emulate li:hover somehow on Internet Explorer 6. This is where css_menu.js comes into play - it detects when the mouse hovers a menu item and adds/removes the "hover" CSS selector from the <li> element. This allows us to use CSS rules matching mouse hovering in IE6. There is a slight difference from browsers that support :hover natively. For these browsers we can use li:hover while for IE6 we the li.hover selector. This means that each CSS rule which matches li:hover has to be duplicated to match li.hover too. This increases the number of our CSS rules, but cannot be avoided if we are to support IE6.