Exploration

Thanks to the help of several contributors, the simple standards-based slide show system I put into public beta status, and which I may well end up calling S5, is almost ready to go final. At its core, it seems to work consistently in Internet Explorer (both platforms), Firefox 0.9, and Safari 1.2. I’ve also scripted things so that the system works in Opera 6 and up, basically allowing those browsers to fall back to using Opera Show. This allows the slide show’s behavior to be consistent with what Opera Show users already expect, which seems like a good thing.

There are two things that don’t work as I’d hoped. The first is the “click anywhere to advance a slide” feature, which is broken in IE/Win. It throws a JavaScript error about the target that doesn’t make sense to me. The second is the show/hide of the menu in IE/Mac, which I just cannot get to work. If anyone can figure out how to make those work, let us know in the comments; otherwise I’ll just prevent IE from running that code in the final version, which will of course mean a reduced feature set in those browsers. I’m not going to lose a lot of sleep if that happens, but I’d rather have the system be feature-consistent across browsers if possible.

(Update: if you downloaded the archive between 1421 EDT and 1504EDT, grab it again. I initially forgot to update it with the new files. Sorry! It’s fixed now.)

i have reworked a bit your code, so that it does work in the same way in opera, firefox and ie. ( page up and down for next and back, up and down arrow to open the quick-jumper window, left to jump, right to close). perhaps you can use something from it.

Arjan: thanks for the code, but having it break other browsers isn’t acceptable. Unfortunately, I’m not skilled with JavaScript, so overcoming the breakage in non-IE browsers is not easy for me; I tried and wasn’t successful. But at least this proves it can be done in IE/Win!

Henryk Pl wrote in to say...

Moin,

Uh, you’re right, Eric. There are more differences that I forgot about. The first, as Arjan mentioned, is that ‘target’ is called ‘srcElement’ in IE-speak. The second is that there is no ‘which’ in the event object. (Well, there is a ‘button’ but that only applies to mouse{down,up,move} events.)

Henryk Pl wrote in to say...

Moin,

A fix for problem 2 of comment 8: Insert the following two lines in keys() between the line “case 32:” and the line “case 39:” (Yes, that’s bad coding style):if(window.event && isParentOrSelf(window.event.srcElement, "controls")) return;
if(key.target && isParentOrSelf(key.target, "controls")) return;

That will disable the return, enter and spacebar keys for elements in the control area.

K Scott wrote in to say...

Bug report that I haven’t seen any one else mention so far: when the style is toggled off, clicking anywhere still executes the advance slide code, resulting in strange behaviour.

The toggle() call should disable that (by setting a flag or something that can be checked?).

If the user tells the browser to disable styles some other way, the problem will still remain, though, and I don’t know of any way in javascript to test for what stylesheet the browser is using. I could be wrong, though; might that be in the DOM?

In addition to K Scott’s comment, when style is toggled off, scrolling with the arrow keys exhibits the same strange behaviour that the different sections are hidden one after the other until only one if left.

Jos wrote in to say...

In the fragment of code

var newopt = document.createElement(‘option’);
var opttext = document.createTextNode(n+’ : ‘+otext);
// newopt.setAttribute(‘value’,n);
// list.appendChild(newopt).appendChild(opttext);
list.options[list.length] = new Option(n+’ : ‘+otext,n,false,false);
you are not using the opttext and the newopt vars. I think you should comment the first two lines

Opera has created technical documentation that describes a standard fileformat used for slideshows. It might be worth checking out. It would rock if one common format is used (when it comes to writing applications that manages these slideshows anyway).

Bruce: I agree. I don’t have Keynote, but as I understand it the files are just XML. If you’d like to send me an example slide show or two, I could take a peek at the file format.

Nico: yes, the gray rectangle happens for me too, and it looks like bug 206000 is responsible. There’s really not much I can do about it, and even if there were, I probably wouldn’t bother. That’s a painting bug that needs to be fixed in Firefox.

Andreas: It looks as though the formats are basically the same, when it comes to the slide markup, although the IDs I generate are shorter than those called for in OSF. That’s easily fixable, as is adding the div class="presentation" to surround the slides. What wouldn’t be the same is the OSF meta tags, which I’m not about to add to my files but which wouldn’t interfere with moving slides from OSF to this system, or vice versa. The other difference is that OSF apparently requires XHTML, whereas this system does not; either HTML or XHTML works as well. Also, the layout stuff is quite different; I’m not sure how easy it would be to harmonize the two. I’ll think it over.

