Skip to: Navigation | Content | Sidebar | Footer

Weblog Entry

Redesign CSS Notes

June 03, 2004

Alluded to in the earlier Technical Summary, the next analysis takes a look at the important CSS highlights of Proton.


As with the menus in Radar, these were inspired by Eric Meyer’s Pure CSS Menus demo. Using nothing but strategic placement of :hover they work without a line of Javascript, and degrade to a simple unordered list in older browsers.

Well, no script was the goal, but Windows IE doesn’t do much when you apply :hover to elements that aren’t links. As noted in the technical notes of this redesign, I launched with Peter Nederlof’s whatever:hover but had to back out due to slowness. I’m hoping to find a way around this when I have a free moment, something that will be a familiar refrain around here for a while as I knock down the various bugs in whatever free time I can find.

The markup behind these menus is relatively simple, although I may back out of an earlier decision to provide the text summaries for third-level menu items in the HTML, simply due to the fact that I’m not yet convinced it’s worth the overhead to provide what amounts to gratuitous text. The unstyled markup is quite a bit bulkier as well, which means more bytes to download and a lot further to scroll before getting to the content. (see it yourself, although you’ll have to shake off the cookie if you click that link by following it up with this one. You’ve been warned.)

The contact form embedded within the contact menu item was a proof-of-concept, mainly to see what the response would be. It’s flaky, and I got the first spam from it within hours of launch, so it won’t stay.

Content Scaling

Some of the ‘looseness’ comments that have been directed at Proton are no doubt a result of the liquid layout. Resizing the window leaves the center text column at a fixed width, while allowing the white margins on either side to fill the extra space. Except in IE, where the margins stay fixed and it’s the content that scales; a reasonable way to work around the lack of max-width support.

If you scale the text in your browser, the width of the centered text column changes accordingly, filling up the white space. Assuming those with larger windows also run larger resolutions (a logical assumption), and guessing that their fonts are generally smaller anyway, this kills two birds with one stone… for those who resize.

The CSS behind it is a simple matter of using an em unit on the max-width value, like so:

