Combining Yahoo User Interface and sIFR: Rich, Tabbed Typography

I’m a big fan of YUI (the JavaScript framework from Yahoo!, not the pint-sized popstar from Japan – no offence, Yui), and have been using it fairly extensively on the soon-to-be-relaunched goedhuis.com.
The main reasons for the love of this particular JavaScript framework are the vast array of well-documented and robust features you get for free, all of which are backed up with clear and helpful real-world examples on the main YUI site. It’s a great resource and has been a joy to work with on this project, a credit to the talented engineers at Yahoo.
Rarely is anything that simple though, and there have been a few challenges along the way on this project. I’d like to share some of these in future posts, but one problem I came up against recently was getting sIFR to play nice with the YUI TabView component.
FYI, the TabView component renders ‘navigable tabbed content’ in a format that is accessible for all users of the web, and Scalable Inman Flash Replacement, or sIFR for short, is a rather snazzy method for rendering dynamic, accessible, rich typography in a web page, using a clever mix of Flash and JavaScript.
The particular issue I hit was with the sIFR-rendered Flash movies not displaying correctly, or even at all, when switching between tabs.
Fortunately, our friend TabView exposes a healthy dose of events that we can subscribe to, the ‘activeTabChange’ event being our knight in shining armour here.
Warning: non-technically savvy readers may wish to look away now…
By subscribing to the ‘activeTabChange’ event we can explicitly render, or redraw, the sIFR movies on the active tab at will.
An example to illustrate may help, so let’s assume we have the following TabView-compatible markup, and that each of the H2s should be dynamically replaced by rich text using sIFR.
Tab One Content
Tab Two Content
Tab Three Content
The TabView instance is created first, using a simple one-liner:
var myTabs = new YAHOO.widget.TabView("sifr-demo");
And, next we wish to subscribe to the ‘activeTabChange’ event:
myTabs.addListener("activeTabChange", handleTabChange);
The handleTabChange is a function we’ll define, that will do the crux of the work. We need this function to replace the h2 on the active tab with some rich text using sIFR.
But, once this sIFR replacement is done, subsequent activations of the tab only need to ‘redraw’ the replaced text. In order to detect whether a sIFR replacement has already been done, we can use an array to track the indexes of all tabs that have been rendered with sIFR, i.e.
var rendered = [];
This should be defined outside the scope of handleTabChange.
Here’s a first stab at the handleTabChange function…
function handleTabChange() {
// Get the current tab
var idx = tabView.get("activeIndex");
// Ensure sIFR is defined
if (sIFR != "undefined" && sIFR.replace && typeof sIFR.replace == "function") {
// Has this tab already been rendered using sIFR?
if (!rendered[idx]) {
// No, not yet, so do the sIFR replacement
var font = {src:'/path/to/your/font.swf'};
var sIFRDefn = {selector:'.replace-me', css:'/* your CSS here */'};
sIFR.replace(font, sIFRDefn);
// Record the fact that this tab has now been rendered with sIFR
rendered[idx] = true;
} else {
// Yes, redraw the sIFR movies
sIFR.redraw();
}
}
}
I found that the above actually works pretty well, we can switch between tabs at will, and the sIFR replaced text is always rendered correctly.
However…
The function needed to be refined slightly, when there were other uses of sIFR outside of TabView on the page. The sIFR.redraw() function actually causes all instances of sIFR to be redrawn on the page, which creates an unsightly ‘flicker’ of all the sIFR Flash movies as they are redrawn.
The workaround is to get a hold of each of the sIFR instances within the TabView DOM tree and then explicitly ‘refresh’ each of those in turn, effectively ignoring all sIFR instances outside of our TabView instance.
We can grab all the sIFR instances in the current tab easily, using the YUI getElementsByClassName method, which lives in the YAHOO.util.Dom namespace.
With the markup listed previously, the following code yields the desired result:
var movies = YAHOO.util.Dom.getElementsByClassName("sIFR-flash", "object", "tab" + idx);
This snippet essentially says ‘get me all the object elements, starting from the DOM node with id ( “tab” + idx ) that have the class name “sIFR-flash”‘. Easy, eh?
So, to round off, here’s the revised handleTabChange function that will redraw only those sIFR movies on the selected tab:
function handleTabChange() {
// Get the current tab
var idx = tabView.get("activeIndex");
// Ensure sIFR is defined
if (sIFR != "undefined" && sIFR.replace && typeof sIFR.replace == "function") {
// Has this tab already been rendered using sIFR?
if (!rendered[idx]) {
// No, not yet, so do the sIFR replacement
var font = {src:'/path/to/your/font.swf'};
var sIFRDefn = {selector:'.replace-me', css:'/* your CSS here */'};
sIFR.replace(font, sIFRDefn);
// Record the fact that this tab has now been rendered with sIFR
rendered[idx] = true;
} else {
// Redraw ONLY the sIFR movies on this tab
var movies = YAHOO.util.Dom.getElementsByClassName("sIFR-flash", "object", "tab" + idx);
for (var i = 0, j = movies.length; i < j; i++) {
for (var k = 0, l = sIFR.callbacks.length; k < l; k++) {
if ( sIFR.callbacks[k].id == movies[i].id )
sIFR.callbacks[k].resetMovie();
}
}
}
}
}
So that’s my method of handling sIFR within YUI’s TabView component, I hope this approach is useful to others. Of course, if anyone has a better approach, then I’m all ears, please leave your suggestions in the comments section below!
Steve wrote this on 26.02.08 – 12 comments
It's filed in the Development, Web technology box

















