Foo Hack » CSS Isaac Schlueter on Web Development Tue, 03 Nov 2015 06:34:16 +0000 en Foo Hack 4.0 Tue, 05 May 2009 07:21:15 +0000 Isaac ...Read More]]> Partly because I haven’t been writing much CSS these days, and partly because it’s been just over a year since the last redesign, I felt like this site needed a face lift.


I’ve been getting more and more excited about the impending freedom of the @font-face CSS declaration. The prospect using any true-type or open-type font in a web page without resorting to flash or images is incredible. If you’re viewing this site in Safari 4 or the latest beta releases of Firefox, Opera, and MSIE, you’ll have a much improved experience.

The body text is set in Bodoni SvtyTwo OS, chosen for its beautiful italics (not an oblique, but a true italic), dramatic hinting, and straightforward lines. I chose the OS over the regular Bodoni SvtyTwo because of the more stylish “lower case” numerals: 1234567890.

Update: I decided to go with Hoefler Text instead of Bodoni. Bodoni looks nice, but without the stronger hinting, it was hard to read on some monitors, especially for folks who are crazy enough to browse the web on Windows. Hoefler Text has a lot of what I liked about Bodoni, and was a strong contender, but it’s not free-as-in-speech. However, it is free-as-in-MP3, so I’ll use it until Hoefler & Frere-Jones send me a C&D. I also widened the column a bit to accommodate the wider typeface.

The headings are set in Qlassik Medium, by Dimitri Castrigue. It has just enough fun to make it stand out, but not so much as to be ridiculous.

Code snippets are set in the famous Bitstream Vera Sans Mono. I’d initially planned to set all things monotype in my favorite coding font, Century Schoolbook Mono. Once you get used to coding with serifs, nothing else feels right. Unfortunately, it doesn’t include bold and italic versions. While the OS will “fake” bold and italics with fonts that it has installed, it won’t play ball when asked to manipulate dynamic fonts linked from a CSS file. I put CentSchBook Mono first, so if you have it (which you should!), it’ll work. Otherwise, you’ll get Bitstream.

If you don’t have a browser that understands dynamic fonts, you can grab them from


I really wanted to stretch my CSS abilities a bit, and also apply some of the principles of typographic design that I’d been learning about lately. The single-column is about 66 characters wide in the target font, and feels about “right” for readability.

Despite my best intentions, a lot of feature creep had somehow taken over, prompting the last revamp. In this version, I put back some features that I’d removed, and removed some things I’d left in.

The vertical measure is set at 30px, with a font-size of 20px. While that’s a bit large, I’ve always favored erring on the side of “too big”, and the Bodoni just felt too cramped at 16/24.

I’ve also taken a lesson from the print world, and set all my bullets and other adornments off into the margins, such that the text is kept strictly flush left. The only element that I couldn’t figure out how to do this with is the <q> element when it starts a paragraph. In that case, it should have a text-indent somewhere around -0.5ex, but I couldn’t manage to do that without borking quotes that start somewhere in the middle of the paragraph.

Since all the major browsers support resizing fonts that are set in pixels, and “zooming” is now preferred over simple font resizing, I went ahead and set everything in pixels so that the math would be easier. There’s really no benefit to so-called “fluid” layouts that are set in ex or em measurements. Plus, browsers that support dynamic fonts seem to have a really hard time with ex/em measurements, since the layout is rendered before the font has downloaded. I do hope that gets fixed at some point, but doing layout in pixels was a welcome return to basics.

Supported Browsers

The luxury of a personal site: I didn’t test even once in MSIE, and I don’t plan to.

Also, since a lot of the style is in the typography, anyone with a browser older than 6 months isn’t going to see my beautiful styles. But they’ll see their own default font settings, I suppose, and that’s probably fine.

What do you think?

CSS vs Tables: You’re Doing It Wrong Tue, 03 Feb 2009 07:40:22 +0000 Isaac ...Read More]]> Definitions first.


A specified set of columns and rows with cells that automatically and fairly smartly expand to fit their contents; cells can span rows or columns; the table as a whole can be treated as one block, and cells can contain tables. A table is a metaphor for visually laying out 2-dimensional content.


