Coding with Jesse

Element dimensions on QuirksBlog

Peter-Paul Koch just announced that he's put up a new test page comparing the JavaScript dimension and positioning variables (offsetWidth, scrollHeight, etc.) across multiple browsers.

As a quick side note, QuirksMode is my favourite JavaScript and CSS reference, when it comes to figuring out browser support and differences. His examples are so clean and to the point. Thanks, Peter-Paul!

Published on January 23rd, 2006. © Jesse Skinner

Microformats

Microformats are a way of defining new data formats using existing standards and languages (ie. HTML and XML). It's a very exciting area of web development. The concept is relatively new, so there are really only a few formats out there (currently nine formats plus ten draft formats). There's also a lot of room for new formats to be created and used.

The idea is to use simple, easy, and predictable ways of defining new standards, rather than defining some complex impossible new standard. This way, the standard is something people can start using and benefitting from very easily and quickly. There's no need to go and change existing structures. Rather, microformats tend to be subtle adjustments to the way people tend to do things anyway.

The ultimate source of everything microformat-related is currently the the Microformats Wiki, and if it's your first time looking at microformats, I suggest you read the microformats entry. Since it's a Wiki, anybody can add new microformats, or contribute to existing ones.

I can't mention microformats without mentioning Tantek Çelik. He can be credited with the concept, and he still plays a very active role in defining and promoting new standards. He's the editor on the Wiki, and from what I can tell, he's co-created most if not all of the current microformats.

You may be familiar with the rel-nofollow standard. Google came up with the idea of adding rel="nofollow" to links in blog comments. This tells the Googlebot to ignore these links when calculating PageRank. This is intented to prevent comment spam, because spammers won't gain a higher PageRank by sticking their URL in comments.

The idea is perfectly simple. It uses an attribute built into HTML, the rel attribute, in a way that is consistent with its intended purpose. The HTML 4.01 spec says:

This attribute describes the relationship from the current document to the anchor specified by the href attribute. The value of this attribute is a space-separated list of link types.

They give a list of link types, but afterwards they state:

Authors may wish to define additional link types not described in this specification.

As a result, the rel-attribute is a common method of implementing link-related microformats. Another example of a rel-attribute microformat is the Technorati rel-tag format. Technorati scans blog posts looking for links with rel="tag". The word or phrase within that link is used as a tag to describe the post. This blog uses such tags, and you can see them at the end of this post.

In the future, I'd like to discuss some more of these microformats and show more examples. Until then, I suggest you check out the Microformats Wiki and see if there's any microformats you can start using today.

Published on January 18th, 2006. © Jesse Skinner

Multiple classes in Internet Explorer

I recently discovered the power of using multiple classes. That is, using more than one class on a single element. The class attribute simply accepts multiple classes separated by a space. For example, you can do something like this:

<style>
.box { border: 1px solid black; }
.small { width: 400px; }
.large { width: 800px; }
</style>

<div class="small box">
<div class="large box">

This is a great way to organize your CSS. For example, you can have a set of classes to define font styles and another set of classes to define box sizes. Then you can use them together in different combinations.

The class names "small" and "large" aren't totally clear, since they refer specifically to small and large box sizes. It'd be great if I could write "large title" and have it affect the font size instead of the width. So, I tried to change the definition by combining multiple classes in a single selector:

.box { border: 1px solid black; }
.box.small { width: 400px; }
.box.large { width: 800px; }

.title { color: blue; font-family: Arial; }
.title.small { font-size: 10px; }
.title.large { font-size: 20px; }

When I tried this in Firefox, everything worked great. Unfortunately, Internet Explorer doesn't support this. In fact, Internet Explorer will just look at the last class in the list. So, it will interpret the last example as if we had written this:

.box { border: 1px solid black; }
.small { width: 400px; }
.large { width: 800px; }

.title { color: blue; font-family: Arial; }
.small { font-size: 10px; }
.large { font-size: 20px; }

Small boxes will have small fonts, large boxes will have large fonts, small titles will be 400px wide, large titles will be 800px wide. Very unfortunate.

Once again, Internet Explorer ruins all the fun. Well, there's an up side to this. When we use "small" to affect the width in one place, and the font size in another place, we make it harder to understand and maintain the CSS. And isn't that supposed to be the point of using CSS?

Besides, not all is lost. We just have to come up with better names. We can still do this:

.border { border: 1px solid black; }
.small-box { width: 400px; }
.large-box { width: 800px; }

.title { color: blue; font-family: Arial; }
.small-text { font-size: 10px; }
.large-text { font-size: 20px; }

It sure isn't as pretty to write something like class="border small-box". But at least then we can use our "small-box" class in places that don't have borders, or use the "border" class to give a border to something without a fixed width.

In conclusion, avoid the .class1.class2 syntax altogether. It's not supported by Internet Explorer, and it makes code harder to read and manage. However, using multiple classes is completely supported and will make your CSS cleaner and more reusable.

