Making a standards supporting page and menu script
Intro
In this tutorial I would like to take up some issues about making a site and a menu script that actually follows the standards.
Ok, let’s get an overview over the situation: I want to make a simple site in XHTML , I want it to work in ALL browsers and internet devices. But for the browsers that supports it I want to make a neat menu system.
Because we want to (and can) make the content of the site view able no matter what we have to take into consideration a lot of different things; browsers that doesn’t support stylesheets and/or scripting, browsers that have stylesheets and/or scripting disabled or even PDA’s with small screens et cetera. This means that as a opposite to most of the scripts found on this site the menu have to initially work, then we add scripting and styling.
Making the initial page
.
We start by making the actual page, I will keep it very simple. First I’ll make a logo div:
My Personal Site
Then the menu, I’ll make it as an unordered list. That way it will look ok in non-style browsers:
<ul> <li> <a href="#">About me</a> <ul> <li><a href="#">Pictures</a></li> <li><a href="#">CV</a></li> </ul> </li> <li> <a href="#">Portfolio</a> <ul> <li><a href="#">Sites</a></li> <li><a href="#">Design</a></li> <li><a href="#">Other projects</a></li> </ul> </li> <li> <a href="#">Weblog</a> <ul> <li><a href="#">Archive</a></li> </ul> </li> </ul>
Then some content:
<div id="content"> <h3>Welcome to my homepage</h3> <p> Here you can learn everything about me. </p> [dummy text] </div>
And last but not least the very important and always needed copyright notice:
<div id="content"> © Copyright 2002 Thomas Brattli
Styling up the page
Again for simplicity of this article I will keep the layout simple. We’ll place the logo on the top, the menu on the right side (just to be different from all the left side menus :} ), the content on the left and the copyright at the bottom.
View the page.
The stylesheet added looks like this:
<style type="text/css">
body{
font-family: sans-serif;
padding-left:5%;
padding-right:5%;
}
#logo{
font-size:2em;
border-bottom:1px dotted silver;
color:silver;
}
#myMenu{
float:right;
width:25%;
}
#content{
float:left;
width:70%;
font-size:0.8em
}
#copyright{
clear:both;
border-top:1px solid silver;
margin-top:20px;
text-align:right;
padding-right:5px;
font-size:0.5em;
}
</style>
It’s pretty straigh-forward stuff so I will not go more into that. By now you are probably very impressed with my stylistic powers, but there’s still a lot to do. Next we want to style up the menu.
Styling up the menu and adding script
Because this could be used on large menus I don’t want to set any classnames or anything on the individual menu items so instead I make a function that will loop the entire three and set the classnames for me (note that I added an ID “myMenu” to the top UL surrounding the menu so I can reach it):
function loopElements(el,level){
for(var i=0;i<el.childNodes.length;i++){
//We only want LI nodes:
if(el.childNodes[i] && el.childNodes[i]["tagName"]
&& el.childNodes[i].tagName.toLowerCase() == "li"){
//Ok we have the LI node - let's give it a className
el.childNodes[i].className = "myMenu"+level
//Let's look for the A and if it has child elements
childs = el.childNodes[i].childNodes
for(var j=0;j<childs.length;j++){
temp = childs[j]
if(temp && temp["tagName"]){
if(temp.tagName.toLowerCase() == "a"){
//We found the A tag - set class
temp.className = "myMenu"+level
}else if(temp.tagName.toLowerCase() == "ul"){
//Set class
temp.className= "myMenu"+level
//Recursive - calling itself with new element
//to go all the way through the three.
loopElements(temp,level +1)
}
}
}
}
}
}
This cute little function will loop any UL three you give it, and set classNames to all the LI, UL and A tags. It’s recursive so it can be used on as many levels at you want. After running this function, called like this:
var menu = document.getElementById("myMenu") //Get menu div
menu.className="myMenu"+0 //Set class to the top level
loopElements(menu,0) //Call the function
it will set the className "myMenu"+level to all elements. Which means that to style up all the top level li tags I go like this:
li.myMenu0{
margin:0;
padding:0;
list-style : none;
}
And to style up the actual text I go like this:
a.myMenu0{
display:block;
position:relative;
background-color:silver;
padding:3px;
text-decoration:none;
color:Navy;
border:1px solid red;
margin-top:10px;
}
View the page (I really need to start making better looking examples)
But it still doesn’t *do* anything. I’ll add one line to the script which makes all level 1+ ul tags hidden:
}else if(temp.tagName.toLowerCase() == "ul"){
//ADDED LINE:
temp.style.display = "none"
//Set class
temp.className= "myMenu"+level
//Recursive - calling it self with the new found element
//to go all the way through the three.
loopElements(temp,level +1)
}
View the page
Now we’re getting somewhere, only the main items are open by default, now we just have to add some code that will enable us to open them again onclick:
function showHide(){
//We have a A tag - need to go to the LI tag to check for UL tags:
el = this.parentNode
//Loop for UL tags:
for(var i=0;i<el.childNodes.length;i++){
temp = el.childNodes[i]
if(temp && temp["tagName"]
&& temp.tagName.toLowerCase() == "ul"){
//Check status:
if(temp.style.display=="none"){
temp.style.display = ""
}else{
temp.style.display = "none"
}
}
}
return false
}
We add a onclick event to the a tags:
if(temp.tagName.toLowerCase() == "a"){
//We found the A tag - let's style it
temp.className = "myMenu"+level
//ADDED LINE
temp.onclick = showHide;
} et cetera...
Wow, it’s working :) We add some styles, and some small script parts and we end up with this:
More examples
Just for fun I’ll show you how easy it is to change the entire layout of this page with some simple adjustments to the stylesheet. Remember, still same XHTML markup and same menuscript.
Summary
Summary
All examples can be validated at w3c:
Validate xhtml1.1
Validate css
Or viewed with Lynx
All the examples in this article can be viewed on any browser, any screen-size and with or without style/script support. The content will be accessible even though the style and scripting might not be (I know it’s not *perfect*, but it works as an example).
NOTE: In this article I have surfaced a lot of different standards and accessibility concerns. Hopefully this site will soon give you more detailed information about some of the subjects.
May 28th, 2007 at 2:12 pm
great Thomas, I’m glad to see your efforts to contribute to hierarchical menus spreading; will these pages be accessible via pocket pc browsing too ?