Use Lucida, Lose Your Readers

April 12, 2007

I’m sure, like me, you’ve come across sites which seem reasonably well designed but where the font looks all wonky and manky, as if it got rendered at a different size and scaled down using a nearest-neighbour transformation *. I came across one today and decided to get to the bottom of it. (For the record, it was for this interesting-sounding SEO tool.)

The cause? Not the use of <font> tags — though what the hell are they doing there? — per se, but their insistence on face="Lucida Sans". Strip them out, or bung in an accepted web font like Arial, and the lumpiness disappears.

Shame, really, ’cause Lucida Sans is a great font, but it clearly doesn’t scale well, or at least not the version installed with XP on my PC. (And no, it’s not the browser. IE6 & 7 make as much of a mess of it as Firefox does.)

Makes you wonder why the designer thought it worked. The stylesheet (yep — he or she did know about CSS) specifies an unusual body font size of 78.5% and if I could be bothered I reckon I could use this to figure out their monitor resolution. It must have been a lot of dots per inch, as there are certain high magnifications where the text looks as Charles Bigelow intended. 140% in IE7, for example.

So add this to the usual admonishments about specifying font sizes and the like: don’t be tempted to stray from standard web fonts or, SEO company or not, you may drive away visitors with unreadable text.

*My best guess is that this is exactly what’s going on.

The Flipside of Star-HTML

January 23, 2007

… is star-pipe-html

I was trying to work around a small Firefox bug today, which involved block elements which should have automatically filled the whole viewport but weren’t, due to some perfectly ordinaly right-floated images. (More investigation into this is required, but that’s a side-issue here.) Luckily, this is a fixed-width layout, so I tried feeding the width in, which cured the problem in FF, but blew up everything in both IE6 and 7. Opera carried on working just fine.

I could have just lived with the blemish in FF, but it would have bugged the hell out of me, so I started looking for a hack that could filter out all versions of IE. (I refuse to use conditional comments. I will not pollute my HTML.)

I came across this very useful Wikipedia page detailing CSS support in all major browser engines. Studying the Gecko and Trident columns I was surprised how much IE has caught up in selector support, but there are small differences, and one was an attribute selector I’d not come across before, the Namespace Selector. In fact the Wikipedia table gets the syntax wrong, but some further Googling turned up the syntax that Firefox (and Opera, Konqueror) accept:

ns|elt (where ns is an XML namespace and elt is an XHTML element).

I tried leaving the namespace blank (which is permitted), but

|html #secondaryContent li { width:660px }

wasn’t read by FF. First I thought I had the wrong day, the wrong browser or the wrong profession for my idea, but then I realised that this selects elements whose namespace is not specified. I had picked the very worst html element of all for that selector, the one which does carry a namespace. (At least it does in my doc, which begins:

<!DOCTYPE html PUBLIC
"-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

…etc, etc.)

The correct selector to select a body element with a namespace attribute (any namespace attribute) was…

*|html

So this is it; a nice, easy-to-remember filter to EXCLUDE ALL EXPLORER VERSIONS up to and including IE7. And not to be confused with our old favourite * html (space, not pipe), which we all know selects for IE6 and below. You could combine the two to make a high and low pass filter for IE7, thus:

p.styleme { color:red } /* IE7 */
* html p.styleme { color:blue } /* other IE */
*|html p.styleme { color:pink } /* FF, Opera, Konqueror, Safari */

According to the table, KHTML understands the namespace attribute selector, but WebCore does not, so it is an open question whether this filter will be seen by Safari. Can anyone confirm this? (Don’t have a Mac around here.)

As with all CSS hacks filters, caution is advised. In this case, I wanted to fix a small blemish in FF while avoiding a blow-up in the IE minefield. I’m comfortable in not knowing the exact behaviour in Safari, iCab and other minority browsers: it’s unlikely that feeding an element the width it ought to have anyway is going to have an adverse effect. But without careful thought, havoc could easily be wreaked. Nevertheless, I thought I’d share this, as in the right circumstances it could be quite useful.

UPDATE: The hack has been confirmed to work in Safari.

School of Rock Advent Calendar

December 4, 2006

Having failed, as usual, to find an advent calendar that meets my daughter’s exact specifications – not tacky, no low-grade chocolate – this is my (slightly late) offering to her. Fun moments from her favourite film, and no cloying, oily aftertaste.

Technically an online advent calendar could hardly be easier; in fact it took her brother and I as long to pick stills from the film as it did for me to code up, which I did using a small amount of css; an even smaller amount of HTML – a single image tag for the resizeable background, and an empty div to hold the images – plus a modicum of jQuery (with some popup assistance from Thickbox).

The jQuery code was mostly familiar territory for me: the images are scripted onto the page in a single loop, and - after the appropriate date - clickable to reveal the image (with attached thickbox link).

