Force Font Smoothing in Chrome on Windows (Hack)

Update: May 2nd, 2012

This post remains for historical reasons, but what it was intended to fix is no longer applicable. All versions of Chrome since the latter v12 releases or early v13 releases should display smooth fonts of any size under Windows. If they don’t, you might need to adjust your OS’s font settings.

Update: June 21st, 2011

This trick no longer appears to work as of the latest Chrome release (12.0.741.100 as of this writing). In the comments below, Flix suggested using -webkit-transform instead to shift rendering to the GPU, but the effect is identical to the CSS hack listed here as far as I can tell. That is, neither works. Using a standard visible drop shadow does work, however.

Consider the rest of this post (mostly) useless and archived. The only way to achieve the desired result is to use drop shadows with no alpha. To illustrate the examples originally included in this post in addition to the suggestion below–and for historical value?–here is a screenshot:

You will notice that there is no marked difference between the first three. Only the fourth appears to be smoothed; it is also the only one with a visible drop shadow.

Twas fun while it lasted!

Original hack as I wrote it back in March–note that this trick no longer works:

I discovered something a couple months ago that was a curio, but it wasn’t until recently that I decided to experiment with it to see if I could (ab)use it. The best part is: It’s not hard, nor does it require any scripting at all. It’s still a hack, and I’ll explain why toward the end of this post. The solution? Use text-shadow; this appears to trick Chrome’s font rendering engine into smoothing the font, but you must use the blur radius:

.smooth {
    text-shadow: 0px 0px 1px rgba(0,0,0,0);
}

There. That’s all. Now you can enjoy (reasonably) smooth fonts across major platforms, provided your users are using Chrome. If you care to know a little bit more about how I discover this, keep reading. If reading is something you’re allergic to, you can continue on to something else.

The rest of the story

Obligatory disclaimer: I’m not much of a designer. I enjoy writing back ends more than I do UIs, but I do occasionally dabble in the world of web-facing user interfaces in addition to various UI libraries like jQuery and its myriad plugins. Sometimes, though, there is an intersection between the world of server software and user interfaces. Occasionally, I notice things that I haven’t read elsewhere; of course, this is such a rare circumstance that I tend more often than not to simply assume I’ve completely lost my mind and go about tending to other chores.

So, let’s talk about font smoothing in Chrome. If you haven’t discovered this already or haven’t read the musings of someone else who has, I’ll quickly share the basic premise. Simply put, larger font sizes look ugly in Chrome (Windows). I don’t know the technical aspects behind this, and Chromium on other platforms isn’t susceptible to the same shortcomings, but if you’ve carefully designed a site on some Unix-like OS like Mac OS X or some flavor of Linux with sub-pixel smoothing enabled, you’re going to be sorely disappointed with the fonts on Windows. While this hack doesn’t work for other browsers–Firefox 4 appears to smooth all fonts and MSIE 8 just ignores what we’re going to do–it does work exceptionally well for Google Chrome.

