Font replacement techniques

Like many other web professionals, I’m tired of the limited font set we have to work with. Gee, should I use Verdana on this site or Georgia? Maybe Arial? Meh. Bor-ing.

The merits and legal implications of CSS3’s proposed @font-face are being hotly debated, which means the proposal is going nowhere fast. Unfortunately, this also means we won’t have native browser support for a wider set of fonts anytime soon. In the meantime our sites (and e-learning courses) will continue to use the same old ho-hum fonts.

Are there any other options? The answer is yes, but none of them are perfect. The most common (and cross-browser) solution is to use what’s referred to as the image-replacement technique; the basic idea is to use a program like Photoshop to create an image containing your text in a nice font, then display the image instead of the original HTML text. Since this requires making a custom image for every line of text, it’s generally only used for headings. Chris Coyier wrote a nice article on the topic about a year ago, and rounded up the most popular techniques at the time.

Some enterprising developers have come up with alternative image replacement techniques that are quite impressive. The most popular (by far) is sIFR, a Flash-based solution that can replace any specified text on your page dynamically, using small SWF files. This solution doesn’t require custom images, is cross-browser, and is extremely flexible. Alas, it also requires JavaScript and Flash Player; if used for a lot of text on the screen, you wind up with a bunch of SWFs floating around, which definitely eats up CPU cycles and slows down older computers.

More recently, there have been interesting attempts at using SVG, canvas, and VML to draw fonts dynamically. One early implementation of this was typeface.js [link no longer available], which appeared to be a great idea but was difficult to use. More recently, Cufon has been getting a lot of buzz. I think it’s very nice and is easy to use, but it also has a few drawbacks, namely what happens if CSS is disabled in the browser:

cufon-screenshot

Image: Cufon in action, but with CSS disabled. Cufon-generated text is blue, the original text is black.

Any text generated by Cufon (and some similar scripts) is treated as an inline image — canvas elements are functional equivalents to images. The original text is hidden using CSS. If CSS is disabled, the original text shows up side-by-side with the generated text. This causes all sorts of problems.

Another drawback is selectability; Cufon and other canvas/VML-based systems have problems making text selectable in all browsers. To be fair, this is a problem with just about every image replacement technique except sIFR, which uses the power of the Flash Player plugin to get around the issue.

I’d like to be able to harness the creative possibilities of typography in my e-learning courses but really wish I didn’t have to jump through all these hoops to do it. Which system will I wind up using? Probably a combination of old-school static images created in Photoshop and sIFR. I feel that sIFR is the best option for my projects because of its greater accessibility and flexibility, but only when I know my target audience has Flash Player. I’m also very impressed by Cufon and hope they manage to take it to the next level to be on-par with sIFR.

Advertisements

Image-Free Progress Bar using MooTools and Canvas

As part of my ongoing experiments with <canvas>, I decided to convert an image-based progress bar to an image-free canvas-based system. I just finished whipping up a proof-of-concept; it uses MooTools to generate the canvas and CSS code. No images were harmed in the making of this progress bar.

More info later (time permitting)

Modal.js updated

Shortest post ever: Just wanted to mention my Modal.js class is still a work-in-progress. Today I made a few updates, most notably to some CSS handling and to the styling of the ‘close’ button (looks much more sophisticated now). Check it out.

Custom modal windows using canvas and MooTools

In my previous post Fun with canvas and MooTools: a Rectangle class, I explained that I wanted to make a modal window for a project at my workplace. I was interested in using MochaUI, but felt it was a bit heavy for my needs. I started playing with the canvas element (using excanvas.js for Internet Explorer support), and wound up making a useful Rectangle class that can quickly draw shapes in canvas using JavaScript.

Shortly afterward I built a simple modal window class named Modal using MooTools. This class combines a dynamic canvas drawing API (the Rectangle class) with dynamic DOM element generation to create on-demand modal windows using no external images. My goal was to make this about as easy to use as a normal JavaScript alert, prompt or confirm window.

I’ve been playing with it over the last week or so, and while it’s nowhere near perfect (esp. the ‘close’ button), I think it’s good enough for my project at work. I figured I’d post it here in case anyone wants to have a look. Feel free to use it if you like, but remember it comes as-is with no warranties! View Modal.js here.

