New: SWFObject examples page

I’ve been creating assorted SWFObject examples for a few months now, usually in response to a forum post at the SWFObject forum. These examples have been piecemeal, just kinda floating out there with no clear links to them or documentation explaining what they are. I decided to create a guide for the examples, which gives a little bit of background for each example as well as the URL for each example.

Displaying code on WordPress entries using CODE and PRE tags

Once again, a journal entry is borne from frustration.

I write these journal entries using WordPress, which is a very easy-to-use blogging solution.

Since I sometimes write about code, I decided to install the Code Markup WordPress plugin. It works very well, and I am enjoying it a great deal (thanks, Bennett).

However, one problem I kept encountering was overflow… when a line of code was so long it would break my layout.

A quick bit of CSS fixes this in most browsers:

pre {
   overflow: auto;

But once again, our friend Internet Explorer 6 said “No! I don’t want to play that way!” Grrr…

It turns out that if your content area has any padding and is also using a fluid sizing method (in my case percentages), the code area will expand beyond the boundaries of your content DIV. Yes, the old box model issue.

Solution? Set a specific width for the pre block element, but only do it for IE… Firefox and other browsers don’t suffer from the box model problem.

The pre block element’s width can be set to a fixed width, but in my case that defeats the purpose of a fluid layout. Then again, if I stick with percentages but set the width to too high of a percentage (“too much” depends on how much padding you’re using), I’d still have issues. Setting a width of 100% will only work if the pre block element has no padding, which would be pretty ugly!

For my purposes, setting pre to 96% width with 1em of padding works out fairly well:

pre {
   margin: 1em 0;  /* left and right margins set to zero */
   padding: 1em;
   background: #FFF;
   border: 1px solid #CCC;
   overflow: auto;

/* for IE 6... using "star" hack */
* html pre {
   width: 95%;

Email address obfuscation

Note: This post contains old code. Read about the updated code at

Everyone knows the story: an innocent email address is posted online and a big bad spambot finds it, relaying it to every spammer on the face of the earth… the email address becomes useless due to the 500 spam emails you get every day!

I always try to encode email addresses on sites I build in an effort to make the addresses more difficult to abuse. This has become a very common practice, thanks largely to free encoder tools such as the Hivelogic Enkoder by Dan Benjamin.

Some encoding methods are easy to beat

However, precisely because of their popularity, some spambots are being written to overcome simpler encoding methods, such as obscuring the address using character entities. A block of text encoded as character entities is easy to defeat with automated decoders, even by an amateur like me. The patterns are still there: the ‘mailto’ protocol, the @ sign, the .com/.org/.whatever, etc… they just look like this:


Javascript shouldn’t be required

More complex encoding methods, such as the aforementioned Hiveware enkoder, still seem to work well, but they also rely on Javascript. While the Javascript adds several layers of complexity for the bot to overcome, it also limits what your visitors can do on your site. What if your visitor has Javascript disabled? Many times, they’ll see nothing… no fake email address, no chunks of encoded text, nada. This is a big no-no if you’re a supporter of graceful degradation/progressive enhancement.

I decided to search around for encoding tricks that would work without Javascript. Guess what? I couldn’t find any, aside form the simple character entity encoding described above. It wasn’t much of a surprise, to be honest.

What about spelling it out at myaddress dot com?

I started looking at the common trick of writing “name at somewhere dot com.” I have a couple of problems with this approach: First of all, the address isn’t clickable. Sounds silly, but it’s a big usability component if you’re trying to encourage people to contact you. Secondly, I think it would be easy to write a bot that finds page content written in that format, especially in places where it’s a common practice, such as bulletin boards and forums. This seems like a temptation for a zealous hacker who wants to prove his or her worth. No thanks.

A simple compromise

After kicking around these thoughts for a while, I decided to implement a compromise between two of the three methods I’ve covered so far: using an altered email address to fake out the bots, and using Javascript to make the bots work a little harder.

Granted, I can tell you in advance this isn’t a foolproof method, but it’s very easy to implement and doesn’t leave Javascript-deprived visitors out in the cold.

Part one: Add some useless text to your address.

Yes, that means we’ll be using the standard email link technique:

<a href="">Email me!</a>

Important! Notice that I didn’t type the email address between the ‘a’ tags… that would make this system pointless! I suggest typing sensible alternate text, such as “Email me!” or the email recipient’s name.

By adding a little bit of unrelated text to the username portion of the address (“REALLYNICE”), we can prevent spambots from knowing what our true email address is:

<a href="">Email me!</a>

So what does this do? It keeps the link clickable, and it prevents the spambot from knowing what our real email address is.

What doesn’t this do? It doesn’t get rid of the useless text (“REALLYNICE”), which means that while the link remains clickable, it’s also useless if the visitor doesn’t manually edit the address.

As the webpage developer, it’s my duty to make the link human-readable, and make the dummy text as obvious as possible. The following example is much easier to read by the average person:

<a href="">Email me!</a>

Part two: use Javascript to make it easier on the end user

At this stage, the email address is somewhat usable, but still requires effort on the end user’s part. If they click the link, it will appear in their email program with the full text “”. Some people will see what they have to do and act accordingly, but others might not realize they need to take action.

Here’s where Javascript comes in as a progressive enhancement: we can use Javascript to remove the dummy text when the link is clicked!

A simple Javascript function examines the link text, finds the specified bit of dummy text, and removes it automatically:

function doMail(theLink, key){

    //Get the HREF tag. This includes the anti-spam 'key'
    var before = theLink.getAttribute('href');

    //If the anti-spam key is not found in the link, exit the function without doing anything
    //If the link is clicked more than once, this prevents the Javascript from throwing an error
    if(before.indexOf(key) == -1) return false;

    //Our new variable "addy" is a combination of the text that
    //comes BEFORE the key [0] and AFTER the key [1]
    var addy = before.split(key)[0] + before.split(key)[1];

    //Substitute the original link with the new link ("addy") 
    theLink.href = addy;


Sample usage:

<a href="" 
   onclick="doMail(this, 'RemoveThisText')">email</a>

Because the dummy text is specified as a key when the function is called, you can use whatever dummy text you like. For instance, at my office all emails are formatted as: You could rewrite the address in the following way:

<a href=""
   onclick="doMail(this, '.dummyText')">email</a>


<a href=""
   onclick="doMail(this, 'noSpam')">email</a>

Of course, I recommend avoiding terms that are easy for spambots to recognize, such as “nospam”. Why not get creative with something like “SpamSucks”?

<a href=""
   onclick="doMail(this, 'SpamSucks')">email</a>

You can even put the dummy text in the domain name, if you choose:

<a href=""
   onclick="doMail(this, 'iDontWantSpamAt')">email</a>

Nothing is invincible!

This email obfuscation method may wind up being easy to crack by the more sophisticated bots, but I feel comfortable knowing that I’ve added a reasonable layer of complexity the spambot must overcome. This in itself will prevent the majority of bots from harvesting my addresses!

I’m also happy because the email address is still human readable (if the dummy text is sensibly written), and is still clickable with or without Javascript. Plus the Javascript is extremely lightweight and the entire method is easier to implement than some of the crazier encoding methods being used today.

@media2007 San Francisco

I just finished the @media2007 conference in San Francisco, and all I can say is “wow.” I was totally in over my head, which in this case is a good thing!

The speakers were all renowned experts in their fields, and I’d be willing to bet 90% of the audience were seasoned web development veterans — no freshmen on this campus! Being an instructional technologist and merely a part-time web developer, I felt like the ugly girl at the school dance sitting against the wall hoping someone would talk to me. Ok, maybe I wasn’t that far out of my element, but it sure was amazing to not only meet the authors of books and blogs I’ve been reading for years, but also to hear them speak about topics they’re truly passionate about. Plus, many of them were very funny guys with excellent stage presence.

At times I enjoyed simply being a wallflower and listening to other people’s conversations. These people, after all, are the movers and shakers of the web world, including W3C members, design gurus and book authors. I mustered up enough nerve to ask a few questions from time to time, but once or twice I felt like a nitwit, as if I just asked a racecar driver if his car goes fast! Oi vay.

For the most part, the speakers were very nice, were approachable, and graciously answered questions, even if it was obvious they’d been asked the same question many times before. Some even handed out free books… I’d like to thank Dan Webb and Jeremy Keith for my books!

Overall, the conference was a success, and the energy/buzz/web-geekiness-run-amok was palpable. I’m very glad I went. Truth be told, I enjoyed it much more than the O’Reilly Web 2.0 conference a few weeks ago.

On a side note, while attending the “Hot Topics” discussion at the end of the event, I volunteered to produce some test suites (mockups) of proposed CSS 3.0 specifications for the W3C’s CSS working group. I must admit I’m pretty nervous about this, but I think it’s a great opportunity to give back to the community and also expand my knowledge and understanding of CSS. *Keep your fingers crossed for me*

I also have this amazing urge to completely redesign my website for fear it won’t live up to the standards of the @media2007 crowd…

Vertical centering — without using tables!

For many years, table-based web page layouts were the rule, not the exception. They were easy to build, they worked cross-browser, and WYSIWYG editors made it a breeze to create and edit tables. CSS-based layouts didn’t really grab hold until just a few years ago, thanks to the evangelism of people like Jeffrey Zeldman and Eric Meyer.

The benefits of CSS-based layouts are very well-documented, and include increased accessibility (for surfers who use assistive technology), ease of site updates (change an entire site’s look and feel with a single stylesheet), and improved search engine rankings (search engines are able to index your content more cleanly when it isn’t surrounded by table markup).

It’s getting easier and easier to avoid table-based layouts these days, and even WYSIWYG editors like Dreamweaver have shifted gears and started including CSS-based layout templates with their software. This is way cool.

But every now and then, a developer like myself will come up against something that was SOOOO easy with table-based layouts and winds up being a royal pain with CSS-based layouts. One of these “d’oh!” moments is when you try to vertically center an element on your web page. Umm… hang on, let me rephrase that: One of these “d’oh!” moments is when you try to vertically center an element on your web page when using Internet Explorer 6.

Firefox supports CSS standards better than Internet Explorer 6 (the dominant browser), and predictably, vertical centering in Firefox is a piece of cake!

This journal entry is devoted to explaining how to get vertical centering working in both Firefox and IE6.

First, an example page.

The ingredients

There are three keys to making this work:

  1. A set of nested DIVs (yes, I know some of you are anti-nested DIV, but hey the world keeps on spinning).
  2. CSS for standards-compliant browsers (Firefox et al)
  3. A separate chunk of CSS for our old friend IE6

Nested DIVs

The first requirement is nested DIVs. You may be thinking “what’s the point of avoiding tables if I still have bloated markup?” My response is that one small set of nested DIVs isn’t nearly as bloated as a table, and using DIVs still helps you keep your markup readable for accessibility purposes and search engines. It’s a good thing! DIVs are also much more flexible should you decide to change your layout later on.

Here’s the layout in all its glory:

<div id="outer">
  <div id="container">
    <div id="inner">
      <img src="" alt="Please wait" width="32" height="32" /><br />
      Well, not really.<br/>
      But don't I look nice centered like this?

The ‘inner’ DIV is what will hold your content. The ‘outer’ and ‘container’ DIVs’ sole purpose in life is to get your content centered on the page! I’ll explain this in a moment.


Let’s look at the CSS:

body {

* {
   margin: 0;
   padding: 0;

/* macs won't see this! */
html, body { 
/* END mac */

#outer {

#container {

#inner {
   text-align: center;
   width: 50%;

We set all elements on the page to have a default padding and margin of 0. This avoids box-model issues. We also dealt with some Mac inconsistencies with the Mac hack.

As you can see from the CSS, the body and outer elements (outer, container) are set to be 100% wide and 100% tall. The outer element is told to behave like a table (display:table), and is vertically centered using the “vertical-align:middle” property.

By nesting the ‘container’ DIV inside the faux-table, we can make the container DIV behave like a table cell: “display:table-cell”. This DIV is also set to be vertically centered using the “vertical-align:middle” property.

That’s it for the vertical centering in CSS-compliant browsers!

In this case, the ‘inner’ DIV’s CSS is purely for horizontal centering. I set the width to 50% simply because I wanted a narrow DIV, and I centered the DIV horizontally using margin-left: auto and margin-right: auto.

Remember, the code up to this point is for standards-compliant browsers, not IE6.

Dealing with our friend, Internet Explorer 6

Now, you may be thinking that writing different CSS specifically for IE harkens back to the bad old days of browser sniffers and alternate web sites, and you would be correct. However, the alternate CSS is very easy to manage, and doesn’t require a browser sniffer! Thanks to Microsoft’s implementation of conditional comments in IE, we can simply insert a chunk of alternate CSS code into a conditional comment… whatever is inside the comment will be safely ignored by any non-IE browser. Here’s an example:

<!--[if IE ]>
   <style type="text/css">
      body {
         color: #ff0000;

You can read more about conditional comments at Peter-Paul Koch’s website.

On our vertical centering example, I used the following CSS code in a conditional comment:

#container {
   height: 1px; /* required for IE to properly center vertically */

#inner {

Internet Explorer doesn’t support the “display: table”, “display: table-cell” and “vertical-align: middle” properties. To get around this, we have told IE to use relative positioning to move the ‘container’ DIV 50% down from the top of its parent DIV (‘outer’), and to move the ‘inner’ DIV negative 50% from the top its parent DIV (‘container’).

Normally these two values would simply offset each other and cause the ‘inner’ DIV’s content to be displayed at the top of the screen. However, through the magical glitches of IE, by setting the ‘container’ DIV’s height attribute, the DIV suddenly jumps down to the middle of the page, right where we want it to be! I have no idea why, but hey, it works. Here’s the proof.

Important: the height must be set BEFORE the top percentage is declared.

Externalizing the CSS

It’s always a good idea to set up your CSS in external CSS files. This helps keep your web page clean, enables you to re-use your code on other pages, and much more. The CSS contained in the conditional code can also be placed in an external stylesheet. Here’s how I set up my page:

<link href="centering.css" rel="stylesheet" type="text/css" />

<!--[if IE ]>
   <link href="centering-IE.css" rel="stylesheet" type="text/css" />

The CSS is exactly the same, but cut and pasted into two external files: centering.css and centering-IE.css.

Now my page is looking clean as a whistle, and I can reuse my code by linking my other pages to my ‘centering’ css files!

Cool, can you do that with a Flash SWF, too?

Yes, you can! Here’s an example.

The code for the Flash example is exactly the same as the first example, except for content: I replaced the contents of the ‘inner’ DIV with some dummy text, and I embedded a Flash SWF using Geoff Stearn’s SWFObject method (the best embedding method I’ve used by far!). No CSS was altered except for the body and font colors.

And there you have it… a nice, (relatively) simple way to vertically center DIVs using CSS and NO tables.


Thanks to some sharp-eyed readers, here are a few corrections and/or additions:

Update: Here is an example of a Flash SWF embedded with a transparent background. The CSS has been altered slightly: an HTML background image has been specified, and the inner DIV has been set to the exact pixel size of the Flash SWF; this properly centers the SWF and causes scrollbars to appear when a minimum width or height has been reached. Tested successfully in IE6, FF2 and Safari 3 (beta), all Windows XP.

Update 9/03/2007: For IE7, if specifying the height of the inner div, you must also specify the height of the container div in the IE-specific CSS file. For example:

In standard CSS:

#inner {
   text-align: center;
   width: 550px;
   height: 400px;

In IE7’s CSS:

#container {
   /* required for IE to properly center vertically,
      must match #inner height */
   height: 400px;

Unfortunately, in IE7 this also produces scrollbars (IE7 thinks the page content is larger than it actually is). I plan to do some more research into this when I have the time.

The Fonthead

My brother recently sent me a link to a webpage with free font downloads. This tickled my on-again off-again love affair with typography, and triggered me to post a quickie blog about the subject. The more intricate details of typography (kerning, leading, metrics and the like) seem as obscure as ever to the everday computer user these days. Most people — quite understandably — only know what MS Word requires them to know. Then there are people like me who know a bit about the subject but still get too lazy to follow all the etiquette, such as using em and en dashes appropriately (see the previous sentence for an example) or using ligatures in printed documents.

What’s the difference between a font and a typeface? No, they aren’t the same thing (at least they didn’t used to be). What about the difference between Times Roman and Times New Roman? And why is using Times Roman (either iteration) NOT a good idea for webpages and other on-screen purposes? (Short answer: it’s a serif font designed for newspapers — specifically the London Times in the mid-1800s — and therefore has a smaller x-height than fonts designed for on-screen use, such as Verdana.)

Anyway, being a geek about this sort of thing, I figured I’d present you with links to some typography sites I’ve been browsing recently. They contain excellent primers on typography, its uses and some typograhical history. Enjoy!

Now if I could only remember how to do that pesky em dash…

I hate to say it…

But I found another Microsoft product helpful today.

It pains me to say it, but it’s true.

I have created an XML template for an online course delivery system I’m building at my workplace. The course data for each course needs to be placed into a copy of this XML template. The problem is that I don’t want to work directly in XML all day, and my coworkers can’t be expected to write course content directly in XML format. I needed to devise an easy-to-use method for inputting data to an XML document (filling in the blanks).

My initial research into the subject found some ‘export-to-XML’ methods that use Excel and/or Word, but they are prone to formatting errors and require extensive workarounds such as oodles of conditional formatting. Didn’t sound very fun. Not to mention the custom XML schema I’d have to write to enable the Excel/Word file to be properly transformed to my custom XML. Other methods involved databases and content management systems, which I wanted to avoid for simplicity’s sake.

Enter: InfoPath. A “how’d I get that?” program that came with our Office 2003 update a few months ago. I had never heard of it until I saw it while randomly browsing my computer’s Program Files shortcuts.

Turns out it’s a program for designing forms that are connected to a data source such as an Access database or… you guessed it… an XML document. And what I truly found surprising is that you don’t need an XML schema, just a sample XML document that follows the format you want your future XML docs to be in. A copycat, so-to-speak. InfoPath will automatically infer the schema from your sample XML! Note: you should probably go in and check the schema details, such as using a “date” data type rather than “integer”.

InfoPath was very easy to use. I created a new blank form, then selected my sample XML file as the data source; InfoPath made the XML tags available as drag-and-drop items, kind of like Flash components. I quickly arranged the items how I wanted them (including using “repeating regions”), and voila!, I had a fully functional form in one afternoon. The data entered into the form is exported to a fresh XML file — based on and validated against my custom XML — whenever I hit “save.”

Of course, that’s a very simplified explanation of how InfoPath works and what it does… I’m still a newbie with the program. However, I can say it greatly simplified the work I needed to do (no crazy workarounds using multiple programs), gave me a form I can share with my coworkers (although you need InfoPath to use the form), and produced valid XML that I can import into other programs as needed, all in one afternoon.

I should note there are other programs that perform similar functions, including Adobe Designer (companion to Acrobat Professional). I will have to investigate the alternatives — I hate being beholden to Microsoft — but so far InfoPath is leading the pack. [link no longer available]

Daily newness: An online XML-to-XSD Converter

OK, most of you probably don’t know the difference between an XML file and an XSD (“XML Schema”) file. For a brief intro check out W3Schools’ XML Schema tutorial. A brief quote: “The purpose of an XML Schema is to define the legal building blocks of an XML document, just like a DTD.”

This week I needed to create an XML Schema doc for work. The XSD file would be used to validate XML files I’ll be making for my online courses. Well, being a newbie to XSD files (though not XML), I was making decent but very slow progress when a thought occurred to me: it should be possible to reverse-engineer an XML file to create an XSD file. And, considering how prevalent XML is these days, someone probably posted an online converter for it! Google to the rescue!

I found a number of tools (mostly software downloads such as XMLSpy), but the easiest one I’ve tried so far is by — gulp — the Evil Empire itself: Microsoft. [link no longer available]

All I can say is whether you love ’em or hate ’em, their tool works great and is completely free. On my first try it pointed out some invalid XML I had written. After correcting my mistake, BAM!, I had a complete XSD file. It wasn’t perfect and needed some tweaking (optional versus required tags, string v. integer, etc.), but it eliminated most of the heavy lifting for me and I’ll be finished a heck of a lot sooner than I would have been without it.

Umm… thanks, Microsoft! (For once…)

Today’s bit o’ knowledge: Firefox Web Developer Extension

today i learned about chris pederick’s ultra-handy Web Developer Extension for Firefox. yeah yeah yeah, i know it’s been around for a while, but i never TRIED it until today. i wish i had tried it sooner!

among its many features is the ability to toggle outlines on and off (looking at other sites’ block-level CSS is fun in a voyeuristic way), as well as the ability to disable a site’s CSS, images, javascript, cookies and more! it makes it really easy to examine the nuts-and-bolts of a web page’s structure/design without doing a save-as and opening in an editor like dreamweaver. me likey mucho.