The trick? Use text-shadow. As it turns out, dropping a shadow behind a particular snippet of text forces Chrome to smooth the font. Here’s a before and after sample with a fairly standard drop shadow (text-shadow: 1px 1px 1px #ccc):

Now, obviously, it’s inappropriate to have a drop shadow on everything. Sure, you can match the drop shadow with the background color of the parent(s) containing the text, but what happens if the background contains a gradient or an image? Worst case, your text ends up with a halo; best case, it just looks a little fuzzier than normal. Here’s an illustration of the halo effect using bright red as the drop shadow (text-shadow: 0px 0px 1px #f00):

Ah, yes, you say. But you don’t need the blur radius argument!

I’m glad you suggested that. Let’s try turning it off (text-shadow: 0px 0px 0px #f00):

Whoops. Here we encounter a problem–the only way to force font smoothing in Chrome is to enable the blur radius. Without it, the fonts appear just as jagged as before. (Note: This occurs regardless of the X and Y offsets. Try it–you can move the drop shadow anywhere, and the text will still remain as it was without a shadow.)

Fortunately, there’s a trick you can use to fib the font smoothing without background bleed. In this example, I have created a CSS class as follows:

.smooth {
    text-shadow: 0px 0px 1px rgba(255,0,0,0);
}

Using RGB plus alpha, we get this result with absolutely no bleed through of the drop shadow. Yes, even with bright red:

Of course, my cautious inclinations suggest to me that it’s best to match the colors to your background anyway, but for browsers that honor text-shadow, support for rgba() is included as well and as such, the text shadow will never appear.

This trick is a hack, because it appears to coerce Chrome’s font rendering engine into smoothing fonts that it would ordinarily ignore. Comparing other Webkit-based browsers on Windows (Arora and Safari, specifically) appears to suggest that Chrome uses a hybrid rendering scheme that is a cross between a built-in rendered and Windows’ default. For instance, Safari will render everything as a jagged text if the default (Windows rendering) is selected but will switch to smooth font rendering if any other mechanism is selected. Arora provides no such option, nor do many non-Webkit browsers like Opera. Obviously, you should only apply text shadows to text that you intend to use a drop-shadow on or other similar visual effect, and using this trick on small fonts (~12pt) will produce text that is almost unreadable. While there’s nothing inherently wrong with (ab)using text-shadow, you’re probably much better off using it as it was intended!

This trick does not work for any other browser on any other platform than Google Chrome for Windows. Tested with Chrome v10.0.648.151.

6 comments.
***

Annoyances: vBulletin 4 Template Hooks

I’ve been doing commercial software development for vBulletin 3.x (and, by extension, 4.x) off and on now for a couple of years. While there are some things that irritate the crap out of me about both of these products, vBulletin (both versions) have features that just aren’t found in other bulletin board packages. Admittedly, many of these exclusive features are provided by an extensive library of 3rd party software, but the point still stands–as much as I hate to admit it. Few other message boards have a plugin system that’s easy to develop for, and fewer still have the vast library of plugins available. phpBB doesn’t even come close. vBulletin still has its shortcomings for developers, but I’ll save my complaints for a later installment.

What I’m going to write about tonight is something that bit me, and I know it’s going to bite someone else out there: Template hooks have been the bane of my existence in vB4 for the majority of this weekend, and once you start adding a few yourself, you’ll grow to appreciate the manic schizophrenia that is the vBulletin 4.x template system in all its unadulterated glory. I hope to save you from the onset of severe insanity, so keep reading for my story and my solution.

Side note: You might also want to make this a summer project, because you’ll be bald by the time you’re finished, and I understand that bald heads get cold quite quickly. If you’re already bald, accept my apologies and tear something else out–like the upholstery stuffing in your desk chair. Don’t have a chair? Reach for the carpet. Don’t have carpet? Well, you’re on your own.

Template Hooks: They Work–But not When You Want Them To

I’ve written a couple of plugins that rely on the various forumhome_wgo_pos* template hooks for both vBulletin 3.x and 4.x. These hooks work perfectly for most use cases, regardless of when your plugin fires, and are almost foolproof. Don’t be lulled into a false sense of security, though. The moment you do anything unusual with template hooks in vBulletin 4.x, you’ll be bitten by the what-the-heck-happened-to-my-output surprise.

To reproduce the ailment that has been afflicting my sanity for the better part of this last Sunday, I direct you to a simple test:

  1. Create a new product, complete with its very own plugin.
  2. Set the plugin to fire on the global_start plugin hook.
  3. Add the following code to the plugin:
    $template_hook['footer_test_hook'] = '<b>Hi!</b>';
  4. Add the following code to your footer template:
    {vb:raw template_hook.footer_test_hook}
  5. Run it!

You should notice that you now have a nice, shiny string containing Hi! at the bottom of your page in the footer code. Now, let’s break it:

  1. Add a template, such as break_my_footer to your product XML (optional; you could use any other template if you like)
  2. Call this template from your plugin using something like:
    $tpl = vB_Template::create('mytemplate');

    Or, if you decided to use an existing (small) template:

    $tpl = vB_Template::create('option');
  3. Then modify your template hook code appropriately:
    $template_hook['footer_test_hook'] = htmlentities($tpl->render());
  4. Watch in horror as nothing appears in your footer.

Try as I might, I spent a good hour or two trawling various vBulletin support sites for answers. Rather than make a post somewhere and risk having one of their ill-tempered devs explain “Well, this is how it’s supposed to work, didn’t you use the search?” when the built in search generally sucks and Google doesn’t always pick up their help threads, I decided that this issue became personal. That is to say, this code insulted my mother, my father, my nonexistent siblings, and each of my ancestors going back 1,500 years.

After performing various blind tests I concluded that somehow the call to the vB_Template::create() factory method was effectively wiping the contents of $template_hook–or ignoring it, or purging it, or performing an exorcism on it with tremendous glee while I steamed with fury in front of my monitor. I then decided that I’d had enough, and so I searched for the footer template to determine where it was being called, prepared, and possibly rendered in the code. My hunch was that the footer was being generated separately from the forumhome cruft that so happily seemed to work no matter where I used it or what I did with it (and indeed it is generated separately). Yet my own template hook refused to work.

Then I came across this code in includes/class_bootstrap.php:

 $templater = vB_Template::create('footer');
                        $templater->register('admincpdir', $admincpdir);
                        $templater->register('ad_location', $ad_location);
                        $templater->register('cronimage', $cronimage);
                        $templater->register('languagechooserbits', $languagechooserbits);
                        $templater->register('modcpdir', $modcpdir);
                        $templater->register('quickchooserbits', $quickchooserbits);
                        $templater->register('template_hook', $template_hook);
                        $templater->register('facebook_footer', $facebook_footer);
                $footer = $templater->render();

Pay careful attention to the line $template->register('template_hook', $template_hook);. Clearly, the footer is processing the template hook here–so I thought to myself, perhaps there’s a nearby hook that I could attach my plugin to so I can guarantee I know that the content of $template_hook won’t be interfered with.

I scrolled up and found a hook that probably should have been fairly obvious to me from the start. But hey, it’s the weekend. What more can you expect?

($hook = vBulletinHook::fetch_hook('parse_templates')) ? eval($hook) : false;

Sheepishly, I changed my plugin to use the parse_templates plugin hook instead of global_start, and it worked! So the upshot is: If you’re going to try using custom template hooks and you discover that they won’t work the moment you load a template, try changing the plugin hook to parse_templates. It might just fix the problem.

Now, this was admittedly all my fault for not realizing that parse_templates may be the correct solution; I really should have examined the vBulletin sources more closely. Shame on me. In my defense, though, the vBulletin documentation is pretty poor, much of it is outdated, and even less of it focuses on issues specific to 4.x. However, I have one particular bone to pick: It’s puzzling to me that whatever is in $template_hook will work fine up until the moment you decide to call vB_Template::create(). There’s a comment under the create() method that indicates something to do with $template_hook and treating it as a special case for the purpose of various globals or some such, along with a reference to a bug tracker ID. I think that’s more coincidental than anything else, and certainly if I wanted to find out what was happening, I could run a trace with XDebug, but I’m not that desperate–or bored (yet). My guess is that, somehow, subsequent calls to vB_Template::create() clobber the contents of $template_hook by the time vBulletin gets around to rendering the footer; I may be wrong–I probably am–but this is an example of bizarre code suffering from manic schizophrenia.

Frankly, the vBulletin sources are so stupidly convoluted it’s a miracle the software works as well as it does. I’ll save that for another rant much later this week or next. In short, remember: If you’re toying with custom template hooks, you might just break your code. If you do, try changing the plugin you’re writing for template rendering purposes to hook into parse_templates. You’re almost guaranteed to have little to no interference with the contents of $template_hook and the parse_templates hook is nearest to the templates that are most likely to be affected.

Toodles for now. Expect to see a whiny rant soon!

3 comments.
***

Annoyances: Video Tutorials

I’ve ranted about this before in another post, but it’s so damnably obnoxious that I can’t contain myself.

Before I start, I want to address the disagreement some of you are bound to have–yes, yes, I know that video tutorials have their place. For example, they might be exceedingly helpful for individuals whose tech level is below such threshold that they have a difficult time understanding the difference between left and right click. Or perhaps it’s a topic that requires some visual guidance such as conceptual demonstrations for Blender, Photoshop, or various other things that are highly interactive and not easily explained. (I still appeal that a skilled writer can explain anything with the written word that a video tutorial can–it’s just that some things are easier to convey visually.)

That, of course, is not the point of this post. The point is that there is a right way to illustrate simple concepts such as a single configuration change in an OS, and there are many more wrong ways to do the same thing.

Here’s an example. I haven’t (until recently) been using Ubuntu much, mostly because I’m in the process of abandoning Gentoo. Thus, I couldn’t remember specifically how to move the window interaction widgets (close, minimize, and maximize) to the right. I immediately stumbled across numerous sites that had embedded Youtube videos like this one.

I promptly closed them.

Video tutorials are a time sink. Generally, the viewer will have wasted at least one minute listening to someone introduce themselves, why they’re important, and then rant about whatever solution they’re going to demonstrate. Then, when the star of the show finally gets to the meat of a discussion that should take less than 15 seconds to explain, they invariably drone on and on about what items to click on, where to enter the change, and we get to stumble over each typo with our hapless host for 20 painful seconds. Once we’re finally presented with useful information, our brains have collectively rotted so severely that we have no recollection of what we were initially researching or attempting to resolve. This is the wrong way to share information. Worse, if one were to add up the total time consumed by video tutorials, minus the 5 seconds of useful information, there are hundreds of hours being wasted every day. It may not be Farmville, but it is close.

Side note: I’m not picking on the video I linked to above–I actually haven’t watched it–but I did see one earlier today where it took the individual recording it about 5 attempts to type gconf-editor correctly.

How then is the right way to do this? Easy. Howtogeek typically does things the right way in a manner that is insanely easy to follow, and you’d have to be comatose to have any difficulty with their tutorials. There are many more examples of how to illustrate a very simple concept quickly and efficiently, both in terms of time and bandwidth.

In other words, a good rule of thumb to follow is that if you can explain the concept in less than a paragraph, a video tutorial is like nuking your house from orbit because you’re too inept to fumble around for a slipper to kill that pesky house spider. That there are video tutorials on how to boil water worries me. Has our society grown so collectively dependent on instant gratification that we can’t so much as spend the time to read something?

Hint: It almost always takes longer to sit and watch an instructional video than it otherwise would to read those same instructions. Ever wonder why those cabinet kits you buy at the store have a piece of folded paper stuffed inside the hardware bag instead of a DVD? Paper is cheaper, for one, and for two, the average consumer is free to stare at the diagram (usually poorly written) for as long as they like; with an equally poorly recorded instructional video, I can only imagine that same consumer replaying the same 5 second segment two or three dozen times trying to figure out that the wooden dowel does, in fact, go inside the hole.

Let me reiterate my pet peeve about frivolous video tutorials:

Stop.

This.

Insanity.

Right.

Now.

Your unnecessary video tutorials are wasting bandwidth, and for most people looking for a quick solution (or reminder), a video tutorial is simply going to waste their time. Certainly, video tutorials are handy for individuals who may not know where to click on something, but I don’t see how it’s any faster than making a single post with a handful of easy to follow written instructions. Click here, click here, type this, press enter, look for item X, change it to Y, click close, done. See? Easy.

For those of you who link to every single obnoxious video tutorial on Youtube for all of your woes, please stop. Find something more meaningful like a textual post. It might surprise you to discover that some of us know how to read.

Video rots the brain, and get off my lawn.

Update: I decided to do some research, and while it doesn’t specifically address video tutorials, I think that usability expert Jakob Nielsen has an article worth reading that targets video on the web. It’s not the same thing, but I do feel that it applies tangentially to this topic.

No comments.
***