.contentarea {
  max-width: 45em;
  padding: 0 25px;

Again, no IE support, so padding was also applied to the edges of .contentarea for the sake of margins in browsers that don’t support max-width.

Accessibility Menu

One of the first pieces of markup to occur after the <body> tag is an accessibility menu, which doesn’t display on-screen in either Proton or Radar:

<div id="skipNav">
 <ul title="Accessibility options">
  <li><a href="#mainContent">Skip to Content</a></li>
  <li><a href="#siteInfo">Skip to Navigation</a></li>
  <li><a href="#styleswitch">Skip to Style Switcher</a></li>
  <li><a href="#linkList">Skip to Sidebar</a></li>

What is it for? With this markup, those without style enabled, and those using alternate access devices have a way to skip to various important parts of the site. (Skipping “to” content makes more sense to me as a user than skipping “over” content, since I care about that which I want, not that which I don’t want.) We all know by now that display: none doesn’t function as expected in screenreaders, so using it to hide this menu adversely affects some of those who need it most. What to do?

A suite of test cases was run against many common screenreaders last year to solve this dilemma, and one CSS technique was a clear winner. This is what I use:

#skipNav {
 position: absolute;
 left: -9999px;
 font-size: small;

By moving the menu off-screen to the left by almost 10,000 pixels (why not save the byte? I did, hence 9999) we can almost guarantee that it won’t display on any browser but those that need it. Note that if the links are underlined, Firefox runs the underline all the way back to the content area. Also, if for some reason you’re not confident that 10,000 pixels will be enough, you can clip the viewing area of the off-screen menu. The following code virtually guarantees nothing will show up, although the above snippet will usually be sufficient:

#skipNav {
 position: absolute;
 left: -9999px;
 width: 9000px;
 font-size: 1px;
 letter-spacing: -1px;

The fun doesn’t stop there. If your browser allows it, try hitting tab to cycle through the page’s links and form elements. By hooking into the :focus link state and absolutely positioning the individual links back into the content area, they show up on-screen as styled blocks.

Example of Skip To links

While this method doesn’t quite solve the dilemma of visible skip links, the only reason I can see why that is true is browser support. Those with mobility problems who use keyboard navigation can access them, those who are unsighted and using a screenreader can access them, and those browsing with a PDA or cell phone without style enabled can access them. If only :focus were more widely supported…

And with that, we’re through today’s analysis. Those were the more interesting CSS tidits from this redesign. I’ll leave discussing the more mundane layout and styling issues for another day. Next up in this series: design notes.

Reader Comments

daniel says:
June 03, 01h

that tab trick is wicked awesome! I just had to say it!

Javan says:
June 03, 01h

I was unsure of your new design at first, but it’s really growing on me. The dropdown menus are rad, but I just noticed one little quirk with them. After mousing over “contact” there is a small gap that you have to “jump” over to get to the form. If you move the cursor down really slowly, the form disappears .

Porter says:
June 03, 02h

Instead of fudging the positioning on the skipnav link(s) with an arbitrarily large value, why not make sure its out of the viewport like this?

position: absolute;
right: 100%;
bottom: 100%;

As long as the element’s positioning context was the ICB (or was at least in the upper left corner), as is typically the case with skipnav links, that would push it out the top, left corner. The values could also be altered to suit other specific cases where it wasn’t.

Just seems a little cleaner…

Conan says:
June 03, 03h

Not heard of IE7 yet?

Dave S. says:
June 03, 03h

“Not heard of IE7 yet?”

Yes I have, and it suffers the same problems as “whatever:hover” – go read the technical analysis from earlier this week for a summary of that issue.

June 03, 03h

Using :active in addition to :focus works for IE/Win. For example:

.skip:active, .skip:focus { /* … */ }

Dave S. says:
June 03, 04h

“Using :active in addition to :focus works for IE/Win.”

…doesn’t seem to. I added it to the style sheet, but I’m not observing anything different in IE.

June 03, 04h

“I added it to the style sheet, but I’m not observing anything different in IE.”

That’s strange. It works on Tom Gilder’s Blog, and on a project I’m currently working on. Actually, it even works on a copy of Mezzoblue/Proton that I saved locally, but not on the live site.

It doesn’t seem to be a caching problem, since it persists even if I quit IE and delete. I’m baffled.

June 03, 05h

P.S. Tom Gilder’s Blog is at

Sage says:
June 03, 05h

Hot diggity dang, that :focus trick is so cool! Jeebus, I wish I had the creativity to think of things like that… *big thumbs up* :-)

June 03, 06h

Re 14: Declaring .skip:focus, .skip:active (i.e. as one declaration) means that if IE doesn’t understand :focus, it *should* ignore the entire declaration. Maybe if you declare them separately it’ll work?

Dave S. says:
June 03, 07h

Great thinking Greg! It didn’t even occur to me that IE would skip the rule. Sad to say I’ve separated them out now and still don’t see a difference. Oh well.

David Robarts says:
June 03, 10h


If the performance hit of JavaScript reading the whole stylesheet is too great, one could always hard code the required :hover rules into the script. Disadvantage: back to two places to update when a change is made. Perhaps the best method would be to separate the styles that need some help from JavaScript and tell the script which stylesheet needs interpreting.

Link to Unstyled:

It would have been nicer if the unstyled link dropped the user back onto the article rather than the home page (ditto for the link back - perhaps with a named anchor).

Content Scaling:

I like your content scaling. Another important function of the padding is creating a minimum margin when the window is narrow, or font is large.

June 03, 11h

Nice write up Dave! How do you find the time to do it ? I may have mentioned this before on your blog but these are the sort of things I hoped I would be learning at University where I am studying a BA Degree in Interactive Multimedia but they still teach tables, font tags and even “How cool the Marquee Tag is” but the worst was when one tutor said we should design a few versions of the same site for the various different browsers and use “a nifty javascript to take the user to the correct site for their browser”. Keep em coming mate.

