Thoughts on Embedding Fonts In Web Pages & Navigational Menus

I'm working on a little web interface for a friend that involves the use of a specific font for the navigation menu items. So far, I've have been a good little developer and have kept everything neat and tidy. The html contains just html with imported style sheets and I have eschewed using javascript by positioning everything with CSS. I can get away with it as a conscious decision was made to ignore IE6 and conform to standards (at least insomuch as the standards are implemented in IE7+, FF3+, and Chrome (assuming that means all webkit browsers & I'll test to make sure that it looks OK in AIR applications too) ).

But fonts are a pain. The friend is a designer, the font WILL be used. That leaves embedding graphics, sIFR, prepackaged Flash or custom Flash. Custom Flash is last because that is what I used, but I will dispatch with the other options as quickly as I can. (There is the @font-face; MS has an IE only font embedding scheme, *.eot files, and FF3.5 will support embedding TTFs but neither is presently practical for wide use.)

Graphics

Actually, as weird as it seems, this did seem like a tenable option to me. I was even prepared to build a library of gif characters to allow for flexibility in future menu changes. But what if the font decision were to change? What if I had to endure crazy styling concerns and found myself tweaking the placement of several dozen images that make up such a small aspect of the overall site. Without alternatives, this might have been the only option to ensure the aesthetic of the site. However, it isn't, so good riddence.

sIFR

sIFR, or Scalable Inman Flash Replacement, is probably not a bad way to go if all I needed was to inject the font into the page. For lots of reasons it is a sane way to deal with fonts. However, I am working on a menu that needs rollover text effects and sIFR doesn't seem to have that functionality.

Pre-packaged Flash

There probably are existing menuing systems out there that will do what I need - honestly, I didn't even look. I had three requirements:

  1. Import links from an external XML document
  2. Embed custom font
  3. Handle rollover effects
I'm pretty much done with the menu - assuming that it is well received by my friend - and, all told, it is under 9K. The extra bells and whistles would likely only caused bloating to my page.

Custom Flash

So writing my own seemed the sanest and to keep the size down, and because it is simple, there was no reason to use Flex. In fact, it was another opportunity to play with FlashDevelop, a free Actionscript IDE for windows. They have picked up the pace in releasing new builds and last week put out FlashDevelop 3.0.0RTM. As I didn't check for updates, I used 3.0.0RC5 in conjunction with Flex SDK 3.3.

I had worked earlier with Menus in Actionscript, but those focused on drop downs that had to integrate with helping javascript functions. I have one released into the wild, but in many ways it is a big pain. I am still going through refinement just in the placement of the menu on the page due to discrepency in browser layout engines, z-Index concerns and a host of other issues. Sufficed to say, I like the effect, but it can definitely be more trouble than it's worth (though there can be SEO benefits for the efforts, especially given that rel="nofollow" no longer removes links from bleeding pageRank). This menu is much simpler and my commented code is well under a 100 lines including Actionscript defined styleSheets.

Loading the XML

Loading an external XMl document is a straightforward thing and something that I do rather often. There are 3 steps:

  1. Creating a URLLoader
  2. Requesting the document
  3. Handling the Response

import flash.net.URLLoader;
import flash.net.URLRequest;

private function init(e:Event = null):void {

// STEP 1
var loader:URLLoader = new URLLoader();

// STEP 2
loader.load(new URLRequest("menu.xml"));
    
// STEP 3
loader.addEventListener(Event.COMPLETE, loadXML);         
}

private function loadXML(e:Event):void {
// VOILA, YOUR XML
var _menuXML:XML = new XML(e.target.data);
}

If you use, FlashDevelop it can create an application skeleton for you. The above uses the nomenclature from that skeleton, so just place your URLLoader code in the init after the comment "// entry point"

Embedded the Font

Embedding the font is also not too difficult. You use a compiler directive to inject the font, and then you just need to make sure that embedFonts is set to true on TextField that will use it. In your StyleSheet or TextFormat object, you can then refer to the name of injected font and all will be well.

package {
import flash.text.StyleSheet;
import flash.text.TextField;

public class Main extends Sprite {        
        
[Embed(source = "ForgottenWorld.ttf", fontFamily = "ForgottenWorld")]
public var fntForgottenWorld:String;
    
public function Main():void {
// constructor fun goes here    
}    

private function addTextField() {
var txtField:TextField = new TextField;
txtField.embedFonts = true;

// I had originally used TextFormat, but styles
// really simplified my code
var style:StyleSheet = new StyleSheet;

// using an Object to define the various Style properties
var myStyle:Object = new Object;
myStyle.fontFamily = "MyEmbeddedFontName";
myStyle.fontSize = 14;

style.setStyle("a:link",myStyle);

txtField.styleSheet = style;
txtField.htmlText = "<a href='http://blog.shortfusion.com'>Furious Coding</a>";

addChild(txtField);

}
}
}
Here are the docs that cover the CSS properties available to Actionscript.

Rollover Effects

Getting the RollOVer effect is just a continuation of the above. All one needs to do is to define the additional style object that expresses the change in CSS properties and then connect it to the anchor state

private function addTextField() {
var txtField:TextField = new TextField;
txtField.embedFonts = true;

var style:StyleSheet = new StyleSheet;


var myStyle:Object = new Object;
myStyle.fontFamily = "MyEmbeddedFontName";
myStyle.fontSize = 14;
myStyle.color = "#0000FF";

// ADDING AN ADDITIONAL STYLE DEFINITION
var myStyle:Object = new Object;
myStyle.fontFamily = "MyEmbeddedFontName";
myStyle.fontSize = 14;
myStyle.color = "#FF0000";

// ADDED AN ADDITIONAL setStyle STATEMENT
style.setStyle("a:link",myStyle);
style.setStyle("a:hover",myStyle);

txtField.styleSheet = style;
txtField.htmlText = "<a href='http://blog.shortfusion.com'>Furious Coding</a>";

addChild(txtField);
}
I used the troyworks discussion of TextField actionscript hyperlink in AS3 to get my mind set straight on this. Before reading this article I was trying to do everything with the TextFormat object and was pretty much hitting a brick wall.

When the site on which I am working goes live, I will post a link. Until then, I have run out of time to post an example - if someone really needs one, I can probably score some time to kick one out, but absent that, too many other demands on my time.

Comments (Comment Moderation is enabled. Your comment will not appear until approved.)
Freelance Web Development's Gravatar Here is a javascript solution. It looks pretty nice.
http://typeface.neocracy.org/
# Posted By Freelance Web Development | 6/20/09 7:23 PM
jason olmsted's Gravatar Thanks for the link to the Typeface project; it worked better than I had expected so now I need to find some time to look under the hood.

Unfortunately, for the usage I mentioned in this post, I would still choose to create a custom Flash strictly based on download weight. The js library it created for my typeface is about 45KB and when one couples that to the 20KB for the typeface-0.12.js that puts the whole solution at just over 60KB or about 3 times the size of my Flash movie + swfobject.js.

It is still very cool, and I imagine that there are optimization possibilities and perhaps differences due to the size of the font used (I am using one around ~20KB).

Thanks again
# Posted By jason olmsted | 6/21/09 4:07 PM
Daniel Sellers's Gravatar You could try Cufon: http://wiki.github.com/sorccu/cufon/about Similar. not sure how it compares in size. I tend to avoid flash for navigation because of 508/accessibility reasons.
# Posted By Daniel Sellers | 6/22/09 8:07 AM
jason olmsted's Gravatar Definitely appreciate the link to Cufon ... will try to give it a whirl sometime soon. It is nice to have options when it comes to getting design elements into a page without breaking accessibility.

That said, using Flash with swfobject, I also have a regular, plain text menu in the div into which the Flash movie will be inserted - when it goes live, the plain text will be driven (via Coldfusion) by the same XML that drives the Flash. So I am assuming, perhaps wrongfully so, that the menu items will be completely accessible. Given that I finally did a release build last night and got it down to 9KB (based on a 20K font and incorporating text effects - had to use TextFormat over StyleSheets, but that's another blog) I don't know if there is going to be a superior solution for a simple menuing scenario - I'd love to be wrong though.
# Posted By jason olmsted | 6/22/09 11:14 AM
BlogCFC was created by Raymond Camden. This blog is running version 5.9.1.001. Contact Blog Owner