Advanced Techniques

by Joe Gillespie — Mar 1, 2000

INTRODUCTION

This section covers some more advanced techniques for Web page design. When I say 'advanced' I don't mean bleeding edge technology, I'm just pushing the envelope of existing technologies to give these pages the 'edge' over the plethora of basic, push button solutions built into many editors and image manipulation programs.

Hopefully, the basic ideas and principles here will provide inspiration for you to produce even greater things.

Beyond Rollovers

The ability to change an image when the mouse passes over it is one of the mainstays of Web design.

Some of the newer software image and HTML editors will generate the JavaScript to provide this function at the click of a button, yet there is still a lot that they can't do, not will they show you how to do it yourself.

This section looks at how to produce not just two, but three-state buttons to give 'latching' menus, a JavaScript keypad for data entry, a fun word game and a full-blown arcade game that will keep you amused for ... well, minutes.

Cascading Style

Cascading Style Sheets let you separate the content and design of a Web page and give you a lot more control over the typography and layout. Although they are not difficult to implement, there are many pitfalls for the unwary. Find out some of the do's and don'ts in specifying styles.

Frames Help System

This is a pop-up help system for your Web pages that will provide additional information for your readers in a very simple and elegant way. Using some divergent programming tricks, it lets you load up a frameset with a specific page and anchor in view.

JavaScript Charts

Charts don't have to be static GIF files, here are some ideas for manipulating graphics using JavaScript to produce dynamic and stunning charts and graphs. You feed them the raw data, and they draw themselves.

All the JavaScript is commented and can be downloaded for you to inspect. The style sheets are also external linked files that you can open and learn from.

BEYOND ROLLOVERS

Dynamic Menus

The most fundament aspect of any site is the navigation. The ability to jump about from page to page is the main advantage of hypertext linking over traditional books, but it is also one of its weaknesses. If the reader loses track of the navigational 'model', it can easily become a maze in which they get hopelessly lost.

The metaphor I've used here is of a book with chapters and pages. The reader knows at any time which chapter and page they are at and can jump to other sections still knowing exactly where they are, where they've been, and most importantly, where they are going to next, because the 'scope' of the site is clearly mapped-out from the outset.

Although the book metaphor uses 'chapters' for the main sections, these could equally well be headings like Home Page, About Us, Product Range, Buy, Contacts - or whatever. The format uses a dynamic navigational menu on the left with 'latching' rollovers.

LATCHING ROLLOVERS

So, what's advanced here? Not much on the surface but if you look at the navigational menu, you will see that as well as the regular rollovers, the chapter buttons stay lit when clicked. This is what I call a 'latched' rollover. It works like the buttons on radios and tells you what 'station' you are tuned-in to.

This is a three-state rollover - there are graphics for 'over', 'out' and 'on' states of each button. The 'on' state is triggered by an onClick action.

The source code is fully commented in an external .js file and can be downloaded, have a peek.


out state - out1.gif

over state - over1.gif

on state - on1.gif

Using 'Indexing'

The other thing I've used here, is a single function to handle mouseover and mouseout image swapping instead of the usual two and a form of pre-loading images using 'indexing' which uses less lines of code than individual new Image() statements.

Each set of button images 'over', 'out' and 'on' have a number after them. The image arrays (mOut, mOver, mOn) use the same numbers, as do the image 'name' attributes. This means that the images can be preloaded all in one go using a simple 'for' loop.

On each iteration of the loop, the variable 'i' takes on the values 1 through 5 - more elegant and efficient than 15 individual lines of code.

if(document.images) { for(i=1;i<=5;i++) { mOut[i].src='rollover/out'+i+'.gif'; mOver[i].src='rollover/over'+i+'.gif'; mOn[i].src='rollover/on'+i+'.gif'; } }

The Swap Code

This swapL function combines the two functions usually employed for mouseover and mouseout events. The required action is triggered by the boolean 'state' parameter which is either true or false.

onmouseover="swapL(1,true)"

swaps the placeholder image with the 'over' image

onmouseout="swapL(1,false)"

swaps the placeholder image with the 'out' image, but not if you are still at the current chapter.

Note. Long lines have been wrapped.

