Progressive enhancement of links using the CSS attribute selector

Attribute Selector Test Page

We have avoided using CSS3 rules for too long. It’s been difficult to justify using rules that won’t work for a significant portion of our audience, Internet Explorer 7 and below. However, Internet Explorer 8 is coming out soon and does work with the features we like.

I think it’s fairly safe to assume IE7 users will upgrade to IE8 within a short time. Those stuck with IE6 for one reason or another will slowly disappear as they are given new computers or their locked down environments are upgraded.

So, with the future of CSS3 functionality within reach, I’ve been energized to begin experimenting again. I’ll be writing a series of blog posts over the next few months that look at CSS3 functionality as a progressive enhancement. How can we continue to deliver a perfectly fine web site to IE6 and IE7 and mobile phones while enhancing the functionality of more modern browsers and devices?

Attribute Selectors

CSS attribute selectors are the golden ring on the web development merry-go-round. They can be daunting to learn, addictive to use, but then disappointing when you realize they are out of your grasp when you test in Internet Explorer. We can, however, begin using them to add additional functionality based on your pre-existing, semantic code. Attribute selectors give you power to write CSS that pinpoints the stuff you already code, without having to go back and add classes or ids. I’ve written previously about using attribute selectors to let your users know the language of a site they are about to visit. This trick relies on the rarely used hreflang attribute, which identifies the language of the site targeted in a link.

There are many other attributes in your HTML, from table headers, image src, link titles, and selected options. Think about all of those juicy attributes just waiting to be targeted. Also think about how you could actually do something useful with them.

Announce the file type of a link with CSS

I once worked for a company that had hundreds of thousands of static HTML pages in their intranet. With no content management system; it was impossible to make global changes. The only thing they shared was a common set of style sheets. Does this sound familiar? Follow along as we increase your site’s usability in a less than perfect, but efficient way.

First off, for accessibility, you need to let users know when a link will open a file, what type it is, and how large it is. This is best done by adding it to your HTML code:

Foo presentation (.pdf, 5kb)

That delivers the information to everyone, regardless of their browser. This, however takes time and is a daunting task for updating legacy code.

We can, however, use the atttribute selector to target the extension of the link to display the icon and insert the text describing the file type. Here’s the sample HTML code:

It’s a simple list of links for different types of files. We’ll be looking at the extensions: .zip, .pdf, .doc, .exe, .png, and .mp3. Feel free to extend this list to any extension you so desire. This would be especially helpful for a company that uses proprietary file types within their intranet.

Now, let’s look at the CSS:

a[href$="mp3"] {padding-left:20px; background:url(bg-file-icons.png) no-repeat 0 0;}
a[href$="png"]{background-position: 0 -48px;}
a[href$="pdf"] {background-position: 0 -99px;}
a[href$="mp3"]{background-position: 0 -145px;}
a[href$="doc"]{background-position: 0 -199px;}
a[href$="exe"]{background-position: 0 -250px;}

