Horizontal Suckerfish-like navigation¶
- Horizontal Suckerfish-like navigation
- Arrangements
- CSS definitions
- Fading levels in and out
- Browser compatibility
- Last adjustments
At first: I'm not the author of this tutorial, I just translated it into English. So feel free to correct my mistakes. The author of the German version of this tutorial is Frank Hess.
With the new navigation structure in the latest Version it is possible do realize Suckerfish-like navigations.
This Tutorial shows the creation of such a navigation menu. If somebody wants to create a Suckerfish-like navigation menu from the beginning on his own I suggest to make all blocks visible and to care later about the mouseover effects. In most tutorials the first layer is set invisible rigth from the beginning. This way troubleshooting is much more difficult.
As a good tool for showing the css structure of the blocks in the HTML code I found Firefox with the Firebug extension.
In this example we want to realize the following site structure:
- start page
- page 1
- page 1.1
- page 1.1.1
- page 1.2
- page 1.1
- page 2
- page 3
- page 3.1
Arrangements¶
1. Creating the main navigation module
Layout->Modules->Add module
Name of the module: Suckerfish
Module type: Navigation menu
2. Creating an empty stylesheet
Layout->Style sheets->New style sheet
Name: Suckerfish
3. Creating a page layout
Layout->Page layouts->new layout
Name of the layout: suckerfish
Layout template: fe_page
Style sheets: suckerfish
Columns: one
Included modules: arrange the module suckerfish in column main
4. Creating the site structure
Hence follows for Typolight the following HTML-code:
1 <div class="mod_navigation block">
2
3 <a href="index.php/startseite.html#skipNavigation_4" class="invisible" title="skip navigation"></a>
4
5 <ul class="level_1">
6 <li class="active"><p class="active">welcome page</p></li>
7 <li class="submenu"><a href="index.php/page1.html" title="page1" class="submenu" onclick="this.blur();">page1</a>
8 <ul class="level_2">
9 <li class="submenu"><a href="index.php/page1_1.html" title="page1.1" class="submenu" onclick="this.blur();">page1.1</a>
10 <ul class="level_3">
11 <li><a href="index.php/page1_1_1.html" title="page1.1.1" onclick="this.blur();">page1.1.1</a></li>
12 </ul>
13 </li>
14 <li><a href="index.php/page1_2.html" title="page1.2" onclick="this.blur();">page1.2</a></li>
15 </ul>
16 </li>
17 <li><a href="index.php/page2.html" title="page2" onclick="this.blur();">page2</a></li>
18 <li class="submenu"><a href="index.php/page3.html" title="page3" class="submenu" onclick="this.blur();">page3</a>
19 <ul class="level_2">
20 <li><a href="index.php/page3_1.html" title="page3.1" onclick="this.blur();">page3.1</a></li>
21 </ul>
22 </li>
23 </ul>
24
25 <a id="skipNavigation_4" class="invisible" title="skip navigation"></a>
26
27 </div>
In the browser the navigation is shown without CSS definitions as follows:
CSS definitions¶
Now we can begin with adding the CSS definitions into our stylesheet named suckerfish. In the first step the list will be sorted among each other and the definitions removed. To ensure that the content won't be truncated due to a too small surrounding box, I set the height of the surrounding navigation block to 300 pixel.
If this is also necessary with another Site structure has to be evaluated from case to case.
1 .mod_navigation
2 {
3 height:300px;
4 }
5
6 .mod_navigation p
7 {
8 margin:0px;
9 padding:0px;
10 }
11
12 .mod_navigation ul
13 {
14 margin:0px;
15 padding:0px;
16 list-style-type:none;
17 }
Therewith the gaps around the paragraph (<p>) wich contains the active page are removed and all entries become arranged left-aligned.
For usage in a site structure the CSS .mod_navigation (see last modifications) has to be adjusted later on.
For playing around and testing purposes I just defined a height of 300 px.
In the next step the menu points of the first level will be rearranged from vertical to horizontal.
1 .mod_navigation li
2 {
3 width:160px; /* Define the width of an menu entry */
4 position:relative; /* position */
5 float:left; /* arrange left-aligned */
6 background-color:#999999; /* the background color */
7 border-right:1px solid #ffffff; /* border settings */
8 border-bottom:1px solid #ffffff; /*border settings */
9 border-left:1px solid #ffffff; /* border settings */
10 line-height:35px; /* defines the height of an menu entry */
11 }
12
13 .mod_navigation li ul
14 {
15 left:-1px;
16 top:36px; /* second level begins 1 pixel under the first one */
17 position:absolute; /* position is set absolute to the parent element */
18 display:block; /* set visible for testing and debugging purposes, will later be set to none*/
19
20 }
Now we have to make the menu entries of the third level visible. They should appear to the right of their superior menu entry. At the moment the menu entry 1.2 hides the menu entry 1.1.1.
So we move it 161 pixel (width of a menu entry plus one pixel gap) rightwards and position it absolute to its parent element.
1 .mod_navigation li ul ul
2 {
3 left:161px;
4 top:0px;
5 position:absolute;
6 }
The output should now look this way:
Well that looks charming doesn't it? Now we can bother with the fading in and fading out of the levels.
Fading levels in and out¶
For the fading in and fading out of the levels the CSS pseudo class :hover is used. The methods described in this chapter work only for Firefox. So we have to do a workaround for IE wich is described in the following chapter.
At first we hide everything exept the first level. Therefore we modify the CSS definition .mod_navigation li ul as follows:
1 .mod_navigation li ul
2 {
3 bottom:0px;
4 left:-1px;
5 right:0px;
6 top:36px;
7 position:absolute;
8 display:none; /* hide the submenus */
9 }
Afterwards we add some new CSS definitions:
Shows the subnavigation if the mousepointer is above one of the main navigation points.
1 .mod_navigation li:hover ul
2 {
3 display:block;
4 }
Hides the subnavigation of the third level if the mousepointer is above one of the main navigation points.
1 .mod_navigation ul li:hover ul ul
2 {
3 display:none;
4 }
Shows the subnavigation of the third level if the mousepointer is above one of the subnavigations of the second level.
1 .mod_navigation ul ul li:hover ul
2 {
3 display:block;
4 }
Browser compatibility¶
As mentioned in the last chapter, nothing happens if the mousepointer moves over a menu entry. The reason is that the IE allows only links (<a>) to use the pseudo class :hover.
But it is possible to add mouse effects to any element by using the Document Object Model (DOM). But unfortunately this requires Javascript. So if you attach importance to the fact that your navigation is usable without Javascript the IE disappoints you.
For the IE we add the following script:
1 sfHover = function() {
2 var sfEls = document.getElementById("main").getElementsByTagName("li");
3 for (var i=0; i<sfEls.length; i++) {
4 sfEls[i].onmouseover=function() {
5 this.className+=" sfhover";
6 }
7 sfEls[i].onmouseout=function() {
8 this.className=this.className.replace(new RegExp(" sfhover\\b"), "");
9 }
10 }
11 }
12 if (window.attachEvent) window.attachEvent("onload", sfHover);
I realized the integration of this script this way: First I saved the file sfHover.js in the plugins directory. Afterwards I added this line in my page laysout into the Additional <head> tags field:
1 <script type="text/javascript" src="plugins/sfHover.js"></script>
This script has to be modified according to the layout area where the navigation is going to be used.
In this case I added the navigation for testing purposes into the main area. This is the reason for the following line in the script:
1 var sfEls = document.getElementById("*main*").getElementsByTagName("li");
If you want to use the navigation iside the header area the line has to be modified in the following way:
1 var sfEls = document.getElementById("*header*").getElementsByTagName("li");
Basically the identifier (ID) has to be specified wich surrounds the navigation. The script runs through all elements beneath the identifier main and changes the classnames inside the DOM by appending the addidional classname sfhover.
Therefore the following definitions have to be edited into the CSS code to add this classname.
1 .mod_navigation ul li:hover ul,
2 .mod_navigation ul li.sfhover ul
3 {
4 display:block;
5 }
6
7 .mod_navigation ul li:hover ul ul,
8 .mod_navigation ul li.sfhover ul ul
9 {
10 display:none;
11 }
12
13 .mod_navigation ul ul li:hover ul,
14 .mod_navigation ul ul li.sfhover ul
15 {
16 display:block;
17 }
Last adjustments¶
To make the menu usable inside a site structure we change the output of the class mod_navgation as follows:
1 .mod_navigation
2 {
3 position:absolute;
4 overflow:visible;
5 z-index:999;
6 }
With this code the menu overlaps the other content items if opened and is positioned absolute to the surrounding conteiner.
Now we want to remove the underscores unter the links and move the text inside the navigation block a bit rightwards.
1 .mod_navigation a
2 {
3 padding-left:5px;
4 color:#ffffff;
5 text-decoration: none;
6 }
You want the background color to change if the mousepointer is over an entry? No problem, just add the following CSS definition:
1 .mod_navigation li:hover,
2 .mod_navigation li.sfhover
3 {
4 background-color:#666666;
5 }
Now the background color changed to a darker grey if the mousepointer is above an entry.
Now our navigation menu looks this way:
There are surely a bunch of possibilties to improve the menu (for example active menu entries shown in another color) or optical advancements. But thats now up to your creativity. You can play with the parameters if you want. It is also possible to create an vertical menu with some changes in the style sheet definitions.
Useful links wich helped me to create this article:
tested with: Opera 9.21, IE 6.0, Firefox 2.0.0.3
--- lindworm (lindworm@gmail.com) 2007-09-28 18:08