On February 26th, 2008 at 9:17 pm, Mark Wubben responded:
Great write-up! You may want to note that you’re talking about sIFR 3 though…
On February 26th, 2008 at 11:46 pm, Steve responded:
Thanks for pointing that out Mark, forgot to mention that we are indeed talking sIFR 3 here!
On February 27th, 2008 at 12:40 am, Joshua responded:
for me as a designer i found this really interesting and i get it, if only i could code which i wont – leave it to the experts…. but for me a designer sIFR is typographic heaven because choice fonts can render as intended and yet you can still resize and get that text talking to google. bliss.
On February 27th, 2008 at 10:37 am, Matthew Hill responded:
Hey, this is a neat bit of code. Excellent work Steve. I’ve been playing with various JS libraries but haven’t tried Yahoo yet, I guess I should check this out.
For me, sIFR still isn’t quite ready for prime-time though. It’s slow if you have too many items on the page. It’s still tricky getting perfect leading. And the biggest issue is that it doesn’t scale sensibly: That is, if you change the pages text size, the Flash text doesn’t rescale unless you refresh the page. Yes, you could force it with some JS to check for an onresize event, but this should be part of the standard behaviour IMHO.
Out of interest, are you using a WP plugin for dislpaying code here? Which one — it looks lovely. :-)
On February 27th, 2008 at 10:42 am, Steve responded:
LOL – thanks Matt – glad someone noticed! ;) After a bit of digging, I couldn’t find a syntax highlighting plugin for WP that I liked, so I quickly knocked up a plugin that wraps the SyntaxHighlighter over at Google Code: http://tinyurl.com/2vpqca Happy to share my plugin, although it doesn’t fully implement all features of the Google SyntaxHighlighter.
On February 27th, 2008 at 11:19 am, Trevor May responded:
Very interesting article, Steve.
I agree with Matt that sIFR en mass is not quite ready for prime time – but it’s definitely improving. It’s also incredibly important that we keep experimenting with this kind of stuff so that when it *is* ready we already know what to do… Plus, experimentation very often reveals all kinds of wonderful new stuff to play with!
On February 27th, 2008 at 12:41 pm, Telmo Carlos responded:
YUI is definitely a great library.
And you did a great job with it. Our websites are looking better and better.
The implementations get closer and closer to the original designs. It’s good for the brand and for marketing. Glad to see the implementation efforts to match the original creative designs are paying off.
Look forward for the next creative-technical challenge.
On February 27th, 2008 at 2:49 pm, Jenni responded:
If you’re rocking the YUI you’ll love their blog http://yuiblog.com/blog/ It’s a bit hard core tech for me – but I was interested in the possibilities for easy pagination – and also how some developers are making use of YUI within AIR apps.
On February 27th, 2008 at 3:42 pm, Jenni responded:
You can see the difficulty with leading in the image used – ideally it would be tightened up, but the use of Clarendon really does lift the design and reflect the client’s brand values.
On February 28th, 2008 at 11:58 am, Steve responded:
Update: the syntax highlighting plugin used by this post is available on our companion ‘braindump’ blog: http://tinyurl.com/23qnkt
On February 28th, 2008 at 8:53 pm, Mark Wubben responded:
> For me, sIFR still isn’t quite ready for prime-time though. It’s slow if you have too many items on the page. It’s still tricky getting perfect leading. And the biggest issue is that it doesn’t scale sensibly: That is, if you change the pages text size, the Flash text doesn’t rescale unless you refresh the page. Yes, you could force it with some JS to check for an onresize event, but this should be part of the standard behaviour IMHO.
Slowness is mostly due to Flash, but okay. You can do leading in sIFR 3, I’m not a typography export but you now have the same leading as you can get from inside Flash itself. And, sIFR 3 supports page zoom in Firefox 3, IE 7 and Opera.
On June 15th, 2008 at 1:28 pm, iain Sutherland responded:
sIFR is an interesting tool and we have tried it in a few places as test installations. It can look excellent, however, we seem to have display issues relating to scaling especially when viewing the results in different browsers. Also, when testing the pages with the javascript turned off we do sometimes see both the flash and the html version of the text. We will persevere.