But as I say, with a couple of tweaks it would be dirt-simple to move the actual slides from one format to the other. I think being in harmony there is probably a good idea.

Paul: That’s exactly what you should see. If you then invoke Opera Show (F11), you’ll see the slide show. The navigation menu will not work, and the navigation keys will be those built into Opera Show (page up and page down, maybe others).

First off, I would like to congratulate you on your work, especially on making it nicely compatible with Opera Show.

There have been several attempts at making HTML/CSS/JS-based presentation tools (such as MozPoint) but none have been designed with the same cross-browser compatibility in mind as you have done. So I sincerely hope that your effort will be generally adopted if people want to use another browser than Opera for presentations.

Secondly, I would like to comment a bit on the abovementioned Opera Show Format, as I wrote the new Generator and the documentation last summer.

The OSF meta-tags are primarily there to make it easier for editors such as QuickShow to distinguish between different fileformats and to convert one into the other. I would therefore like to suggest that you consider adding a metatag of your own, so that future editors can also import your format.

As you pointed out, OSF requires XHTML (the same doctype as you seem to be using) but I would like to add that the presentations will also work fine when using an HTML doctype. So why did I decide to use XHTML? The well-formedness will make it easier for editors to parse the information. Furthermore, some JavaScripts require a clearly defined DOM to work properly, which is not always the case when using HTML tagsoup.

The layout section in the code is also there, with scalability in mind. This way editors can easily distinguish content from layout and when certain naming conventions are used (e.g. topleft, topright, etc.) then editors can provide a UI for editing the headers/footers.

Another major difference between your format and OSF is that the latter requires an id for each slide. That makes it easier to link to different slides from an external source, e.g. a teacher giving a link to slide 25 from the last lecture.

If anyone has suggestions or improvements for the Opera Show Format, they are always welcome.

Last thing I would like to add: the idea of using a select box for navigating between slides is great! For the Opera Show Generator I wrote a script which generates a kind of navigation menu, with an ordered list of the slides, but I hadn’t though of using a select box. Nice one!

I really like the XHTML requirement. It means that I can easily parse the slideshows for use in other contexts. Tonight I threw a quick script together that collects metadata from all OperaShow Presentations and displays them on a webpage. My OperaShow Manager (screenshot is just a small example of what can be done quickly.

I’m a practical guy so I’d prefer formats to be as easy to convert as possible. It makes my life easier. :)

I am currently working on a new version of QuickShow which among other things has the ability to open/save in OperaShow Format (I collaborated a little with Mark on the OSF spec).

As a test I opened your test presentation with my latest build and it parses perfectly, nice. I think it wouldn’t be too much work for me to add the cross-browser support to the output.

While QS doesn’t mind too much about Doctypes when it opens a file it edits and saves as XHTML so it would be very nice indeed if we were all using the same flavour of HTML (XHTML), and generally swimming in one direction.

Hendryk is kind of on the right track with the IE event think (and this is based on just scimming over the comment shere and not looking at the real code): window.event is true for all versions of IE, but when using el.attachEvent the event is passed as argument (not sure whether that is IE6 only or if it works for earlier versions, too). The event.target error is due to the fact that IE’s event object names it event.srcElement, so to get the target in a x-browser way this code snippet is the best to use: var target = event.srcElement || event.target;.

Not sure if this is relevant at all (just saw some new Option(...) stuff in the comment), but here’s a link to a Select Manipulation test page :)

I’m not sure if that’s all to say but it is all I found during the skimming :)

Henryk Pl wrote in to say...

Moin,

Bjoern: Yes, attachEvent is a different method of getting event handlers called in IE (one that I didn’t know about before). However, according to the examples in Microsoft’s documentation on attachEvent there will be no parameter to the function that is being used as event handler.

Of course the preferred way of handling events would be using DOM Level 2 Events, but unfortunately these are not supported by any version of IE. Given that current Geckos as well as current IEs still support the old way of using object.onfoo = handlerfunction (albeit with slightly different semantics in the handler, as I explained in the comments above) I don’t think it is beneficial to switch over to using DOM Events (for Geckos and similarly advanced browsers) and attachEvent (for IEs since 5). Maybe, in three years or so, when the IE folks got DOM Events into their browser …