cascading style sheets; not floating divs, not any specific markup, but just the concept of the visual display of markup specified by a series of rules that are kept separate from the markup they operate on, generally in an external linked file or a style tag in the head of the document.

Talking Past Each Other

CSS is (for various reasons cited elsewhere ad nauseam), in most cases, the more optimal technological approach. That’s not to say that the existing state of the CSS language is perfect. In fact, even the most vocal CSS advocates regularly assert that there are deep problems with the existing spec and browser support.

Tables are (for various reasons cited elsewhere ad nauseam), in most cases, a more optimal metaphor than any of its rivals. There’s nothing inherently wonderful about the tags themselves. In fact, even the most vocal table advocates regularly assert that the markup is ugly.

Therein lies the crux of the problem. CSS is a great technological approach, and tables are a great metaphor. The question then usually becomes, Should I mark up my content using <div> tags or <table> tags?, which really means, Is the separation of style from content more or less important than using the optimal layout metaphor? The debate goes a little like this:


This layout metaphor is better, so you should use these tags. All you idealists are unrealistic! (Also, if you think markup matters, you believe in fairies. It so doesn’t!)


Metaphor shmetaphor! You don’t care about the sanctity of data or code quality. Think of the maintenance! (Also, if you can’t do it with divs, you’re stupid. It’s so easy!)

The Right Answer, it would seem, is to use the table metaphor with the CSS technology. In the ideal world, you’d always mark up your content using the tags that would communicate your meaning most clearly to your intended user agents. Then you’d tell user agents how to treat those tags visually. To describe this visual display, you should be able to use the table metaphor, or the float metaphor, or absolute and relative positioning, or anything else, but that should not be done by your markup.

Getting Real

In the real world, it’s not so nice. The CSS specification has a set of display values designed to mimic the table tags, but they aren’t well supported, and anyway, it’s an imperfect imitation of a hack that was not really intended to be used the way we all ended up using it.

In other words, CSS is not an ideal example of what CSS aims at, and the table/tr/td tags are not an ideal implementation of the table/grid metaphor. CSS tables, though they are clever and in some cases quite useful, take it from bad to worse.

The state of the CSS art is not at a point where you can realistically expect to make any significant stylistic changes to your pages without altering the markup. If you need to move the navigation bar from the right to the left, or re-skin the page with dropshadows instead of rounded corners, or convert your gradients from 2-tone to 3-tone, or make your boxes vertically centered instead of top-aligned, you’re probably going to have to change your markup, at least a little.

In theory, it’s possible. I know a handful of my colleagues will vehemently disagree and point at countless approaches to enable virtually any kind of reskinning using only CSS changes. (I’ve used Leslie Sommer’s CSS Mojo technique to great success in the past; we used it for pretty much everything on Yahoo! Buzz.) But let me tell you, from years of experience building production sites with CSS, most of the time, in reality it just doesn’t work that way.

And why should it? What kind of crazy lunatic writes all their HTML by hand in text files, anyhow? Clearly you have some kind of back-end engine spitting it out from templates, so you just change the template, and voilà!, the markup is changed everywhere.

A Very Blue Bike Shed

Working at Yahoo, I’ve met some webdevs with truly incredible CSS ability, who crank out live code under real deadlines to exacting standards. They use CSS, and not tables, and they Get Shit Done. There are a lot of them, more than I can list here, but Nate Koechley, Matt Sweeney, Hedger Wang, and Leslie Sommer all deserve a special mention. I came to Yahoo knowing CSS pretty well, but I became an expert largely as a result of working in such a highly skilled community of developers.

Also due to my time at Yahoo, I’ve seen some absolutely crazy debates about markup and coding standards on the devel-frontend mailing list. I mean, you think this little flare-up in the blogosphere is anything? You got no idea, buddy. Seriously. And these are coworkers who (for the most part) really like and respect one another.

You wanna know a secret? It makes no difference.