function swapL(num,state) { if(document.images) { if(!currentChapter[num]) { if(state) { document.images['pos'+num].src ¬ =mOver[num].src; } else { document.images['pos'+num].src ¬ =mOut[num].src; } } } }

Keeping Track

Now, here's the tricky bit. To keep track of which is the current chapter, we set up an array called 'currentChapter' with one element for each chapter holding true or false.

currentChapter=new MakeArray(6); currentChapter[1]=true;

So, initially it looks like this:-

true, false, false, false, false

There is also a simple variable 'chapterNum' which keeps the number of the current chapter, initially 1.

var chapterNum=1;

This currentChapter array along with the chapterNum variable are used by the next function, mClickL() to process the logic for the 'on' state button.

The OnClick Action

The third 'on' state of the button is accessed like this:-

onclick="mClickL(1)"

This changes the placeholder image to an 'on' state image, but only if it is not the button for the current chapter.

First it marks the 'currentChapter' array as false and restores the existing chapter button to its 'out' state.

It sets the chapterNum variable to the new chapter number and marks the 'currentChapter' array element as true.

Finally, it swaps the placeholder for the 'on' state image.

function mClickL(num) { if(document.images) { currentpage[pageNum]=false; swapL(pageNum,false); pageNum=num; currentpage[num]=true; document.images['pos'+num].src ¬ =mOn[num].src; } }

Feedback Helps

Yes, it takes a little more effort to create three-state buttons. The reward is 'positive visual feedback' that tells the reader which chapter (or it may just be a page) they are at.

With a static navbar or imagemap, the reader is always offered the same set of choices on every page. Going to the page you are already at is not a logical choice.

You could 'grey-out' the button for the current chapter. That shows that it is not an appropriate choice, but doesn't tell you that you are already there!

By highlighting the button, you are doing both jobs.

The 'previous' and 'next' page buttons on the first and last pages grey-out (or blue out in this case) to show that you can't go any further.

This navigational method is a mixture of linear and random access. You can randomly access the chapters, but then there is a linear progression through the pages because they are in a logical sequence. The alternative would be to have the logical sequence on a long, scrolling page.

Next, we will look at some more fun things to do with rollovers.

Javascript Keypad

This little widget lets you enter a four digit number which appears both in the LED display and in the form field. The 'C' button clears the display.

This could be used as the basis for a calculator or for typing-in PIN numbers.

The JavaScript function that intercepts the button clicks are called from within the tag.

The function uses setTimeOut to return the button to it's 'up' state after 200 milliseconds because using onMouseDown and onMouseUp causes problems on the Mac as it uses a time delay to bring up contextual menus.

Download the commented JavaScript code.









More Javascript Fun

Similar in technique to the keypad on the previous page, this is a puzzle called 'Find the King'.

By clicking on the letters, you can spell-out the name of a famous ancient king. You can only click on each letter once.

In addition to conventional rollovers, this script makes extensive use of JavaScript arrays to keep track of the random sequences of numbers and letters required.

Download the commented JavaScript code.

yout
nuta
emkn
pahv

More Rollover Fun

The next example is something I wrote a couple of years ago. This uses the rollover principle in conjunction with a random number generator to produce an infuriating game called 'Rollette's Revenge'.

You have to click on the robots that pop-up randomly out of the holes and you only have 30 seconds to score 15 or more.

The time period is set as 30000 milliseconds with a setTimeOut() after which, a 'score' page is displayed using document.write.

CASCADING STYLE SHEETS

Cascading Style Sheets allow you to separate style and content on your Web pages. Once you have inserted the text into a page in its default form and specified the style in an external style sheet, you can control the style of every page on a site from that central .css file.

Of course, the style specification doesn't have to be an external file, you can do it on a page by page basis, but that loses most the advantages of the technique because if you want to change a style, you have to make the change to each and every page.

Download the style sheets used for this article.

The principle of Cascading Style Sheets gets a lot of bad press because of the inconsistencies in implementation across browsers. If you avoid some of the more esoteric features and stick to the basics, CSS can be very useful in controlling the look of your pages.

For instance, HTML has no provision for leading (line spacing). If nothing else, CSS can give you line space and increase the readability of your page significantly, but we can go a bit further than that!