Michael Guitton wrote in to say...

Obviously the reason why the list doesn’t show up in IE5/Mac is because there is an error in the following statement:

list.options[list.length] = new Option(n+’ : ‘+otext,n,false,false);

which should read:

list.options[list.options.length] = new Option(n+’ : ‘+otext, n);

#20 is right in pointing out there are remnants of useless code.

Also I’d like to share a debugging tip for IE5/Mac. You must embed the whole script in the HTML and turn on ‘display script errors’ checkbox in the prefs. It’s the only way to track down potential problems in your source code with this browser.

Likewise, I can’t get the menu to show up with keyboard shortcuts. Unfortunately I’m quite busy at work so I can’t tell when I can take time to fix this. Perhaps later this week if I’m lucky.

Last point, I noticed that there isn’t much defensive coding. When the (X)HTML code does not contain the required elts or when there is a typo in an ID, you end up most of the with a script error. For example, you should wrote:

Michael Guitton wrote in to say...

Henryk Pl wrote in to say...

Moin,

Michael: Yeah, you’re right with regards to defensive coding. This certainly is not ready for prime time yet, but serves to be a pretty good proof of concept.

I took the last hour to simplify (well, kind of …) slideJump() and fix its bugs: the rest of the script didn’t know about jumps done by this function, which made strange things happen when you advanced slides; also the slide number wasn’t displayed at the bottom. Instead I now simply call go() from there which will take care of everything necessary. Then I added new functionality: You can now use regular anchors (<a name="..."> or even <a id="...">) in the slides which will work with ordinary browsers and have slideJump() go to the right slide. This only works onLoad() though, I’m not sure we can capture jumps between slides in JavaScript. E.g. clicking <a href=”#somewhereelse”> won’t work in presentation mode.

This way you can have more permanent (when moving slides around) links to certain parts of the text that even work in old style browsers or with javascript disabled. I think this is something Mark wanted. I tested the new code in Gecko and IE 6 (should work with IE 5 too, not sure about Mac). For obvious reasons you can’t have anchors named s123 (with arbitrary values of 123). If you don’t like the new functionality you can remove everything from the first “else {” to the corresponding “}”. Then you will also see why I said that I simplified the code ;-)

Michael Guitton wrote in to say...

Henrik, good work on slideJump(). I had found in the meantime that there was some duplicated functionality between go() and this function. Thanks for doing all the dirty work. Too bad because I had something similar in my JS code library. ;)

BTW, I noticed that GetElementsWithClassName would fail for elements having more than one class name specified.

Henryk Pl wrote in to say...

Moin,

Thanks, Michael. With regards to the onload handler: I agree that setting it in the HTML body tag is not particularly elegant. The usual solution is to remove the onload="startup();" from the body tag and instead append window.onload = startup; at the bottom of slides.js. This way the user never comes into contact with even a single line of JavaScript (except from the <script src=...>, of course). For that reason I would deem adding a script section to the presentation HTML even more ugly.

Your idea about the className is very good. There are however some errors in your code, so here is a replacement line that actually works:if (allElements[i].className.search('(^|\s)'+className+'(\s|$)') != -1) {

In response to Henryk in #34: There are lots of benefits, the most obvious one is that addEventListener/attachEvent do not override previously assigned event handlers (see AttachEvent.js for a nice wrapper around all possible attach event methods). And do people really care about v4 browsers nowadays? Within the scope of this site I highly doubt anyone does ;)

The fact that the sample on MSDN’s documentation for attachEvent does not demonstrate the event passed as argument does not mean it is not, it is.

I guess it’s the right time to take a look at the actual code myself :)

Update: the test file has been updated, along with all the CSS and JS; the archive is also up to date as of this post. These changes bring the format more in line with OSF (though not completely) and includes nearly all the JS changes suggested. I’m discussing improvements to OSF compatibility with Mark, and we’ll see how that turns out. As Phil pointed out, the two formats are very close together, and I’m hoping we can make them still closer. The idea of having them interoperable really appeals to me.

Thanks especially to Michael G. for pointing the way to having GetElementsWithClassName() handle multiclass values properly, something I’ve meant to do for a while now but wasn’t sure how to go about doing; and to Henryk, for all the excellent contributions.

I like the slideshow and would like to adapt it for presenting fiction on the web. Is there any way to re-work it so that the link box does not show up? Just wondering…the linkbox is not really needed for what I have in mind.