Language is as language does. If everyone uses the <table> tag for markup, guess what happens: <table> is now a semantically meaningless (or at least, semantically vague) tag, and any user agents that might care about navigating tabular data have to deal with that fact. It becomes just another <div>, for all intents and purposes, but a little less flexible, and with a default styling that makes it handy for layout.

The passion for the rants comes from the fact that it is meaningless! Of course it’s a fertile ground for bikeshedism!

That’s right: It doesn’t matter.

Use whatever tags work for you. I don’t care. You’ll still be a good person.

I can tell you from experience that a deep knowledge of CSS is essential for serious front-end development. (Most so-called DHTML is actually just manipulating CSS with Javascript, and the Javascript is pretty light.) CSS can do some things that table tags can’t, so you ought to learn it. The reverse is also true, so you should know how to use tables, too.

Write code that you can maintain, that is flexible enough to let you change it without sacrificing the stability of your product. Test it in the user agents that you expect to support. Stop debating the color of this bikeshed.

If there’s ever a good reason to go back and change your tables to divs, or vice versa, you can do that. Hell, plan for that, because whether you use CSS for layout or not, you’re going to need to touch your markup sometimes. It is much much harder to build a product people want than it is to build a product that works in Browser X.

Belorussian translation provided by fatcow

Foo Hack Redesign 3.0 Mon, 04 Feb 2008 17:00:41 +0000 Isaac ...Read More]]> So, it started out as just a few font changes. I’d been growing less and less pleased with Trebuchet MS, and had found a few cases where it broke the militant line-height rules I’d set for this site. In general, I felt that it was too crowded, and the gray hash textured background was (in my opinion) a contrived and artless approach.

I’m not a very understanding end-user when it comes to this site. The Foo Hack design team got fed up with my complaints, and decided to give in and make some changes.

Feature creep is a bitch when you have a deadline. For personal projects, there is no deadline, and so a bit of feature creep is fun, within reason. That’s a big part of the reason why I have so many back-burner projects that are almost finished; just as I near the finish line, I decide that it needs a little more, or another project gets more interesting for a while. So, on to what changed.


I was a computer geek first, but when my dad replaced our DOS home computer with a Windows 3.1 box, I fell in love with fonts. I can waste an afternoon surfing the web downloading fonts that I’ll probably rarely (if ever) use. Web design is about 90% typography, and it is an art that blends strict perfectionism and fluid acceptance in a beautiful way.

For the main body text, I wanted something subtle and easy on the eyes. Something that would let the writing speak in the voice that I intend, without getting in the way. For the “small” items of diminished importance (asides and things in <small> tags) I wanted a serif font with a very thin ex measurement, so that the text could “feel” smaller without altering the line-height. For the headings, I wanted a rounder, more open font that could evoke a sense of boldness without being too heavy. Subheadings and meta items (the date, “comment” link, etc.) should use the same font, but with less letter space and a subtler color.

For the body text, I decided to go with Helvetica, the classier old-world cousin of Arial. I was initially pleased with the results.

Cliché though it may be, Times New Roman was the perfect choice for the diminished items. It’s very light, yet still fairly readable, and when italicized, it practically disappears. I was already using it for that reason, but since I don’t love TNR all that much, I was willing to entertain other possibilities.

If Helvetica is so great, why do I see Arial?

A problem came up when I noticed that the line-height was getting messed up whenever a TNR inline element would wrap to the next line. I figured out the problem.

Let’s say you have font A and font B. You create a block-level element using font A. Then, you have an inline element using font B, which wraps to the next line.

If A and B don’t put their letters on exactly the same point in the line-block, then the line-height will adjust up or down, as the next line is set by the position of the letters in B instead of the position of letters in A. Since the B element isn’t a block-level element, it won’t create a whole new block, and will have the effect of adding or removing a few pixels from the overall height of the A element.

To correct this problem, and still have 2 fonts sharing the same block-level element, you need to find two fonts that have exactly the same vertical letter placement on the line block.

I’m not exaggerating when I say that I created a test page and exhaustively tested every combination of serif and sans-serif fonts on my Mac. It took about a week. There was only one combination that worked.

Arial and Times New Roman.