The ability to serve-up a different set of styles depending on the browser and operating system being used is a major advantage. By querying the browser version with JavaScript, you can provide a set of styles that maximise consistency across browsers and platforms.

One of the main abuses of Cascading Style Sheets is that of trying to force a particular type specification on a reader. Font styles, as you are probably aware, cascade. So if you specify 'Verdana, Geneva, Arial, sans-serif' and the user doesn't have Verdana installed, the browser will step through each font in turn until it finds one that is.

This particular spec is a favourite of mine as it doesn't force Arial on Mac users giving priority to Geneva, which is a font optimised for screen use and much easier to read.

For this article, I have produced separate style sheets for Mac and PC versions of Netscape and Explorer and a browser detect routine determines which one of the four to use. The blue text at the bottom of the screen tells which one is currently in use.

To get similar results on the two platforms, I have specified the basic body type as .85em for Mac and .65em for PC which equates to approximately 10 and 8 points on the respective platforms.

The size conversion factors to get similar sizes on both platforms are:-

Mac platform - set PC sizes to 0.75 of Mac's

PC platform - set Mac sizes to 1.33 of PC's

Font sizes are a trickier subject. HTML uses relative font sizes, bigger than and smaller than 'normal'. What is normal? Normal is whatever the user consider to be correct for their particular situation. Depending on their browser, computer and monitor size, this can be almost anything.

Cascading Style Sheets will allow you to specify font sizes in several different ways. You can specify point sizes, but as we know, this will give different results on Macs and PCs. You can specify absolute pixel sizes, which will give the same result on Mac and PC, but it could make the type impossibly small to read on a large, high resolution monitor or too big on a small low resolution one.

Although you might get acceptable results on your own computer(s), unless you are in complete control of the situation, and on the World Wide Web you usually aren't, it is best to stick to relative font sizes for general access sites.

I now use pixel-based font specs for this site, but only because it is targeted at a 'designer' audience with fairly predictable set-ups.

The following pages show the difference between using relative sizes, points and pixels.

This paragraph has no font face or size specification so it is being displayed at your browser's 'normal' setting.

You can set this size in your browser preferences, most people don't bother and just leave it at the default size. Microsoft Internet Explorer lets you change the font size from the button bar at the top of the browser window, but this feature can be missing depending on how the users have set their preferences.

This paragraph has a main style applied to it which uses the 'em' specification. Using 'em' maintains the user's default font size.

In this instance, the style is declared in a special style sheet prefixed with 's'. It uses div classes instead of tags, one for the body copy and one for the heading.

Mac spec

.bodycopy { font-size: 0.85em; line-height: 1.5em; font-family: Geneva, Arial, sans-serif }

PC spec

.bodycopy { font-size: 0.65em; line-height: 1em; font-family: Arial, sans-serif }

On my Mac, 12 point is normal, and this paragraph specified as 12 point looks the same as normal, but on my PC, it is 33.3% bigger.

font-family: Geneva, Arial, sans-serif font-style: normal; font-size: 12pt; line-height: 18pt;

12 point and 12 px (pixels) gives the same result on a Mac as it has a relationship of one pixel per point. Not so on a PC, there are 96 pixels per (logical) inch on a PC as opposed to the Mac's 72ppi.

font-family: Geneva, Arial, sans-serif font-style: normal; font-size: 12px; line-height: 18px;.

This paragraph is specified as 9 points which is the smallest type you can safely use on a Mac. Below that, there are not enough pixels to completely form the character shapes.

font-family: Geneva, Arial, sans-serif font-style: normal; font-size: 9pt; line-height: 12pt;

This 9 pixel font will often cause problems for PC users or anybody else with a high resolution screen.

font-family: Geneva, Arial, sans-serif font-style: normal; font-size: 9px; line-height: 12px;

Dropping back to 8 point, the type will still be readable on a PC, but not on a Mac.

font-family: Geneva, Arial, sans-serif font-style: normal; font-size: 8pt; line-height: 12pt;

Note. If you can't read some of the text here, don't worry. I'm just making the point that small type will cause problems for both PC and Mac users under certain circumstances.

Because of its relatively large x-height, Verdana looks much bigger on a page than most other fonts.

If you do use a font spec such as:-

