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 http://itgotmethinking.com/2009/02/01/obfuscating-email-addresses-revisited/

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:


yourname
@somedom
ain.com

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="mailto:someone@somewhere.com">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="mailto:someoneREALLYNICE@somewhere.com">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="mailto:someoneRemoveThisText@somewhere.com">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 “someoneRemoveThisText@somewhere.com”. 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="mailto:someoneRemoveThisText@somewhere.com" 
   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: givenname.familyname@ouroffice.org. You could rewrite the address in the following way:


<a href="mailto:givenname.familyname.dummyText@ouroffice.org"
   onclick="doMail(this, '.dummyText')">email</a>

or


<a href="mailto:givennamenoSpam.familyname@ouroffice.org"
   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="mailto:givennameSpamSucks.familyname@ouroffice.org"
   onclick="doMail(this, 'SpamSucks')">email</a>

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


<a href="mailto:givenname.familyname@iDontWantSpamAtouroffice.org"
   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.

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:


<body>
<div id="outer">
  <div id="container">
    <div id="inner">
      <img src="http://pipwerks.com/images/posts/indicator_green.gif" alt="Please wait" width="32" height="32" /><br />
      Loading...<br/>
      Well, not really.<br/>
      But don't I look nice centered like this?
    </div>
  </div>
</div>
</body>

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.

The CSS

Let’s look at the CSS:


body {
}

* {
   margin: 0;
   padding: 0;
}

/* macs won't see this! */
html, body { 
   height:100%;
   width:100%;
}
/* END mac */

#outer {
   height:100%;
   width:100%;
   display:table;
   vertical-align:middle;
}

#container {
   display:table-cell;
   vertical-align:middle;
}

#inner {
   text-align: center;
   width: 50%;
   margin-left:auto;
   margin-right:auto;
}

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;
      }
   </style>
<![endif]-->

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 */
   position:relative;
   top:50%
}

#inner {
   position:relative;
   top:-50%;
}

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" />
<![endif]-->

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.

Updates

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;
   margin-left:auto;
   margin-right:auto;
}

In IE7’s CSS:


#container {
   /* required for IE to properly center vertically,
      must match #inner height */
   height: 400px;
   position:relative;
   top:50%
}

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…