Ah, compromise, my old nemesis. You strike again. Not willing to give up the line-height strictness, I gave in and decided to use Arial instead of Helvetica. On the bright side, Windows users were mostly going to see Arial anyway, and they’re both tried and true web-safe fonts. And, at typical screen resolutions, it’s hard to tell the difference anyway. But still, it’s a bit of a sore point.

Gotham, Large and Small

Gotham, the masterpiece homage to urban signage by Hoefler & Frere-Jones, is quite possibly the best font ever devised. It’s open and confident even when it’s not bold, balanced and practical. I went with this as the headings, and it also was the best candidate for the smaller informational bits. (After all, it seemed fitting to put navigational links in a font designed for signage.

The downside of such a perfect font is that it’s not free. It would be fantastic if Apple or Microsoft were to license Gotham for their respective operating systems, but I don’t see that happening any time soon. Those that don’t want to install Gotham will see Century Gothic (if it’s installed, most likely because they got it bundled with Microsoft Office), or something in the Lucida family.

Accentuate the Important, Diminish the Rest

I brought down the contrast a bit, and did away with the background graphic. Some color was sprinkled around to help create a meaningful mental model of each page. I got the idea for the categories above the titles from Rands in Repose, one of my favorite regular reads.

The default set of post meta info that Wordpress provides is far more than necessary. I got rid of everything that didn’t directly benefit the goals of conversing with the world through this blog.


It seems awkward that my comments should have a blue left border, and reader comments are unadorned. Simply using random colors wouldn’t do. So, I wrote a function that will hash a string into a color value. A simpler hash would have sufficed, but I wanted more control over the range of colors that it selects, and rand() was a good fit. So, your comment will always have the same color (unless you use a different email address, of course) and all the colors will be in a particular mid-range of luminosity that is bold, but not overpowering.

I’ve already run into a few situations on this blog where I felt that threaded comments would have been helpful. However, the threaded forum-style comments would be complex and counterproductive. I grabbed a standard threaded-comment plugin, and tweaked it to replace the interface with a few hyperlinks. Since conversations are more naturally many-to-many, I’d like to implement something along the lines of what Dunstan Orchard used to have on his blog, but doing that the right way means a bit more investment, and this project was dangerously close to being back-burnered forever.

CSS Modal Dialog that Works Right Mon, 26 Nov 2007 18:13:04 +0000 Isaac last post, I touched on a method to get different browsers to handle the inline-block display style. I decided to use that on a project that I'm working on now that has a few modal dialogs. Modals are usually done wrong on the web, but I'm pretty confident that this approach does it right. Feel free to skip all this and go straight to the example....Read More]]> Note: This method has a few problems. Scrolling breaks on the iPhone, and the test page has some issues with tabbing through links. See my comment below. A new version will be posted soon. –i

In my last post, I touched on a method to get different browsers to handle the inline-block display style. I decided to use that on a project that I’m working on now that has a few modal dialogs.

Feel free to skip all this and go straight to the example.

In the application world, creating a modal is pretty straightforward. Here are some features that every modal window should have:

  1. Interaction with the contents of the parent window should be *impossible* until the modal is dealt with. Scroll-mouse should not scroll the background page, clicking should not click the background page, tabbing should not get you there, etc.
  2. When you dismiss the modal, the parent window should be *exactly* how you left it.
  3. The parent window should be dimmed, or there should be some other indicator that it is currently not available for interaction. This has the corollary effect of making the modal “pop” a bit more.
  4. In a web page, a modal should be constrained within the viewport. Opening a new window just to show a dialog box is ugly as a bucket of slugs.
  5. The modal should be placed consistently. If it is not movable, then it should be centered vertically and horizontally. This positioning should be consistent if the parent window is resized or moved.
  6. The modal should be smaller than the parent window. If the viewport is resized smaller than the modal, then scrollbars should appear that allow the user to see the rest of the modal.

The rule of thumb: The modal should be visible always and in every situation, the parent should be dimmed and preserved. Almost every modal dialog I could find online broke a few of these rules.

In some, the html and body elements have their overflow set to hidden when the modal is shown, so the current scroll position of those elements is lost. If you were looking through a list of items, and you brought up a modal dialog related to one of them, then you’re back to the start of the list when the modal is dismissed. Annoying.

