Monthly Archives: December 2006

Hyperlink Cues with Favicons

I wanted to extend the concept of hyperlink cues a little. For links that point to external sites, what if, instead of showing a generic ‘external link’ icon, we showed that site’s favicon?

Instead of this:

or this:

Do this:

The favicon gives the reader something to recognize if they are already familiar with the destination site, and if not familiar, something new to associate with it. It’s similar to the way a feed reader, or a bookmark list, might show sites.

The method to do this requires some CSS, but the most of the magic happens with JavaScript.

Note: I’m no JavaScript guy, and I can say with great confidence that there are more efficient and fool-proof ways to accomplish some things I put forth. If you know how the JavaScript mentioned here can be improved, please let me (and everybody) know.

On with the show.

English before JavaScript

First I wrote out what I wanted to happen in English:

  1. Look for links on the page.
  2. If the link points to some other site, grab the favicon off that site.
  3. Place the favicon next to the link.

Considerations

  • Favicons are easy to get. If a favicon exist, I can always count on it being in a predictable spot: it’s always right off the root of a domain, like this: http://www.askthecssguy.com/favicon.ico. For this reason, there’s no need to store favicons locally.
  • Not all sites have a favicon. Though most of the sites I regularly visit have a favicon, not all do. In those instances, I could either show nothing, or have a generic image to indicate that a link is external.
  • Not all favicons are the same size. Some are 16×16 pixels. Some are bigger. Yet I want all the favicons to have consistent dimensions. For this reason, I don’t want to call the image as a CSS background image, since currently-supported CSS doesn’t allow for resizing of background images. I’ll have to call the image using the img tag, and style it with the dimensions I want.

Examples

View example pages and view source to see code.

  • Faviconize Everything (View Page »)

    The script will scan every link on the page and place favicons after any links that point off site, resulting in:

  • The favilist (View Page »)

    The script will only attach the favicons to links within ul class="favilist", resulting in:

  • The favilist 2 (View Page »)

    Same as above, but showing favicons at ‘full-size’ 16×16, so bigger text, too, resulting in:

  • Faviconize Divs with Class (View Page »)

    Only works on links within a div tag of a specified class.
  • Faviconize Divs and excluding a domain (View Page »)

    I modified the ‘faviconize all’ script so that it will overlook a domain name of your chooseing. If you never want to faviconize pages that link to other pages on your own site, but your blog engine always puts absolute urls in your links, this might be helpful.

Room for Improvement

Here are some known problems. If you can help me solve them, please let me know!

  1. Safari doesn’t support the javascript onerror event. If a favicon doesn’t exist, it’s the onerror event that tells the browser to use the standby “external link” image instead. For Safari, I just get a blank spot instead of my standby image.
  2. The regular expression I’m using to grab the domain name out of my link is far from the best one to use. I suck at regular expressions, and after hunting through tutorials with examples, I found one that worked, but it’s got all this extra nonsense. It would be best to have one catered to my specific use. I just need to grab the domain from a link, like “www.wikipedia.org” from “http://en.wikipedia.org/wiki/Favicons”.
  3. Resized images are not ideal anyway, but they really look like ass in Internet Explorer.

Dec 30, 2006: Added example for only faviconizing div tags with a specified class.

Dec 30, 2006: I decided to drink my own kool-aid and introduced this effect in my comments. If commenters left a URL, their name becomes a hyperlink to that URL, and the faviconize script should then show the favicon of that URL if one exists.

Dec 31, 2006: I added another example. The new example shows how to modify the javascript so that you can specify a domain that will be ignored during the faviconization. (word?)


This post was ported from an old host and CMS, so many comments were lost. Below are the comments that I found were most helpful regarding this post that I salvaged. Some links or attributions may not be working correctly.