Note: The code in Modal.js is subject to change!

I’m completely open to suggestions for code improvements (my code still feels ‘hacky’ to me), but I’m not really interested in adding new features at the moment. If you really want a full-featured, well-crafted window system, you should use Greg Houston’s MochaUI.

Modal Examples:

The default

The simplest way to invoke the window is:

var modal = new Modal({ title: "My title", html: "<p>My html code goes here</p>" });

Simple no-frills

You have the option of not using a window titlebar or ‘close’ button:

var html = "<p>This is a modal window without any title bar.</p>";

var modal = new Modal({
    html: html,
    width: 300,
    height: 200,
    edgeMargin: 1,
    windowRadius: 9,
    opacity: 0.80,
    colors: {
        modalBackground: "#CCC",
        windowBackground: "#999",
        contentBackground: "#EFEFEF"
   },
   showTitleBar: false
});

Public Methods

close() This closes the modal window. Once the window is closed, the elements are destroyed and garbage collected using MooTools’ element.destroy method.

var mymodal = new Modal({
    title: "My title",
    html: "<p><a href='#' onclick='return goAway()'>Close me</a></p>"
});

function goAway(){
    mymodal.close();
    return false;
}

Options

The options available in the Modal class are:

Text

  • title (String) Text content for titlebar. String format, loads into an h1 element.
  • html (String) Text content for the main window content. Loads into a div.
  • padding (Number, default is 12) Indicates how much padding the content div gets, in pixels.
  • font (String, default is “Verdana, Geneva”) Sets CSS style for the title and window content. Can be overridden by inline styles.
  • fontSize (String, default is “small”) Sets CSS style for the window content div. Can be overridden by inline styles.

Size/shape

  • width (Number, default is 350) Width of window before the drop shadow gets added, in pixels.
  • height (Number, default is 200) Width of window before the drop shadow gets added, in pixels.
  • shadowSize (Number, default is 6) Size of drop shadow, in pixels (note: not 100% pixel perfect measurements).
  • titlebarHeight (Number, default is 28) Size of titlebar, in pixels.
  • edgeMargin (Number, default is 1) Size of window chrome between shadow and content area, in pixels.
  • windowRadius (object OR number) Size of window corner radius, in pixels. If a number is specified, all four corners get the same radius. If an object is used, each corner gets the number specified (see below).
    • windowRadius.topLeft (Number, default is 9)
    • windowRadius.topRight (Number, default is 9)
    • windowRadius.bottomLeft (Number, default is 3)
    • windowRadius.bottomRight (Number, default is 3)

Behavior

  • animate (Boolean, default is true) Indicates whether or not to fade out the modal background when dismissing the window.
  • backgroundClickDismissesModal (Boolean, default is true) Indicates whether or not clicking the background will dismiss the modal window.
  • closeButton (Boolean, default is true) Indicates whether or not to include a close button. Only works when showTitleBar is also set to true.
  • showTitleBar (Boolean, default is true) Indicates whether or not the title bar should be rendered.