In others, you CAN scroll the background, but the modal is set to respond to the onscroll event to try to stay in place. Some of the time, they use display:fixed to behave a little nicer in non-IE browsers. At worse, you get a jumpy seizure-inducing experience; at best, you accidentally scroll the background and lose your place without realizing it.

It’s a bit of an edge case, but you do have to handle cases where the modal might be taller/wider than the viewport. As a test, I tried resizing the viewport down on a bunch of modal approaches. Vertical centering often doesn’t do too well unless the contents are smaller than the viewport, so the top and bottom of the modal were cut off. Unacceptable.

It wasn’t terribly difficult to create one that obeyed these rules. Here’s the approach that I took.

  1. Build it with tables.
  2. Replace the tables with divs, and give them the appropriate display:table, display:table-cell CSS rules.
  3. Fret and hack to try to get it to work in IE, unsuccessfully.
  4. IM another yahoo who has a reputation for being a great webdev hacker.
  5. Adapt what he did to my needs.

For the non-IE browsers, it’s pretty straightforward. Take the scrollbars off of the HTML and BODY elements, and put them on #body instead. #modal is a sibling of #body, so when it is 100% height and width, it will cover it up. Then #modal will overlap the scrollbars of #body, without losing the scroll position. Also, that means there’s no need to do any trickery with a negative right margin to try (unsuccessfully, on the mac) to overlap the scrollbars.

Since .overlay element in the modal has a display:table, it will always expand to fit its contents. .overlay’s parent is overflow:auto, so if .overlay is too big, it’ll let you scroll to see the rest.

What this means is that you can’t cut off the top and bottom of the modal. It’ll be vertically centered if there’s room, and if not, it’ll be flush to the top and scrollable. Perfect.

For IE it gets trickier. Hedger’s example showed 2 great ideas, though. Basically, if you have 2 siblings that are display:inline-block, then, in IE at least, the line-block will expand to fit both of them. So, they both end up being vertically centered to the height of the taller child. If that taller element is width:0, then you essentially have an arbitrary line-height setter for the inline-block row. In this case, the height is set to 100%.

The other child will be whatever height it is based on its contents. If that happens to be taller than 100%, then the line-height will be taller than the viewport. At that point, the overflow:auto parent shows a scrollbar to let you see the rest. Identical behavior to the standards browsers!

The second problem arises with IE’s peculiarities when it comes to percentage heights. For whatever reason, if you have a position:absolute element, it doesn’t like to do height:100% unless some parent has a fixed height value, like 500px. 100% of 100% doesn’t compute, for some reason. Sadly, that means that the element that does the overlay wouldn’t be able to properly do its job in IE. So, instead of using a separate transparent layer with a background image, Hedger used the DXImageTransform.Microsoft.gradient filter on the modal container itself. However, since the gradient filter doesn’t actually prevent interaction with the background, I added a 1 pixel transparent gif as the background image.

I’d very much like to not use this transparent pixel. It feels a bit like a spacer gif to me. But, all in all, it’s a pretty small price to pay.

I didn’t bother to tackle the tab-order focus stuff in this little test page, since I wanted to just isolate the stylistic stuff to get it working across browsers. However, it would be good to put a focus handler on #body, and any time a #body element gets focus, focus the #modal instead. That way, once you tab off the modal dialog, you’d get right back onto it. In the spirit of being friendly to keyboard users, it would also be a good idea to keep track of the currently focused element when the modal opens, and go back to it once the dialog closes.

Here it is for your view-source pleasure.

Please please feel free use this modal. Life is too short to futz around trying to see the “cancel” button that is hiding off the screen so you can go back to reading your page.

Let me know if you can think of any enhancements or find any problems with it. Those of you in the US, I hope you had a great Thanksgiving.


I updated it to add support for focus and blur events. It works in Firefox, MSIE, and Safari. Opera on the Mac has some really strange behavior regarding focusing on links, and I decided that it just wasn’t salvageable. Safari requires a bit of hacking to get the focus stuff to work properly, but I think it’s acceptable.