a[href$=".zip"]:after{content: "(.zip file)"; color:#999; margin-left:5px;}
a[href$=".pdf"]:after{content: "(.pdf file)"; color:#999; margin-left:5px;}
a[href$=".doc"]:after{content: "(.doc file)"; color:#999; margin-left:5px;}
a[href$=".exe"]:after{content: "(.exe file)"; color:#999; margin-left:5px;}
a[href$=".mp3"]:after{content: "(.mp3 file)"; color:#999; margin-left:5px;}
a[href$=".png"]:after{content: "(.png file)"; color:#999; margin-left:5px;}
a[href$=".exe"]:after{content: "(.exe file)"; color:#999; margin-left:5px;}

See the final test page.

Pattern matching in the attribute selector

We have some limited “regular expression” functionality in CSS3. We can search for an attribute’s presence and match a pattern within the attribute’s value.
Patrick Hunlon has a good summary of the pattern matching:

  • [foo] — Has an attribute named “foo”
  • [foo=”bar”] — Has an attribute named “foo” with a value of “bar” (“bar”)
  • [foo~=”bar”] — Value has the word “bar” in it somewhere (“blue bar stools”)
  • [foo^=”bar”] — Value begins with “bar” (“barstool”)
  • [foo$=”bar”] — Value ends with “bar” (“I was at the bar”)
  • [foo*=”bar”] — Value has bar somewhere (“I was looking for barstools”)

Attach icons to anything with CSS

The CSS is simply looking to see if the desired extension is at the end of the link href. If so, apply the following styles.

Adding an icon to the link

First, we are match any of the desired file extensions. We then add a background image and some padding on the left side with a bulk rule. Then the background position on the sprite is adjust for each particular link type. Combining multiple icons into one background image reduces the number of files the user has to download, making your page faster. This will work with any browser that recognizes attribute selectors, including Internet Explorer 7. However, support for more obscure attributes may be spotty.

There’s another peculiarity with pattern matching. Some attributes are case sensitive while others are not. The href attribute is NOT case sensitive, so the above rules will also work if your image name was FOO.ZIP, foo.Zip, or

Adding the descriptive text

Now, we are going to add a bit of descriptive text to each link. We can’t describe the file size, but we can tell the user what type of file it is. This is using the :after(content:) functionality and is supported by Internet Explorer 8 (yeah!!!) but not Internet Explorer 7 and below (boo!!!).
We will also adjust the color and give it a bit of spacing.

A big step forward with a small chunk of work

There you have it. A small chunk of CSS coding has now added substantial usability to your legacy pages. While the CSS version is not as accessible as having the data in the actual link code, it’s a significant improvement over nothing at all. Further, there’s no harmful effect on browsers that do not understand the function. You’ve added information, but haven’t taken anything away. This is a win in my book. To save some time and effort, you could just download and use this package of CSS and icons from Alexander Kaiser.

This rather simple example of attribute selectors and pattern matching can open your eyes to many possibilities. There are a number of developers that have been expoloring this potential for the past few years. Take a look at some of these resources for more ideas and have some fun.

Sample XHTML2 code

XHTML2 has been discussed for several years. It’s a logical evolution of HTML and XHTML. It introduces new tags that offer more flexibility and semantic value. So, what does it look like? Explorin Lauren has put together a sample page and it looks pretty simple.

XHTML2 introduces a new list item, the NL or Navigation List. Think of this as a cross between a DL and a UL. It is built similar to the UL but has a label tag.

You’ll also notice the image tag has been replaced with the more agnostic object tag.

Will you actually begin using XHTML2? Unfortunately, it’s not backwards compatible and browsers need a lot of evolving before they are ready for the new code. HTML5 is more likely the next evolution of HTML.

After working with XML for the past couple years, I would enjoy the structure of XHTML2. However, I also hate to think of the logistics of converting existing CMS sites and legacy sites to the new code. Not to mention the branching of CSS and/or JS for the new DOM elements.

@media 2006 first impressions

@media and the WCAG2

I was waiting for the WCAG2 smack down at this week’s @media conference in London. The stage was set for some serious smack talk and WWF style-insults. Heck, Joe Clark was even mentioned at least a half dozen times.

But a surprising thing happened on stage. The presenters, Gez Lemon, Patrick Lauke, Andy Clarke, and Ian Lloyd didn’t explode in indignation. Rather, it was the opposite. The panel pulled out their hoses and began putting out the WCAG2 fires.  The new guidelines are not perfect and nobody was close to agreeing to them. They are overly complicated and confusing. This was agreed upon.

However, they also seemed to agree that the guidelines were not going to bring the four horsemen of the apocalypse to the web developing community either. The guidelines are deliberately vague and technology-agnostic to allow for future growth.  Gez Lemon pointed out a new part of the WCAG web site that allows you to print a condensed set of guidelines for your specific technology, i.e. XHTML, SMIL, CSS, etc.

On the other hand, the number of people in the room that had actually read the guidelines could be counted on two hands. Further, the number of people that had read not only the guidelines, but also the supporting documents could be counted on one hand doing a variety of gestures.

@Media and the state of web design

It was a bit of a surprise to see the less discussion web design  at this year’s conference. The panels also discussed accessibility, web 2.0,  microformats, DOM scripting, hand-held devices, CSS history, and internationalization. Dan Cederholm discussed his bulletproof web designs, Nate Koechly discussed contrasting design considerations for two Yahoo sites, and Andy Clarke discussed alternate inspirations for web design. There was also a great panel with Veerle Pieters, John Hicks, and Cameron Moll about good vs. great design.

getting ready for Andy Clarke presentation

At last year’s event, Joe Clark creating some buzz and inspiration with his impassioned plea for single-column zoom layouts. You could feel the energy as people began mentally designing their zoom layouts.

This year Clarke, as in Andy Clarke, set the stage for a renaissance in design.  Why concentrate on grids when the result is the same old layout with a bit more perfection? Instead, he suggested we take that grid and start playing hops scotch with it. Make a practice grid and begin placing different shaped boxes until something comes together that is exciting and new.

He further showed how you could get layout inspiration from newspapers, photographs, and fliers. A Japanese newspaper’s layout looked the most foreign to my eyes, as well as many others. Vertical and horizontal sections seemed scattered around the page. Clarke super-imposed the grid onto the page and introduced us to a new method of laying out a page.

Chinese newspaper
Header, left column, right column, footer… yawn.  It’s easy, comfortable, and static. Clarke suggests breaking free of these standards and moving your content around the grid. Leave some open spage, add vertical bars and maybe even a framing device.

He further challenged us to abandon the concept of graceful degredation and move on to transcendental CSS design.  Echoing the points of Nate Koechly’s essay on Yahoo’s Graded Browser Support Grid, Clarke suggested we begin coding for the best browsers. We need to use CSS2 and possibly CSS3 elements. IE5 may not look as good as Safari, but his gloss-black pinto with wrong-way flames isn’t going to impress the ladies as much as his Audi S4 convertible either. Do we continue to downgrade the experience for everyone?  Or do we begin looking forward and push past today’s limits?  The introduction of IE7 this year will hopefully solve much of the existing troubles and allow us to make this move guilt-free.

@media and Internet Explorer

Eric Meyer began the conference with a keynote about the history of CSS, HTML, web design, and browsers. He set the stage for Internet Explorer discussions that would span several presentations. Further, he placed faces to the browsers, introducing many people to Tantek Çelik who has been credited with the IE5 Mac goodness and Chris Wilson, who has been credited with the IE Windows goodness and badness.

It’s easy to look at the problems we have with IE6, an outdated browser, and accuse the Internet Explorer team of being a bunch of hacks who couldn’t code their way out of a garbage sack.  Meyer reminded the older developers and taught the newer developers the history of the browser wars and how technically advanced IE6 was for its time.  In its day, it was a great platform for accessibility and contemporary table-based web design.

Fortunately, we have moved beyond the table-based days and other browsers have replaced Internet Explorer as the technology leader.  Microsoft is playing catch up and Chris Wilson came forward to pimp IE7. I also think many of the developers in the room will have a harder time kvetching about IE6, the broken browser from the behemoth beast of Redmond, after seeing an actual person on stage saying how proud he was to have worked on it. This geeky looking guy with a history of bad haircuts was also upset about the deadtime between IE6 and IE7 and promised to do his best to continue building better Internet Explorers in the future.

Wilson covered some of the required marketing points that most developers didn’t really care about. Security, blah, parental controls, blah, new controls, blah… better RSS support, blah…  I actually think IE7 does a great job with RSS, but Wilson didn’t discuss this very much.

He did grab our attention with a new feature, OpenSearch.  Developers can add a small metatag in the document head that will allow the user to add their site to the browser’s built in search bar. You can allow the user to search your site from a consistent location within the browser.  I couldn’t tell if your site remained in the list of sites to search from permanently or only while it was being viewed.  I’m going to look into the specs and try this as soon as possible.

Wilson also went over the list of bugs that have been fixed and took questions from people about future plans, backwards compatibility, and more.  He didn’t come across as the super-friendly, super-smart, super-man like Tantek, the ex-Internet Explorer leader. But he did put a human face to what many people considered their enemy and this is a good thing for the future of web design.

Book Review: HTML and XHTML: The Definitive Guide

HTML & XHTML: The Definitive Guide, an essential resource book for web programmers. Continue Reading Book Review: HTML and XHTML: The Definitive Guide

There are books you read that change your way of thinking (Designing with Web Standards), books your read for ideas (Usability: The Site Speaks for Itself), and books you keep within arm’s reach at all times. This book, HTML and XHTML: The Definitive Guide, is one that you should always keep on your desk.

I’m saying this from experience. I’m a self-taught web programmer and have read over well over a dozen programming books during the past few years. This is the book that traveled with me from job to job. It’s where I go to check on the proper use of tags and attributes. It’s a well laid-out reference book that is actually interesting to read.

Who should get this book

This book is for those working directly with HTML code. It does not discuss programming languages, JavaScript, or CSS to any extent. However, it clearly defines how to use valid markup to build sites. I have found it invaluable for building forms and complex data tables. It’s also a great foundation for those learning semantic markup from the beginning.

Using vertical-align for images and buttons

I’m working on a basic search form and the visual design requires a graphic button instead of the browser-generated input. I’m using the button tag instead of an input type=”submit”. While putting the page together, I had a nagging issue with the button not aligning with the label and input. I tried various combinations of margins, negative-margins, padding, and even floated the elements. All of these techniques eventually worked, but the were too klunky and I knew there had to be a better way.

I remembered the vertical-align:middle style while working on a footer paragraph that included inline links and RSS buttons. I tried it with the submit button and it also worked perfectly. I’ve tested this in FF 1.5 and IE6. I have not tested it in Safari yet.

Code Examples


form#foo button {vertical-align:middle; border:none; padding:0; background:none; cursor:pointer; *cursor:hand; /*alternate cursor for IE*/}