Colors

  • opacity (Number, default is 0.66) Indicates the opacity level of the background modal div. Number must be between 0 and 1.
  • colors (object) Child properties are used to specify colors for window elements. All color parameters accept standard CSS color conventions, including hex and RGB.
    • colors.modalBackground (Default is #000) Background modal div.
    • colors.windowBackground (Default is #AAA) Window chrome color.
    • colors.windowTitleBar (object) Used to create a gradient background for the window’s title bar. Accepts two properties: top and bottom.
      • colors.windowTitleBar.top (Default is “#F5F5F5”)
      • colors.windowTitleBar.bottom (Default is “#AAA”)
    • colors.contentBackground. (Default is “#F8F8F8”) Color of the canvas element behind the content div.
    • colors.closeButton (object) Used to create a the background and stroke for the closeButton.
      • colors.closeButton.fill (object) Used to create a gradient background for the closeButton.
        • colors.closeButton.fill.top (Default is “#F5F5F5”)
        • colors.closeButton.fill.bottom (Default is “#F36”)
      • colors.closeButton.stroke (object) Used to create a gradient stroke for the closeButton (does not work in Internet Explorer).
        • colors.closeButton.stroke.top (Default is “#FFF”)
        • colors.closeButton.stroke.bottom (Default is “#F00”)

Drawbacks

A system like this is bound to have drawbacks, and the biggest one is probably accessibility. Users with a screen reader or similar device may find the custom modal completely unusable. This is the same problem most RIAs face due to dynamically generated content. I’m considering implementing a check that uses a traditional JavaScript alert, prompt or confirm window in lieu of the custom modal if the user is using a screen reader. The check may or may not be based on whether WAI-ARIA mode is activated, but I have a long way to go before I’m ready for that! (Side note: To see WAI-ARIA in action, check out Google Reader.)

Another drawback is the mingling of my CSS with my JavaScript; in most cases I don’t like using JavaScript to set styles, except to set a classname. However, in this case I want the modal window to be as simple as possible and look nice out-of-the-box without requiring adding CSS files and all that jazz.

Lastly, I’d like to point out that the window doesn’t auto-size to fit the content. However, if the the HTML content doesn’t fit, the main content div will sprout scrollbars, ensuring you still have access to all of the content.

Anyway, this has been a fun experiment for me. It’s taught me a lot about what goes into creating feature-rich and flexible JavaScript widgets. I have nothing but respect for people who make JavaScript-based UI components like the folks behind MochaUI, Dojo, and YUI. It’s a TON of work.

Fun with canvas and MooTools: a Rectangle class

Greg Houston’s uber-cool MochaUI has led me to experiment with the canvas element the last few days.

I first saw MochaUI sometime in 2007. While I was duly impressed, I couldn’t quite find a use for it and filed it away in my bottomless “play with this later” drawer.

Recently at work I realized I needed a good modal window that was more extensible than JavaScript’s built-in confirm and prompt windows. MochaUI looked like a handy way to get slick modal windows into my project, but I soon realized that MochaUI is designed to do much, much more than I need, and therefore is (for my purposes) bloated. So, in typical DIY fashion here at pipwerks, I decided to borrow a page from Greg’s book and make my own MochaUI-inspired modal window using the canvas element, CSS, HTML, and MooTools.

Before I could get into the full modal window code, I needed to understand the canvas element, and learn how to manipulate it. Luckily for me, it isn’t much different than ActionScript’s drawing API. After evaluating what I’d need for my little modal window, I whipped up a MooTools-based JavaScript class that produces canvas rectangles in the blink of an eye. Check out the test suite.

Here’s how you’d instantiate a plain-jane rectangle with no stroke and a pink fill:

var canvas = new Element("canvas", {width:300, height:200}).inject(document.body);
var rect = new Rectangle({
    canvas: canvas
    width: 300,
    height: 200,
    x: 0,
    y:0,
    fill: "#F36"
});

Want rounded corners? Just add a radius parameter:

var rect = new Rectangle({
    canvas: canvas
    width: 300,
    height: 200,
    x: 0,
    y:0,
    fill: "#F36",
    radius: 9
});

As demonstrated by the test suite, the class includes the ability to specify the radius of each corner, the fill type and color (solid or linear gradient), and the stroke weight and color (including linear gradient).

For those of you unfamiliar with the canvas element, there are a host of additional options I chose not to build into my class, including join type for lines, radial gradients, and image backgrounds. For the purposes of my modal window, I didn’t need that stuff and wanted to keep it simple (and smaller file size). Feel free to modify the class for yourself, though.

Sometime in the next day or two, I’ll write about my modal window and provide test links. I’ll also cover the fugly hack required to get Internet Explorer to work with canvas.

Until then…

UPDATE: Read about the Modal class here.

PS: Disclaimers:

  1. If you’re wondering why I didn’t include a sample of the class in action on this page, my WordPress install uses jQuery, which conflicts with MooTools. I didn’t feel like fighting it tonight.
  2. I don’t write JS classes often, so I’m sure mine could use some cleanup. Feel free to make suggestions!