Rune says:
June 03, 11h

Nice notes. Your tricks about the issues are also worth remember.
You’re the master, Dave!

Dan says:
June 03, 11h

Kudos. As a hobbiest web designer with little time to read up on new and imaganitive methods in CSS, your site has been a god send to me. Thanks.

June 03, 12h

Paul - That whole issue is one worth talking about, university’s teaching old school techniques, with large companies requiring BA’s for applicants. Definitely slows standards adoption..

Nice writeup Dave, the more I come through the new design the more I like it. This one really breathes without becoming unreadable or looking rediculous at wide resolutions. Now when I go back to radar, it feels claustrophobic. Strengthens the case for liquid.

A general question I know, and I don’t want to start a whole thing here, but if a new client came to you today and they had no preference, would you go liquid or stay fixed?

June 03, 12h

I like the :focus trick to make the Skip Navigation links visible when tabbing through the links. Cool idea and cleverly implemented.

June 03, 12h

i like your implementation of the “skip” menu…a good expansion on something i have been using for quite a while on some sites, as outlined here
the only problem is that - again due to the :hover/:focus issue - it doesn’t work for anything other than a single link in IE.

neil says:
June 03, 12h

Very interesting.
I totally agree with the ‘skip TO content’ idea, I use that for my sites.
People do seek ‘A’, rather than choose to avoid ‘B’ so they can access ‘A’. Much more positive and real world I feel.

I’m really not sure were I stand on hiding accessibilty options.

It ‘s strange that so many of us will display XHTML, CSS, 508 and Accessibilty referer links in our footers as ‘badges’
of what our designs have achieved, but choose to style the actual accessibility options/tools as hidden from the standard design.

It’s rather like keeping the wheelchair ramps at the back of public buildings because the ‘look’ of them might detract with the architects design.

Why do we feel the need to hide web accessibility options so thoroughly from our designs?

June 04, 03h

I really liked your content scaling also. I have always just used a margin: auto to kind of get the same effect but as you can tell its not as good of a method as this.

Paul - And you are still paying for this school?

Dave says:
June 04, 06h

Oh… this site looks so bad now that it hurts my eyes.

It looks very unpleasant.

G. I. says:
June 04, 06h

I use

a:hover, a:focus, a:active { }

and it works in IE5-6 on my site to “hover” with tab on links.

June 04, 07h

Hi Dave,
It’s a shame that comment box won’t stay, I thought the effect was really cool. I love the skip links idea - I stumbled across it briefly a few days ago by accident; but wasn’t sure what they were or how they worked. Thanks for clearing that up.

As for the text summaries on third level menu items, why don’t you use the title attribute for the link. That way user’s with screen readers can chose whether or not to read it, which can’t be done as easily with a paragraph. I think you should be able to add the image versions using the ::after pseudo-element, rather than the paragraphs, or even a supurfluous, empty span element. Sure, :after still won’t show up in IE if you eventually provide a javascript fallback for the menus, but IE user’s could always read it from the tool-tip text, so it still degrades gracefully.

Robert Hilbe says:
June 04, 07h


There ist another solution to make css based menus work in nonsupporting browsers. The trick is to apply a class (e.g. .sfhover) to li elements in the navigation when they are moused over and to remove it when moused out. The only concession: You have to add additional rules to your css file.

What do you think about it?

See ALA-article “Suckerfish Dropdowns” or

Philippe says:
June 04, 07h

I have used this accessibility technique for quite a while with one link, and no problems in IE. I’ve also implemented the same with 3 links on my blog at [emps] :
where it seems to work fine (tested so far on 7 different machines).

June 05, 05h

Wonderful, wonderful to see such an excellent web producer take a chance and “be true to thine own self.” Now a comment to myself: “The reason for visiting Mezzoblue on a regular basis in the first place is to be bathed in the clarity of the written word, so remember the reason for your non graphic browser options.”