Heads– it depends. If you set the whole control area to display: none then it should suppress the display of any descendant elements. Alternatively, you could use CSS positioning to throw the link box off-screen, thus rendering it inaccessible to the user. Well, to the vast majority of users, anyway.

Henryk Pl wrote in to say...

Moin,

Uhm, your renaming the slide ids to ‘slide0′ etc. broke part of my slideJump() modifications. Also initially I didn’t think of multiple classes, so that will have to be fixed, too. I suggest adding a convenience function isClass() to wrap around that rather lengthy regex.

Michael Guitton wrote in to say...

In response to Bjoern in #41. “Do people really care about v4 browsers nowadays?” As pointed out in the source code of AttachEvent.js, IE5/Mac — which is not a v4 browser — doesn’t support attachEvent nor addEventListener. Using old-style event handlers can work equally well assuming you take additional steps to preserve any event handler that has been assigned previously.

Henryk Pl wrote in to say...

Moin,

Yikes! I just noticed that you write <div onmouseover="javascript:showHide('s');" ... in the HTML document. This is evil. Never ever shall you use “javascript:” in any onfoo event handler! The only reason this seems to work is that by pure coincidence foo: bar is a labeled statement in ECMAScript.

Another point I don’t like is that the empty <select> prevents proper HTML validation. Actually I wanted to remove the form from the HTML anyways and dynamically insert it in JavaScript later so that non-Javascript-capable clients won’t see it at all. The only thing that needs to be left is a stub <div id="controls"></div>.

and a call to it as the first line of startup():if(!isOp) createControls();

This way Opera doesn’t see the controls as they won’t work, but that also needs a modification of slideLabel(). Insert if(isOp) continue; after the line obj.setAttribute('id',did); to make it skip the rest of the loop. (Alternatively don’t call slideLabel() for Opera at all.)

There is only one thing left that I’d love to have: Have the text resize automatically according to the window size. Otherwise text in presentations created at 1024×768 will look kind of lost at 1600×1200 or similar. In fact even the example presentation looks strange at my 1400×1050.

This is something I need help with, as I’m not too proficient with the CSS. I’d suggest adjusting the font-size of <body> element according to the ratio of the window size the presentation was designed with and the current window size. After that all lenghts and positioning of elements inside the body would need to use relative units. I have the script code ready and working, but it doesn’t play too well with the current style sheet.

(The * 2 in the last line stems from the fact that the stylesheet has font-size: 2em defined for body. Adjust as necessary.)

Call it with window.onresize = resizer; resizer(); directly below the line document.onclick = clicker; in startup(), and of course insert a definition of the baseWidth/Height in the surrounding HTML file:<script type="text/javascript">var baseWidth=1024, baseHeight=768</script>
before the <script src=....

Tested with Gecko and IE6, but doesn’t work too well in Gecko and has some slight problems in IE.

Henryk: having the design scale to different resolutions is quite tricky. There are currently two approaches already being used:

1) use JavaScript to query the width of the screen and set a base value for the <html> or <body> tags and then use relative fontsizes for the rest of your styles. This is what QuickShow does.

2) use CSS3 Media Queries which is currently only supported in Opera 7.x (and that is only experimental).

I decided to use Media Queries for the Opera Show Generator, as documented here. I could use it because the queries are only used in combination with the @media projection and Opera is the only one to support that.

For cross-browser compatibility, JavaScript seems to be the way to go but that means that all values in the stylesheet should be relative ones (including padding/margins). That is quite well possible, but needs some work to scale nicely.

Michael Guitton wrote in to say...

In response to Bjoern in #41. “Do people really care about v4 browsers nowadays?” As shown in the code sample you pointed out, IE5/Mac does not support attachEvent nor addEventListener. Using old-style handlers is not such a bad practice presuming you take the necessary steps to preserve the previously assigned event handler.

Michael Guitton wrote in to say...

Nobody seemed to notice my warning in #35 regarding new Option(..) not working in IE5/Mac.

Code in slideLabel() should read:

list.options[list.options.length] = new Option(n+' : '+otext, n);

Also — in the event we end up assigning location.hash with current slide number — it might be mandatory to add the following statement in slideLabel() that prevents some mess in the pop-up items when someone hits the back button in IE:

BTW, a nice add-on would be to assign the slide number to the selectedIndex of select element to keep the pop-up in sync with the current slide.