The only really interesting parts were the ‘random’ mapping so that images didn’t all appear in numerical order – achieved via a hard-coded mapping object, as there is apparently no way in javascript to fix a seed for the random number generator – and the use of cookies to remember which windows my daughter (or anyone else who cares to enjoy it) has opened, which pushed my envelope slightly. It seems incredible to me that all cookies get returned in one horrible, semicolon-delimited string (what would have been so bad about a string array?), but there you go.

Amazingly the two cookie handlers worked perfectly, although a bug in my mapping between jQ objects and DOM objects hid this for a while. This is always a tricky issue in OOP whenever you have two representations of the same thing, and the standard solution (attach a custom property - in this case .ref - to the DOM object holding the array index of the item which describes it) always feels a bit like a hack.

Anyway, for what it’s worth, here’s the code:

var windows = new Array;
var today = new Date;
var mapping = {
  1:17,
  2:22,
  …
  23:20,
  24:4
};
var folder = "school_of_rock";
$("body").ready(function() {
  for (var j=1; j<=24; j++) {
    var thing = document.createElement("div");
    thing.ref=mapping[j];
    windows[mapping[j]]=$(thing)
      .addClass("window")
      .appendTo("#picContainer")
      .html("<p>"+mapping[j]+"<\/p><img src='"+folder+"/"
        +mapping[j]+".jpeg' \/>")
      .bind("click", function() {
          $("body").focus();
          if (today.getDate()>=this.ref) {
            $(this)
              .find("img")
              .css("visibility", "visible")
              .wrap("<a href='"+folder+"/"+this.ref+".jpeg'
                class='thickbox'></a>");
            TB_init();
            setCookie(this.ref);
          } else {
            alert("Not yet!");
          }
          return;
      });
    //windows[j].get().ref=j;
    if(!readCookie(mapping[j])) {
      windows[mapping[j]].find("img").css("visibility", "hidden");
    } else {
      windows[mapping[j]].find("img").wrap("<a href='"+folder+"/"
         +mapping[j]+".jpeg' class='thickbox'></a>");
    }
  }
});
function setCookie(n) {
  document.cookie = "opened"+n+"=true; expires=Mon, 1 Jan
    2007 00:00:00 UTC; path=/";
}
function readCookie(n) {
  var where = document.cookie.indexOf("opened"+n);
  return (where!=-1);
}

It’s quite re-usable (I’m already thinking about the countdown for Christmas 2007). Ideally I would have scripted the background image into the page, so that only a single change in the folder variable would be neded to repurpose the entire thing. Oh, and if it hadn’t been so late at night, I would have added some animation to the window opening.

I should mention that since it has a target audience of (I)one, and I know which browser she uses (Flock), I have happily not had to think about how it looks in Internet Explorer, a situation of which I have taken full advantage. Since it uses percentage sizes and relative positioning, it’s fair bet IE6’s faulty positioning model will screw it up royally. If anyone else can be bothered to make it work I would be interested in seeing it.

Next year, she wants sound, too ;-)

Valid CSS Is Irrelevant

November 12, 2006

Someone recently posted on the css-d list (a useful place to learn more about practical CSS) a very ugly hack which proudly announced at the end “this hack is valid CSS3″. Well, great. Does that mean that whatever flaw in the target browser (in this case Safari) the hack was used to work around will bring other browsers to their knees when they catch up in CSS support? Not a great approach to web site building.

I am not anti-hack. Recently I resorted to an amazing filter: hack to get around an inheritance bug in IE6, and I use * html in pretty much every stylesheet I write. But normally I am compensating for some major lack of support in the still-unfortunately-widespread IE6 that other contemporary browsers have (eg no min-height). I think hacking for leading-edge browsers is a bad idea, and try to confine myself to hacks that can do no harm in the future (I don’t use the underscore hack, but it’s a safe one, as it’s unlikely new browsers will suddenly start supporting it.)

And as for “valid CSS” – I could care less. zoom:? filter:? Ok, if it works. Valid HTML - yes, please. That’s future-proofing. But isn’t CSS where we shunt all the complexity and ugliness that used to be in the markup? One day there may be an elegant and easy-to-understand layout language, but sadly CSS ain’t it.

In my view, as developers we are custodians of the information entrusted to us. In trying to make it appear on screen as intended we should add as little cruft to the markup as possible to achieve the desired look and feel. CSS and Javascript are tools to add visual appeal and functionality to the basic information. These need to be future-proofed too, of course, but we must accept that they are of secondary importance and some day they may be superceded.

Aiming for valid CSS is fine, and won’t it be nice when it’s all we need? But we mustn’t fool ourselves into thinking that if it validates we can’t have done anything wrong.

Get free blog up and running in minutes with Blogsome | Theme designs available here