Published on January 16th, 2006. © Jesse Skinner

5 things every web site can learn from blogs

Blogs are here to stay. However, I don't believe every web site needs to have a blog to benefit from the way blogs have changed the Internet. Here are five things blogs have taught us that we can use to improve all web sites:

  1. Update regularly

    Many web pages have some kind of "News" or "What's New" section. Most of them never seem to change. Blogs essentially took this section and made it the centre of the entire web site. Things are always changing and events are happening. The best part of the web is how up-to-date it can be. If something important is happening, and there is nothing about it on your web site, your visitors won't trust your web site as a source of information.

  2. Let visitors subscribe

    Blogs didn't invent subscriptions, but they've certainly proven they work. Long outdated are the phrases "Bookmark this site", "Under Construction" and "Check back soon". Every web site is changing and being updated. Visitors don't have the time to check back. You need to offer a way for them to subscribe. RSS feeds are certainly the new standard for subscriptions, though E-mail updates are still relevant for those who don't use RSS.

  3. Speak with a human voice

    Blogs aren't written in buzzword-filled meaningless marketing speak. They're written in the same language people use to talk to each other. The kind of language that people actually want to read. By changing the language of web sites, you not only make your web site more friendly, you make it easier to understand. If you really have something worth saying, be direct and clear about it. If not, why would you bother writing anything at all?

  4. Get personal

    Blogs don't hide the people behind the web site. In fact, that may be their strongest attraction. The Internet is changing the voice of companies whether they embrace it or not. For example, Robert Scoble's blog has become the voice of Microsoft. His blog is honest, admitting where Microsoft fails, where it needs to improve, and what its true motives are. It's time for the people behind web sites to come out and tell their stories.

  5. Let visitors discuss

    People need a chance to respond and add to things they read on the Internet. Most blogs give visitors a chance to discuss in comments and trackbacks. Where comments and trackbacks aren't appropriate, wikis and forums fill in the void. If your web site doesn't give a chance for visitors to contribute and share feedback (whether it's positive or negative), they will do this on their own blogs. Offering a place for the visitors of your site to come together and share feedback builds community, trust, and lets your site evolve in response to what people want.

Published on January 14th, 2006. © Jesse Skinner

JavaScript Speed Detection

This question came up on the css-discuss mailing list today (asked by Howard 'duke' Holtz):

I would like to include a Flash header on the homepage, but switch to a standard gif header for viewers with slow connections. I was hoping that there is a way to maybe have two “includes”, and use one or the other – but first I need some kind of 'conditional switch' or 'logic switch'.

This is a great question. I don't think any website has addressed this issue through scripting. We've all seen websites that start off with "Click here for Flash, Click here for slow connections" pages. But what about using JavaScript to test the speed of a connection?

I started experimenting with JavaScript and came up with a fairly simple, clean solution. It is all based on the onload event of an image. What we will do is time how long it takes to load an image. If the time is below our threshold for "high speed", we will display the flash content. Otherwise, we will do nothing and display the default content.

<script type="text/javascript">
var start = (new Date()).getTime();
var THRESHOLD = 2500; // a number we will calculate below

function speedTest() {
    var duration = (new Date()).getTime() - start;
    if (duration < THRESHOLD) {
        // fast connection (display flash)
    } else {
        // slow connection (do nothing?)
    }
}
</script>
<img src="some-image.jpg" onload="speedTest()">

The onload event can go on any image on the page, preferably the largest image to give us a better estimate. Let's say we only want users downloading faster than 10k/s to get the flash code. We check the size of our some-image.jpg, and see that it is 25kb. We can easily calculate the THRESHOLD value like so: (25kb) / (10k/s) = 2.5s. Converting this to milliseconds gives us 2500, so this is what we will use for the THRESHOLD.

If you're using Bobby VanDerSluis' Unobtrusive Flash Objects 2.0, you can put the UFO code to load Flash in the block for users with a fast connection. You can then do nothing for users with a slow connection and just let them see the default content on the page.

I have thought of one problem with this solution: if the image is in the user's cache, the number will be very low. This will cause the flash to be loaded if they come back later. To avoid this, you could add a no-cache rule on the webserver for this image. Or, instead of using an image on the page, you could load an image in the background with JavaScript using a random URL like so:

var testImage = new Image();
testImage.onload = speedTest;
testImage.src = "some-image.jpg?random=" + Math.random();

Of course, if you are using PHP or another scripting language on the server, you could generate the random URL a number of different ways. This fix also has the downside that the visitor must download this extra image every time. You'll have to balance these factors in your solution to come up with one that fits.

Good luck! I'd love to hear your comments, suggestions and questions about this. Let me know how it goes on your own web sites!

Published on December 14th, 2005. © Jesse Skinner
<< older posts newer posts >> All posts