One last thing. When CSS is disabled in IE5/Mac, the pop-up onmouseover and onmouseout handlers work as expected. Therefore I guess this an issue with the CSS positioning rules. Could anyone confirm this?

Okay, I sense this is beginning to run away from itself. I’ve dropped a few of the suggested fixes into place– sorry I didn’t act on comment #35, Michael, it was an oversight– but some of the more esoteric stuff I’m going to have to postpone until later. The one thing I’d like to do is add the suggested selectedIndex massaging, but I tried two different ways I thought would work and neither did. If I could get some example code, that would be great.

The font resizing is something I already tried, and discovered that in Gecko browsers things fell apart pretty badly. This appears to be because the element boxes do not change once calculated, so the when the font size changes everything goes to hell. So for v1.0, the font size will be set in the CSS. If a presenter needs to change it, he can do so by editing the body‘s font size value. This will not account for slides posted to the Web and viewed under varying conditions, but that is not a project goal. The idea here is to provide a lightweight presentation solution along the lines of Opera Show, but in a cross-browser fashion.

Things like font scaling may be added later. But not now.

Similarly, I got lost enough trying to follow the internal-links code that I’m probably going to push it off to a later version. It’s nothing against you, Henryk; your contributions have been great and have deeply influenced the JS as it now stands! I hope to revisit what you did for v1.1. Since (as I understand it) the internal-links code won’t affect the markup structures, I’m willing to delay that feature introduction.

At this stage, I’m focused on, pretty much in this order:

Beating down any bugs in the current functionality (as opposed to browser bugs that draw gray rectangles, introduce slight scrollbars, and so on).

Henryk Pl wrote in to say...

As you probably already noticed that your selectedIndex approach doesn’t work this way. Instead the line has to read:document.getElementById('jumplist').selectedIndex = snum;

Additionally there’s a minor bug in isParentOrSelf: the contents of nodeName are always uppercase. So it can never match 'body', but only 'BODY'.

With regards to link following: TMTOWTDI. I’ve got a less cryptic solution here (hey, it even got comments! ;). There was also a very minor bug in clicker(): Clicking something inside a link (e.g. the image in <a><img></a>) would not be detected by target.href != null. This is fixed in my modified code.

(Obviously the function needs my findSlide() function. Attention: findSlide() contains an occurence of nodeName, too, and I initially made the same mistake of writing 'body'.)

Yet another thing: pretty.css is not valid CSS. There’s a typo (padding; 0;) and a missing unit (line-height: 1;). (On a related note: Sorry about messing the markup of this page up in my comments above.)

Just curious — how much do you think this work overlaps SlideML? I ask because I was hunting for somethign like this a few weeks back and found SlideML. It seems very similar: you author in a single file in a small SlideML syntax + XHTML, run thru an XSLT stylesheet to emit multiple XHTML files. It has some problems that still need cleaning up — the JavaScript to navigate slides is hinky (and this thread illustrates the difficulty!), but seems like there’s a lot of overlap here. Not having used SlideShow, can anyone do a quick comparison and discuss the pros & cons?

Mikael Jervelind wrote in to say...

A suggestion!
It would be nice if it was possible to navigate to a slide by means of pressing a number (one or more number keys) and then Enter. This is a feature in for example PowerPoint which is sometimes useful.
I think it is just as simple as to store the numbers in a variable and check if there are something stored when the Enter key is pressed.
The store should be cleared for any key but numbers.

Not what you are asking for, some kind of off-topic: i was curious, if that could be done without div’s with class=’slide’, just a ‘ instruction ‘ for certain elements ( var slides=[‘h1′,’h2′]; ) to make a ‘ cut ‘ in the normal document flow.

You can check out a sketch for such a solution here, if you like. ( the key handlers are a bit different )

Val: I would say that this system, like OSF, is something that SlideML could use as a target format. In other words, someone could create a SlideML document and then run a transform to turn it into OSF or this format. There is certainly overlap in terms of intended use, but that doesn’t strike me as being a problem.

Mikael: That would be nice, but won’t be part of the initial release. I’ll have to look at doing that in a later version.

Christian: My original Opera Show files did exactly that, only without the JavaScript. I’ve instituted the class="slide" constructs because it’s more compatible with OSF 1.0. Okay, to be totally honest, originally I instituted them because it was easier to process the DOM structure that way, but at this point they’re staying in due to OSF 1.0 compatibility.