Verdana, Arial, Helvetica, sans-serif

be aware that your text flow will change dramatically.

This paragraph is set in Verdana 10 point. Compared to the font in the paragraphs below, it looks bigger and takes up more space on a page.

This paragraph is set in Geneva or Arial 10 point. Compared to the Verdana above, it looks smaller and takes up less space on a page.

This paragraph is set in Times 10 point. Compared to the font in the paragraphs above, it looks smaller and takes up less space on a page.

Headlines

like this can be specified in pixels quite safely. In fact, using a pixel specification will maintain the size relative to graphics, which also use absolute pixel sizes. The headline size in relationship to body text will vary if the body text is specified in relative terms.

font-family: Geneva, Arial, sans-serif font-style: normal; font-size: 36px; line-height: 36px;

Relative type specs

 

xx-small, x-small, small, medium, large, x-large, xx-large

% (used with other specs)

smaller, larger

Absolute type specs

px, mm, cm, in

Typographic type specs

pt, pc, em, ex

WEB SITE HELP SYSTEM

Sometimes, on a Web page, you want to give some subsidiary information such as help or a glossary. You could jump to a link further down the page or to another page but that tends to break the surfer's natural flow of reading.

A better way is to bring up a small 'child' window in front of the main one so that the information can be read, and the window dismissed, leaving the reader at exactly the same place as they departed from.

There is nothing particularly new about this idea, it is used all the time in 'Help' systems on most computers, but the way I have implemented it here has some interesting techniques.

For a start, my Info Window uses frames. As it is a temporary window, it doesn't matter that it can't be searched, indexed or bookmarked.

The frame on the left holds a constant logo, and the 'Close' button. The frame on the right is a scrolling page with the variable information.

Normally a frameset will only load the initial pages specified in the frameset, but we want the facility to not only put alternative pages into the right-hand frame at load time but we should also be able to jump to any anchor position on those pages.

If we use document.write to create the frameset, we can add any URLs we like dynamically.

The JavaScript function to open the child window looks like this:-

function showHelp(f,a) { window.open(f,a, "toolbar=no, width=600, height=250, directories=no, status=no, scrollbars=yes, resize=no, menubar=no, history=no"); }

The clever bit here is to use the window.name property 'a' to pass the URL and name of the anchor where we want to go.

But there is a small problem here, the window.name property doesn't allow characters other than letters, numbers and the underscore, so the dot and # in the URL are substituted with two underscores and three underscores respectively in the link.

Point

showInfo() opens the child window frameset 'info.htm' and passes the URL to it. The function parseName() then reconverts the encoded string back to a legitimate URL replacing the "_ _" with "." and the "_ _ _" with "#".

The frameset is then written to the window using document.write statements so that the URL can be incorporated into the frame.src for the right hand frame.

The variable information pages uses a series of tables stacked one above the other with the anchors at the top of each table and the information roughly centred vertically so that only one definition is presented at a time.

This technique can also be used in conjunction with any site where you want to jump to a specific anchor within a frameset or to put variable information into a child window.

Javascript Charts

By manipulating the height value of an image, it is possible to produce graphs and charts dynamically.

This function takes the Y-axis value (h), scales it to fit a given height, and document.writes it into a table cell in the specified colour (c).

function drawBar(h,c) { h=10+(h*168/700); var graph="" document.write(graph); }

It is called from within the cell like this

drawBar(450,"red");

The individual bars are small GIF files in various colours.

The next page shows a very basic application of the technique that only draws the bars. With a little more work, it would be possible to draw the whole graph including the title, the axis values and to vary the bar widths and spacing

You could also do horizontal bars by varying the width of the GIFs instead of the height. See this in action on the survey stats page.

The graph on the next page uses 'building blocks' instead of stretching the GIF. Each GIF is 13 pixels high and they are stacked one on top of each other to give the Y-axis value.

After subtracting the fixed 26 pixels for the roof and ground blocks, the remaining floors are inserted with a document.write loop to give the correct height.

Each block is shown separated on the right for clarity, on the actual graph they touch.

Download the JavaScript file.

You can use GIF files appropriate to the subject of your graph - coins, people, pages, or whatever.

Del.icio.us Digg Technorati Blinklist Furl reddit Design Float