If you want the script to skip anchor links like that, you can change the following line:
if (hrefvalue.search(hoststring) != -1) {
into
if (hrefvalue && hrefvalue.search(hoststring) != -1) {
This way the code only executes if the hrefvalue exists, and it should therefore skip links the one you describe.

shawn said:
Bit of caution, this
cue.onerror = function () {
this.src = “external.gif”;
}
will cause an infinite loop if external.gif also errors for some reason.
Also you are setting localdomain = in every iteration of your for loop. I would declare it before the loop.

Instead of relying on onError, create your IMG tag as a DomElement, using your ‘default’ placeholder image. Then go away and fetch the favIcon, and if you don’t find one, your image still contains the default image, otherwise swap out the SRC attribute in your new dom element. THEN add it to the document.

JAM said:
hey, great post. while i was fiddling with it, i noticed that you can completely remove the regex. instead of
var domain = hrefvalue.match(/(\w+):\/\/([^/:]+)(:\d*)?([^# ]*)/);
domain = RegExp.$2;
you could write
var domain = links[j].hostname
tested in ie8, ff3.5 & o10. mostly should work with before version

Showing Hyperlink Cues with CSS

I like the little icons next to hyperlinks that signify if that link will take me offsite, open a popup, or link to a file (as opposed to another html page). Here’s how to do it in a way that’s supported in IE7, Firefox, and Safari.

Images

First, find some nice little icons (or better yet, create them yourself) in gif format that will be used as the cues. It might be easier for them all to be the same size (the ones below are 14 x 16) and have a transparent background.

Links to popup window
Links to external sites
Indicates a mailto: link
Links to pdf files
Links to Word files
Links to Excel files

Example 1 – link to pdf file – HTML

As an example, we’ll start with the link to the pdf file. Take a look at the following html:

<a href="files/holidays.pdf">View Holidays</a>

The link it generates might look something like this:

Notice there are no classes, ids, etc. that distinguish this link from any other. The only reason we know that it leads to a pdf file is that the last bit of the href attributes value ends in “.pdf”.

With some new CSS selectors that are supported in IE7, Firefox, and Safari, you can apply style declarations that are based on the values within tag attributes.

Example 1 – link to pdf file – CSS

If we apply the following styles to the html above:

a[href $='.pdf'] { 
   padding-right: 18px;
   background: transparent url(icon_pdf.gif) no-repeat center right;
}

We would get something like this:

How does it work?

The above CSS rule looks for all a tags whose href attribute ends in “.pdf”, then gives it some extra padding on the right of the link to make room for a small pdf icon as a fixed position background image. The dollar sign is what means “end”. Since the href in the html has a value of “files/holidays.pdf”, it will match the above CSS declaration, and the little pdf icon will be visible next that link.

Example 2 – mailto: links

Easy enough. Now what about the mailto: link? Take the following html:

<a href="mailto:billg@microsoft.com">Contact Me</a>

and apply the following style:

a[href ^="mailto:"] {
   padding-right: 20px;
   background: transparent url(icon_mail.gif) no-repeat center right;
}

Notice the caret (^) in the rule. The caret and equals sign means “starts with”. The rule looks for all a tags whose href starts with “mailto:”, then gives that link some extra right padding to display a small mail icon as a background image.

Here is the result:

Example 3 – Links to popup windows

Developers who separate markup from behavior should be linking to popups in a very web standards fashion – using a value of something like “popup” as a class or rel attribute in the link. Like so:

<a class="popup" href="help.html">Help Page</a>

Use that same class or rel to show our little icon.

a[class ="popup"] {
   padding-right: 18px;
   background: transparent url(icon_popup.gif) no-repeat center right;
}

The rule looks for all a tags whose class is set to “popup”, then gives that link some extra right padding to display a small popup icon as a background image.

Finding one value out of many

But what if we have multiple class or rel values? Like in the following example html:

<a class="popup specialstyle" href="help.html">View Help</a>

Now class doesn’t equal “popup”, but instead equals “popup specialstyle”. So the rule above won’t work. It’d be nice to have a way to see values that might be separated by spaces. You can by using the following:

a[class ~="popup"] {
   padding-right: 18px;
   background: transparent url(icon_popup.gif) no-repeat center right;
}

That tilde (found in the top left of most keyboards, requires shift key) and the equal sign together means “look for this word separated from other words with spaces”. Perfect for trying to match one value when there are several present.

In Summary

These selectors aren’t new, and the ones mentioned here are far from a comprehensive list. What’s new is IE7, and so I cherry-picked a few CSS selectors that I knew worked in IE7 and other modern browsers, and knew those are useful for the above effects. If it helps for you to see the code and have some images to play with, you can download the zip which has some examples.

(After thought: I could’ve attached a zip file icon to the “download the zip” link above, but chose not to. After all, I tell you it’s a zip already – no icon is really needed.)

Dec 22, 2006: I think my example above regarding the class attribute was ill-chosen, as it is much easier and better supported to target tags by class by simply using tag.classname selection method rather than tag[class="classname"]. (I can’t believe I didn’t think of that while writing the article.) I guess it shows that, like in mathematics, there is more than one way to reach the answer.

Dec 29, 2006:If you like this article and the effect it describes, you may also like a more recent article I’ve written about hyperlink cues called Hyperlink Cues with Favicons.

Jan 9, 2007: For this to work in IE7, make sure you specify a the right doctype. (see Aug 23, 2007 updated below).

Jan 21, 2007: If you’re looking for more icons to implement, Alex provides a nice start.

Jan 25, 2007: It was pointed out to me that for links that span two or more lines, IE doesn’t display these links as intended. Because the background position is set to “no-repeat center right;” it’s centering the icon between two lines. Consider putting the icon on the left side and use position of “top left” if you see yourself possibly encounterting multi-line scenarios.

Aug 23, 2007: Florian has notified me that which doctype you choose is important to IE7. He writes:

This page helped me a lot:
http://hsivonen.iki.fi/doctype/

I have now reconfigured my web server to add “http://www.w3.org/TR/html4/strict.dtd” to the doctype and now it works perfectly.

Basically, if FF says from page information that it’s in Quirks mode, then IE7 will fail … so if you look at the doctype table above, then you’ll find that any doctype that leads to quirksmode is deathmode for IE7.

Hope this information is helpful for you, too.

Very helpful. Thanks!


This post was ported from an old host and CMS, so many comments were lost. Below are the comments that I found were most helpful regarding this post that I salvaged. Some links or attributions may not be working correctly.


I just wanted to point out the fact (I skimmed through the article so forgive me if it’s mentioned somewhere and I just missed it) you can use any HTML attribute as a selector, and that’s really where this technique shines. For instance, a more common use of the attribute selector in the context of your popup example would be:
a[rel=”popup”] {
padding-right: 10px;
background: url(popup.gif) no-repeat right;
}
Then, all you have to do is add a rel=”popup” in you HTML href.

Baseball Card Image Captions with CSS and JavaScript (Near-Mint)

With my last entry, I discussed how to have the DOM generate text captions for images. Now I’m going to take it further, and with a little pre-drawn blank baseball card in png* format, I’m going to have the DOM turn my images into 1987 Donruss (or even 1987 Topps) baseball cards, with the caption showing as the player’s name.

*Why .png? As we all know, IE6 doesn’t play ball with .pngs. I could’ve used .gif format for the pre-drawn transparent baseball card, and this technique would work fine in IE6 without any hacks. But I’m wanting to use the 1987 Topps and 1987 Donruss card designs as frames (my heyday of collecting), which have rounded borders and special angles. There needs to be some varying levels of opacity in those corners, which .gif doesn’t do. It would all just look like ass unless I used a more boxy frame, like the 1988 Score set, but that’s not the one I’m going to use for this tutorial. I’m also not going to include the IE6 htc hacks, or the alpha-transparency hacks, which would’ve juiced up IE6 so that things will work, but instead I’m leaving them in the dugout. IE6 has a pitcher’s batting average when it comes to standards support, so upgrade to IE7 and call it a day. But know that this works in Firefox, Safari, and IE7, and if you wanted to create your frames as .gif instead of .png so that it’ll work in IE6, it’s your privilege to do so.

On with the game.

The idea is that you start with an image, a portrait in a vertically-rectangular fashion:

…and that image would be marked up like so:

<img
  src="dave.jpg"
  alt=""
  class="donruss"
  title="Dave Letterman" />

By the time I mix in a little JavaScript, that markup will turn out looking like this:

<div class="imgcontainer donruss">
  <img 
     style="width: 318px;
     height: 446px;"
     src="dave.jpg"
     class="donruss"
     alt=""
     title="Dave Letterman">
  <img 
     class="frame"
     src="frameDonruss.png">
  <div class="caption">Dave Letterman</div>
</div>

…producing our desired effect:

Note that the original image is stretched to meet the dimensions of the outer frame (in this case, 318 x 446). That’s why it’s best to use a vertically oriented image to begin with – so that it at least scales proportionately – if not the exact dimensions of the final product.

The markup generated by the JavaScript would by styled so that the different elements are layered to form the card:

An outer div is created and styled as position:relative so that the card frame and caption can be absolutely positioned in the right spot.

View the example and enjoy. If someone ends up making them with different card designs, let me know – I’d love to see them.

Image Captions Generated with CSS and JavaScript

For a online news article I used to update, one thing we’d always feature is an image of some CEO and present a caption to go with it. I was unsure of the ‘best’ way to display image captions. This is one of those things for which I wish there was a SimpleQuiz.

Which is the best way to display an image and its caption?

  1. <p>
    <img src="person.jpg" alt="person" /><br />
    This is a person
    </p>
  2. <div>
    <img src="person.jpg" alt="person" />
    <span>This is a person</span>
    </div>
  3. <img src="person.jpg" alt="person" />
    <p>This is a person</p>
  4. <table>
    <tr>
    	<td>
    		<img src="person.jpg" alt="person" />
    	</td>
    	<td>
    		This is a person
    	</td>
    </tr>
    </table>
  5. Make the caption part of the image.

I’m sure there are several other ways. When I received a new update for the newsletter that involved an image and a caption, I found myself checking previous issues to remember how I’d done it before so that I could be consistent. I had always wondered if there could be an easier way so that I wouldn’t have to remember. With the power of DOM Scripting, I can do just that.

I chose answer B above for the purposes of this demonstration, with some slight deviation. Here’s the picture I chose to work with:

I wanted my caption to be on the bottom of image, appearing as if it’s part of it, with a strip of color behind it for readability, but have the strip being somewhat transparent so that the part of the image that I’m covering could still be visible. The final result to look like this:

The only thing I want to put in the markup is the <img> tag.

<img src="dave.jpg" alt="" />

…but I know that I’ll have to give a tad more information for the DOM to work its magic. For one, I need to add a class. Another thing is the text to use as a caption. I could use the alt attribute for this, but instead I’m going to use the title attribute.

<img
  src="dave.jpg"
  alt=""
  class="captioned"
  title="Dave Letterman" />

And I want the DOM to create the caption for me. For the most part, I used example from choice B above, with some tweaks. The end markup to create this would look like this:

<div class="imgcontainer">
	<img
	  src="dave.jpg"
	  class="captioned"
	  alt=""
	  title="Dave Letterman">
	<div class="caption">Dave Letterman</div>
</div>

When thinking about how to write a script to accomplish this, it’s best to write out the steps in plain English:

  1. Look through all the images on the page.
  2. Check to see if the images have the class “captioned”.
  3. If so, take the title attribute value from the image, create a div with a class=caption and put that title attribute text within that div.
  4. Place that caption div immediately after the image.
  5. Wrap the img and the caption in a div together, giving that container div a class of “imgcontainter”.

Here’s the script I came up with. I call it ‘captionizeImages’.

function captionizeImages() {
  if (!document.getElementsByTagName) return false;
  if (!document.createElement) return false;
  var images = document.getElementsByTagName("img");
  if (images.length < 1) return false; 
  for (var i=0; i<images.length; i++) {
    if (images[i].className.indexOf("captioned") != -1) {
      var title = images[i].getAttribute("title");
      var divCaption = document.createElement("div");
      divCaption.className = "caption";
      var divCaption_text = document.createTextNode(title);
      divCaption.appendChild(divCaption_text);
      var divContainer = document.createElement("div");
      divContainer.className="imgcontainer";
      images[i].parentNode.insertBefore(divContainer,images[i]);
      divContainer.appendChild(images[i]);
      insertAfter(divCaption,images[i]);
    }
  }
}

And, of course, each of those elements need to be styled:

.imgcontainer {
	position:relative;
	float:left;
	}
.caption {
	font: normal 1em/1.3em arial;
	background:#fff;
	color:#000;
	position:absolute;
	bottom:0;
	left:0;
	text-align:center;
	width:100%;
	opacity:.75;
	filter:alpha(opacity=85);
	}

The .imgcontainer needs position:relative because the .caption div will need to be absolutely positioned relative to that container div. I had to float it left so that the div would wrap nice and snug around the img (with a float, the div expands all the way across the screen).

For the caption, I wanted to have a little transparency, which is where the opacity declaration comes in. For IE, I have to use filter:alpha(opacity=XX) instead of the opacity:.XX declaration.

View the example.

Row Locking with CSS and JavaScript

I was recently asked about the effect used to highlight a table row with a mouse click. This is different than highlights while hovering, as the clicked row should stay highlighted until clicked again. To differentiate this effect from ‘row highlighting’, I’ll refer to it here as ‘row locking’, since the effect stays in place until the user re-clicks (or unlocks) the row.

This effect is not achieved by CSS alone, but by a combination of CSS and JavaScript. While I’m confident in CSS, I’m quite a novice at the latter, which I’m sure will become evident by the end of this post. However, after reading Jeremy Keith’s DOM Scripting, I feel I have the tools to tackle the matter and come up with a possible solution. Much of the code I use to achieve the effect is directly derived from code examples in Keith’s book.

An Aside

Jeremy Keith’s DOM Scripting is a must for the XHTML and CSS designer who has put off learning javascript. I realized that as a web designer, I might be able to get away with not knowing PHP, mySQL, and other back-end stuff, but there’s no reason to limit myself to just two-thirds of front-end web design. Copying and pasting from prototype/scriptaculous/moo.fx/etc. is no substitute for learning how to do this kind of stuff, some of it very simple stuff, on my own. I appreciate Keith’s book for making the remaining third element of front-end web design so approachable.

Why?

Before going further, it might be good to mention why the effect may be useful.

  • If you’re scanning over a long table, it’s nice to mark a row to help guide the eye
  • If you wanted to compare two rows in a table, but they were several rows apart, highlighting each row could serve as a handy helper.
  • I noticed my Movable Type system panel uses this effect in the comments review section, and that the highlighted row also serves as a label for a checkbox on that row (handy stuff), although they are probably using a different method to achieve the effect.

The Blank Slate

I assume that a table that could use this effect would already be using table striping (making every other row a different color). So my ‘blank slate’ will be table with some basic data with no classes or style attributes in the xhtml. I’ll use a very simple script from Jeremy Keith’s book for striping the table (with a minor tweak so that it only stripes rows in the <tbody> tag, not the <thead> tag). The function works by attaching a class of row=”odd” to every other row on page load.

View Example 1: The Blank Slate.

Row Locking Successfully Achieved

Now that I have a table to work with, it’s time to decide how to achieve the row-locking effect. In DOM Scripting, Keith offers an example of code to achieve row highlights with a function called ‘highlightRows’, which uses onmouseover to change the class (and consequently, the color) of the row when the mouse moves over the table. If I can modify that script to use onclick instead, that might be all that is necessary to achieve row locking. With some minor tweaking, I ended up creating the function ‘lockRow’, which worked. On click, it adds a class (using addClass) to the row called ‘selected’.

View Example 2: Row Locking Successfully Achieved.

Doing More

I had mentioned that I modified Jeremy Keith’s ‘highlightRows’ function to create the ‘lockRow’ function. Ideally, I would like to use both effects.

To see the ‘highightRows’ function in action (without row locking), view Example 3: Row Highlighting. This script attaches a class of ‘highlight’ to any row that is hovered over.

Unfortunately, to combine ‘highlightRows’ and ‘lockRow’ in one table is not as easy as just placing all the functions on the same page.

View Example 4: Attempt at Using Both lockRow and highlightRows Not Working So Well.

I think I need to change the ‘highlightRows’ function to be conditional, so that it would only work on rows that wouldn’t have the ‘selected’ class. My attempts at achieving this have turned up unsuccessful. (Update Dec 22, 2006: Thanks to simu in the comments, there is now a working example – see end of post.)

For instance, here’s the ‘highlightRows’ function without modification:

function highlightRows() {
   if(!document.getElementsByTagName) return false;
   var tbodies = document.getElementsByTagName("tbody");
   for (var j=0; j<tbodies.length; j++) {
      var rows = tbodies[j].getElementsByTagName("tr");
      for (var i=0; i<rows.length; i++) {
         rows[i].oldClassName = rows[i].className
         rows[i].onmouseover = function() {
           addClass(this,"highlight");
         }
         rows[i].onmouseout = function() {
           this.className = this.oldClassName
         }
      }
   }
}

Here’s what I thought would make the function only work:

function highlightRows() {
   if(!document.getElementsByTagName) return false;
   var tbodies = document.getElementsByTagName("tbody");
   for (var j=0; j<tbodies.length; j++) {
      var rows = tbodies[j].getElementsByTagName("tr");
      for (var i=0; i<rows.length; i++) {
         if (rows[i].className.indexOf("selected") == -1) { 
            rows[i].oldClassName = rows[i].className
            rows[i].onmouseover = function() {
               addClass(this,"highlight");
            }
            rows[i].onmouseout = function() {
               this.className = this.oldClassName
            }
         } 
      }
   }
}

But that doesn’t do the job, so I’m kind of stumped at the moment. (Who’s going to start the ‘Ask the JS Guy’ web site?)

Another thing I found myself wanting to do is use shift+click to highlight several rows in a row. I’m not sure why I’d want to do that with my simple table example, but for some (like in the Movable Type checkbox scenario), it could be helpful. Right now, I’m not certain how to approach that one, either.

Dec 22, 2006: Simu (first comment below) has offered a modified highlightRows() function that allows for both the highlightRows() and lockRow() functions to co-exist and work together. (Thanks!) The javascript is very clear. View Example 5: Revised highlightRows JavaScript – lockRow and hightlightRows together a Success!

Dec 26, 2006: Tom pointed out my link to example 5 was in fact still pointing to example 4. It’s been corrected now – many thanks to Tom. Sorry for any confusion to others.

Feb 5, 2007: Kenny asked of a way to apply these effects to only tables of a certain class, which is a very good idea. View Example 6: Targeting tables with a specific class.

Feb 6, 2007: Raj asked about having, among other things, a checkbox for each row. Great ideas. View Example 7: Adding checkboxes to each row.

May 14, 2007: On my example with checkboxes, clicking a row would check the corresponding checkbox, but if I actually clicked on the checkbox, it was havoc. I toyed around with cancelBubble and stopPropagation, and ended up with a working example 8, which has an additional function to fix the issue.

Aug 19, 2007: Locking rows with radios is now working. See example 9 to see it in action and view source/copy.

Oct 22, 2008: New version of example 9 now using jQuery. See example 10 and the article describing it.

The CSS Guy Facts

Chuck Norris became a living legend the day Chuck Norris facts hit the Internet. Maybe if I start a list of larger-than-life ‘facts’ about my xhtml and css prowess, I’ll become one, too, and possibly be a story book hero for your nerdy great-grandchildren.

  • The CSS Guy has created many online forms, but has never completed one, as he refuses to “Submit” to anybody or anything.
  • The CSS Guy once escaped from a deserted island on a raft he built using only a transparent spacer gif and some javascript.
  • Most secure sites require SSL digital certificates and firewalls. All the CSS Guy needs is “Coded by the CSS Guy” in the footer.
  • The CSS Guy once took a dump on a keyboard, and it validated as XHTML 1.0 Strict.
  • The blink tag was originally created because the Internet lost a staring competition to the CSS Guy.
  • The CSS Guy’s web browser doesn’t just accept cookies, it demands them.
  • The CSS Guy does not use search engines. Instead, all information on the Internet seeks out the CSS Guy.
  • When the CSS Guy was in grade school, his crayons were labeled in hexadecimal.

I tried to wrap this post in a <roundhousekick> tag, but my browser couldn’t handle it.

What’s with the candy apples?

When creating this blog, I imagined to get CSS questions directed to me. The main question I’ve gotten so far is, “What’s with the candy apples?” I guess if you’re going to ask the CSS guy a question, I better answer it, even if it isn’t CSS-related.

Ask the CSS Guy's logo that featured candy apples

The site is going for a carnival theme. If we were at a real carnival, maybe between the booth where a guy guesses your weight and the trailer with the bearded lady, you’d have me waiting to tackle some CSS stumpers. Call me a geek, but I find figuring out CSS solutions fun. I also find it fun to start a fresh new blog for a while. It’s about as fun, you might say, as going to the fair. So I think the theme fits right in.

Not long after I created this blog I knew I had to get away from the Movable Type default template. I asked JD to help me come up with a design, and he came back with a photoshop document of much of what you see here. Not only was I happy to get away from the default Movable Type template, but I was excited to move towards a design that seemed so fresh. Much appreciation, JD.

So among many things that you might see at the fair are candy apples, and I found an image of some candy apples that could help decorate my new home. At the fair, you may also see ferris wheels, ‘ring-the-bell’ games, among other things. As this site progresses, you might see images of those things here, too.

So keep the questions coming. I’m happy to answer them. (BTW, I do relationship advice, too. )

Keeping CSS file sizes lean for practicality and sport

One of the benefits touted by separating style from structure is smaller html file sizes. But with many sites, the accompanying CSS file(s) can offset the savings in size, with CSS declarations that can quickly add up. Doug Bowman’s site, for example, has 50 KBs worth of CSS. Since CSS is cached, and therefore only downloaded once, and since a growing number of people are on broadband connections, some developers might not see this as a problem.

But there are still some dial-up users out there who still do value the time of initial page load. There are still server admins who care about bandwidth.
And fortunately, there are still some web developers out there who not only still care about those dial-up users and server bandwidth, but also take great pride in keeping their CSS files as slim as possible. If you think that only comes by sacrificing readability and structure to the CSS, you may be surprised. Here are some tips in doing so.

1. Use shorthand properties

I thought I’d start by stating the obvious, and say that you should use CSS shorthand properties. (Is anyone learning CSS without learning these, too?) I won’t go into all of the shorthand properties here (if you need to know all of them, use this handy page.

Basically, instead of declaring things this way:

#menu {
	margin-top:20px;
	margin-right:5px;
	margin-bottom:10px;
	margin-left:12px;

Do it like this instead:

#menu {margin:20px 5px 10px 12px;}

I’ll get another obvious one out of the way with my next suggestion.

2. Cut Colors in Half

Hexidecimal color codes can be shortened in many cases. #ff6600 can just be #f60. This only works when the values are given in pairs, but it’s still helpful. White and Black are both common declarations, so instead of #ffffff and #000000, use #fff and #000 respectively. This may not save much, but every little bit helps.

3. Plan ahead

Backpack enthusiasts care about every ounce they carry when hiking. The weights of the tent, flashlight, even silverware, was an important factor when purchasing and packing. Similarly, one can plan ahead when creating a site, and can shave off some bytes in the process.

When planning what CSS is used, make sure to research to find out how many different layouts your page can have. Are there some pages with three columns and some pages with only two, but the column with the main content will be the same in each? Then use classes and IDs wisely.

For example, take the following xhtml for a page with two columns:

<div class="layout2col">
	<p>Dogs smell.</p>
</div>

… and on another page with three columns:

<div class="layout3col">
	<p>More about smelly dogs.</p>
</div>

The CSS for that site might look like this:

.layout2col {width:400px;}
.layout2col p {
	font: normal 1em/1.2em Verdana;
	color:#333;
	}
.layout3col {width:250px;}
.layout3col p {
	font: normal 1em/1.2em Verdana;
	color:#333;
	}

It’s ok, but a bit repetitive. If the xhtml could instead look something like this:

<div id="content" class="layout3col">
	<p>More about smelly dogs.</p>
</div>

The following, more concise, CSS could be used and achieve the same results as above:

#content p {
	font: normal 1em/1.2em Verdana;
	color:#333;
	}
.layout2col {width:400px;}
.layout3col {width:250px;}

4. Ids, Classes, and File names

If a naming convention is used for ids, classes, and images, it can mean a big difference in the CSS file size.

For instance, instead of have a ul with an id of #primarynavigation and another ul with an id of #secondarynavigation, use #nav1 and #nav2 instead. Instead of #header and #footer, maybe use #head and #foot. Instead of a class of .content, maybe use a class of .main.

Image names are another place you can apply this technique. Instead of naming the background image to an h1 “background_h1.gif”, consider a name like “bg_h1.gif”.

5. Change Directories

File names aren’t the only place to trim some letters. Consider the directory where images are stored. The image directory has to be referenced with every mention of a background or list-style image. Many people call that directory “images”, but what if it was named “img”, or just “i”?

#logo {background: #fff url(../i/logo.gif)}

Not only would you save a few letters over the course of a CSS document, but it could be enough to keep many lines from wrapping, and therefore adding to the readability of a CSS file.

6. Consider ditching alternative fonts

I was always told to offer alternative fonts, such as the following:

p {font:normal 1em/1.2em Verdana,Arial,sans-serif;}

…which says that paragraphs should be of font-family Verdana, and if Verdana isn’t available on the user’s system, use Arial, and if Arial isn’t available, use whatever the default sans-serif font would be.

But I think some fonts, such as Verdana and Georgia, are on everybody’s system, so why bother offering a back-up? You could save a few bytes by ditching those alternatives:

p {font: normal 1em/1.2em Verdana;}

I usually only do this for Verdana, Arial, and Georgia. If a less boring font was to be used, it would still be good to list alternatives.

7. Work in one CSS file, but publish another

One easy way to trim file size is to take out comments and white space for the final version of the CSS file. Comments, white space, and putting one declariation per line are all great ways for developers to organize and write their CSS. But once you’re ready to publish that file, make a copy of it and strip all the comments and white space from the copy. Upload that new slim file to your server. After all, browsers don’t care about your CSS comments and white space. If you ever need to troubleshoot, rewrite, or add to your CSS, you can do so in your ‘working copy’. Then make another slimmed down copy to republish. CSS Tweak is a great service for stripping white space and comments.

Knowing that one will later publish a slimmed down CSS file can be quite freeing to a developer, and may result in that developer using more thorough comments than one would otherwise. And comments help everyone, even the person who originally wrote them.

I’d love to hear of any other techniques people find helpful.


This post was ported from an old host and CMS, so many comments were lost. Below are the comments that I found were most helpful regarding this post that I salvaged. Some links or attributions may not be working correctly.


Marty said:
Surley the best way to improve speed for dial up users is correct optimisation of images.

Bill Dashfield said:
Load time is important on our site; my approach is
* minimize image size
* keep CSS compact and optimised – easier to maintain.
* use Gzip (at server) to compress text (HTML, JS, CSS) files, reducing text file size by 66% or 75%, and reducing overall page load time by 20-40% with a single change. Uncompression has been long supported by browsers (HTTP 1.1 I think), is invisible, automatic and degrades gracefully. It is fast at the browser, though processor intensive at the server. Each page is cached once gzipped. (As my site is hosted externally, and has dynamic content, I’m still working on getting gzip enabled for HTML). With Gzip saving so much, I now leave comments in.
* Minimise numbers of files – some tools suggest each file increases loadtime by 0.2 secs in redtape.
Good design can greatly reduce the number of small image files. Currently, with variable layouts, IE specific and test files, I have up to 6 CSS files for a page – too many, even though they are all small and cached. I hope to optimise to 3 or 4.
PS 56Kb is 56 Kilobits per second = 1/8 of 56 KiloBytes per second. In practice it is much lower than that, even on a good line.