It does not break the OSF 1.0, actually the idea was to make it more similar to it (in the projection css: body>h1, body>h2 {page-break-before: always;} and in the js: var slides=[’h1′,’h2′]; ). You can test it ( still here ), with js disabled it does work as normal OSF in projection mode ( little problem with the test image, which is a little bit to high, and the whole thing is still just a sketch ) and with js enabled it does work on the same way as in the Fox and in ie.

( i think i could be possible to ‘ parse ‘ the projection css for the Fox and for ie, so that it would work with such a js module with no more additional adaptions, but perhaps a little bit to much ‘ music ‘ )

But it’s more for personal interests, your current solution is sure ok.

The content of a slide must be enclosed by a div with a class=”slide” attribute and a unique id=”slide[counter]” where the [counter] is replaced by the slide number. The id is required to be able to link to specific slides in a presentation.

From Opera Show Format 1.0 documentation. In the format I’ve created, the slide IDs are dynamically assigned instead of placed in the XHTML, but they use exactly the same format (slidenn).

So taking out those divs would, in fact, make the format more incompatible with OSF 1.0.

Michael Guitton wrote in to say...

Apologies for duplicate comment entries in #47, #50 and #51. When I posted #47 using Camino, this browser freezed (!) and when I visited this page subsequently using Safari and IE, my comment was nowhere to be seen… making me think the previous POST request did not succeed.

Thanks for the tip. I did play around with assigning display: none to the div control tag but found the arrows and toggle switch disappeared too–I’d like those to display. I’ll fool around with it some more but if you have an idea of how to get just the linkbox to not display I’d appreciate it.

I’m trying to work out how best to deal with image inclusion via CSS. I’ve wrapped each image in a div with an “image” class. Any suggestions on how to best modify my definition to properly handle sizing? I’m tranforming via XSLT, so don’t want to hard code sizing information in the img elements. I just want to constrain the div to a certain proportion of the “slide.”

Jon Malachowski wrote in to say...

Thank you so much for this. I am an Engineer at George Mason and I think this is a great solution to basic presentations. I made one for class and the professor was impressed. I left s^5 on the footer for you! If anyone would like to see: http://mason.gmu.edu/~jmalacho/prsp.html

1. I added a cookie to retain the current slide. I found this useful in cases where you leave the presentation to visit another site or link in a slide that does not open a new window. Hitting your browser back button would take you back to the start of the preso – the cookie solves that problem. The cookie is set to expire within 1 dayso you can take a lunch break and pick up where you left off :-)

Eric Everman wrote in to say...

I’ve noticed that in the current version (as of March 2005), clicking a slide in Firefox will cause the ‘blinking cursor’ to remain on the screen. With large font sizes, this is a REALLY BIG blinking cursor which means the clicking is not a usable way to go to the next slide.

Jeroen van der Vegt wrote in to say...

Hi, this seems to have evolved to something quite usable, but development seems halted. Before I make any contributions, I’d rather know if Eric still feels like updating the program (I would like adding functional (b)lack/(w)hite keys, and #56).

I also found that variable ‘n’ or ‘i’ is often not declared properly, and the function names could use an update (function names starting with a capital, a function called ‘showHide’….)

Matthias Ebert wrote in to say...

1) ALLOW DIRECT LINKS FROM OUTSIDE
———————————-
To allow a direct link from outside to a specific slide,
I recommend to use the usual parameters behind the URL-name,
i.e. s5-demo.html?3
This example presents slide3 in the browser.

HOWTO:
You can simply add the following javascript function to slide.js:

This function has to be called in:
– the startup(),to be used by slide0
– the last row of go(), to be used by all other slides
function startup()
{
...
if (loop) setTimeout('nextSlide()', loop_timeout);
goTo(getParameter());
}

As S5 was released quite a long time ago, I am thinking if there is an updated version available with adoption of HTML5 and jQuery. If not, I may try to follow the S5v2Beta or Slippy and develop on top of that.

Remember to encode character entities if you're posting markup examples! Management reserves the right to edit or remove any comment—especially those that are abusive, irrelevant to the topic at hand, or made by anonymous posters—although honestly, most edits are a matter of fixing mangled markup. Thus the note about encoding your entities. If you're satisfied with what you've written, then go ahead...