Adding style to your rel attributes with CSS

View the finished example: Adding style to your rel link.

There’s a little attribute in HTML links that is starting to get a bit of attention lately. The “rel” attribute is a sparsely defined attribute that applies some meta information about a link’s relationship to other documents. Unfortunately, this information is usually hidden from your users. Let’s take a light-hearted stab at turning it into a visual element.

Rel attribute usage

While the W3C originally considered the rel attribute to describe the relationship of pages to each other, i.e. next, previous, directory, and start. The attribute has been adopted by the Microformat community for its inherit usefulness. The rel attribute is now used for tags, to define your relationship to someone, and even to tell search engines not to bother following a link.

The opportunities to use the rel attribute are seemingly endless. There are more proposals to define people you don’t like and links for voting.

But all of this flexibility comes at a small price. To remain valid, you need to tell the browser what these new rel values may actually mean. This is handled by linking to appropriate profiles. Just simply insert the profiles into your head tag. Multiple profiles may throw a validation error, but it’s ok. You don’t need to do this for the standard rel values.



We will be using the CSS3 attribute selector functionality to look at the value of the rel attribute and apply some style accordingly. First we’ll add some padding and a background image to any link that has a rel attribute. We’ll then use background positioning to display an icon that is appropriate for the link. It’s a fairly simple hack.

For more information on using attribute selectors, check out my previous posts:

Sample HTML Code

  • This link is ignored by search engines (rel="no-follow")
  • (rel="tag")
  • Sample CSS


    a[rel] {padding-left:20px; background:url(rel-sprite.png) no-repeat 0 0; }
    a[rel~="help"] {background-position: 0 -350px ;}
    a[rel~="license"] {background-position: 0 -1347px ;}
    a[rel~="no-follow"] {background-position: 0 -1200px ;}
    a[rel~="tag"] {background-position: 0 -47px ;}

    It’s all fun and games

    I’ll be the first to admit this exercise has significant issues. I’m assuming the following elements are true:

    1. All possible rel attribute values are accounted for in my CSS, if not there will be a blank space generated by the first rule
    2. You can only have one relationship defined by XFN. Unfortunately, most people are defined by multiple values, i.e. rel=”met friend colleague”. This CSS does not account for multiple values.

    So, the display of your rel attributes may be a bit off in the edge cases. Keep the spirit light and nobody will say anything… I hope. Have fun with your rel attributes. They’re just sitting there waiting to be used.

    View the finished rel attribute style example.

    Related Information

    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$="zip"],
    a[href$="pdf"],
    a[href$="doc"],
    a[href$="exe"],
    a[href$="png"],
    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 foo.zip.

    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.

    Internet Explorer is officially released

    Back in the dark days, programmers battled with a forgotten browser. It was good for its time, like a 4-cyl Fiero. But time marched on and this browser stagnated, forcing those working in the internet world to jump through programming hoops to make their pages work.

    There were a few heroes that made this work a bit easier. Big John and Holly started a virtual library. There even became an “IE7” long before Microsoft got off their asses. The IE7 javascript was a library designed to fix the annoying issues in Internet Explorer 6. Zeldman began touring the world preaching the horrors of bad browsers.

    And then something magical happened. Firefox was released with great support for standards-based programming. Quick on their heels came Safari and new versions of Opera that made life much easier. Instantly, Microsoft began losing their monopoly on the browser. Something had to be done!

    IE7 logoChris Wilson must have been summoned to the all mighty Gates and given the go ahead to build the new beast: IE7. “Go forth and build a browser that fixes as many IE6 bugs as possible. Add tons of security fixes. Add new RSS and open-source features. And whatever you do… make it backwards compatible for our customers.” It was a big order to fill.

    Internet Explorer 7 was on the road map.

    To show good faith, they released a very early version – IE7 Beta 1. This browser was so meager that it generated even more bad press for the hard working group. Standardistas were up in arms over the remaining bugs. The team began to reach out even further to the developer pool. They made nice with the Web Standards Project, they went to conferences, worked with the web dev teams of large websites, they even gave out really cool shwag.

    All of this led to some big promises and regular releases of subsequently better products. Bugs were squashed and developers began to learn how to deal with IE6/IE7 differences. I personally found a bug with transparent png sprites that I was happy to see fixed for the final release.

    Internet Explorer Hits The Streets

    This is the week we’ve all waited for. Internet Explorer 7 is officially released. Download it now. Microsoft will be actively pushing this browser as a security and feature upgrade. You can expect to see large numbers of your audience using IE7 over the next six months. I wouldn’t be surprised if IE6 is a grade B browser within a year.

    Internet Explorer 7 is not as good as Firefox. It’s not as good as Safari. It’s arguably not as good as Opera, only because Opera users love to argue. But it is much, much, much better than IE6.

    More importantly, this release finally allows us to use CSS2 rules. IE7 recognizes things like link[ahref=”fr”], div>p, li:hover, and ul:first-child. It doesn’t recognize generated content, that is my biggest complaint about the browser.

    Web standard design seems to be stagnating lately as we’ve gotten fat and lazy creating rounded corners without thinking twice. AJAX took over some of our creativity. Now it’s time to go back to the CSS2 specifications and really begin re-inventing web design.

    We’ve not only seen the light at the end of the IE6 tunnel, we’re standing out in the sun throwing pinecones at each other and running through the fields like drunk rabbits. Hats off to the IE7 team for delivering a browser we’ve been asking for. It’s not the one we begged and pleaded for, but maybe that’s what IE8 is for.

    The big list of fixed stuff in IE7

    The IE7 blog has a new post of items that have been fixed in the upcoming release of IE7. While not on the list, the problem I found with alpha transparent png sprites has been fixed for the final release.

    Take a look at the list and think of it as new tools to use.

    Bugs we fixed

    All bugs on positioniseverything.net except the “escaping floats” bug (which is planned for the future)

    • Peekaboo Bug
    • Internet Explorer and Expanding Box Problem
    • Quirky Percentages
    • Line-height bug
    • Border Chaos
    • Disappearing List-Background bug
    • Guillotine Bug
    • Unscrollable Content bug
    • Duplicate Characters Bug
    • IE and Italics
    • Doubled Float-Margin bug
    • Duplicate Indent bug
    • Three pixel text jog
    • Creeping Text bug
    • Missing First letter bug
    • Phantom box bug

    Details on some of the other bugs (from sources other than the positioniseverything.net list) that we fixed:

    • Overflow now works correctly! (That means boxes do not automatically grow any more.)
    • Parser bugs: * html, _property and /**/ comment bug
    • Select control: CSS style-able and not always on top
    • Auto-sizing of absolute positioned element with width:auto and right & left (great for 3 column layouts)
    • Addressed many relative positioning issues
    • Addressed many absolute positioned issues
    • % calculations for height/width for abs positioned elements http://channel9.msdn.com/ShowPost.aspx?PostID=191182
    • <?xml> prolog no longer causes quirks mode
    • HTML element truly independent of the Body (now gets its own width, height etc.)
    • 1 px dotted borders no longer render as dashed
    • Bottom margin bug on hover does not collapse margins
    • Several negative margin issues fixed
    • Recalc issues including relative positioning and/or negative margins are fixed now
    • CLSID attribute of <object> tag no longer limited to 128 characters
    • :first-letter whitespace bug described in http://blogs.msdn.com/ie/archive/2005/09/02/460115.aspx fixed
    • Descendant selector now works properly for grand children when combined with other selectors
    • First-line and first-letter now applies when there is no space between word :first-line and opening brace {
    • Pseudo-classes now are working as expected if selector is excluded
    • The :link selector works now for anchor tag with href set to bookmark
    • Addressed !important issues
    • PositionIsEverything piefecta-rigid.htm now works
    • List-item whitespace bug fixed
    • Fixed Absolutely Buggy II
    • Absolute positioned elements now use always correct containing block for positioning and size information
    • Nested block elements now respect all overflow declarations (hidden, scroll, etc)
    • Fixed the opposing offset problem (absolute positioned element whit all four top, bottom left and right are present)
    • <a> tags nested within LI elements will no longer add extra bottom margin when hover occurs
    • We no longer lose the image aspect ratio on refresh
    • Cleaned up our ident parsing according to CSS2.1 rules
    • Fixed parsing bugs for multi- class selectors and class selectors that are combined with id selectors
    • And many more

    We also extended our existing implementations to comply with W3C specifications:

    • Enable :hover on all elements not just on <a>
    • Background-attachment: fixed works on all elements – so Eric Meyer’s complexspiral demo works
    • Improved <object> fallback

    Finally, we added new features from CSS2.1:

    • Min/max width/height support (also for images, which did not work in IE7b2)
    • Transparent borders
    • Fixed positioning support
    • Selectors: first-child, adjacent, attribute, child
      • A couple of CSS 3 attribute selectors: prefix, suffix and substring since we were working already in the code base (also the general sibling selector)
    • Alpha channel PNG support (Not a CSS feature but too important for designers to not call it out J)

    IE Blog

    IE7 is still not as good as Firefox, Opera, or Safari. However, Microsoft is planning an aggressive updating campaign and hopefully it won’t be long before we can count on our average user’s browser supporting advanced CSS styles. It’s time to stop complaining about IE6 and begin planning how you will use these new tools.

    Forcing the footer to always be at the bottom of a page

    Cameron Adams (The Man in Blue) has created a method to force a footer to stick to the bottom of a page, regardless of how much content it contains. His approach is based on the work by Craig Erskine (solarDreamStudios).

    The Setup

    You have a page that terminates in a sturdy footer, such as this site. You’d like the footer to be cemented to the bottom of the browser window regardless of the amount of content. How do you position the footer at the bottom on a small page, yet not cause a conflict with long page? It’s actually more irksome than you would imagine.

    The Solution

    The footer is placed outside the content wrapping div. The html, body, and content div are given height:100%, which pushes the footer off screen. The footer then uses negative margins to sneak back up into the page. For pages with longer content, space is needed in the content div to avoid overlapping on the bottom.

    Based off the original footerStick, footerStickAlt sets up the Web page so that it will span the entire height of the browser window, even if the content is less than the height of the browser window. However, where footerStick then used absolute “bottom” positioning to get the footer to appear at the bottom of the screen/content, footerStickAlt positions the footer outside the height of the content, and then applies a negative margin to get it to display inside the browser window.

    So, where footerStick’s code requires you to place the footer inside a containing element, footerStickAlt requires you to place it outside the element:





    You then need to apply a bit of CSS:


    html { height: 100%;}
    body { height: 100%;}
    #nonFooter { position: relative; min-height: 100%;}
    * html #nonFooter { height: 100%;}
    #Footer { position: relative; margin-top: -7.5em; }

    …For the case where the Web page content is larger than the browser window, the footer will be positioned naturally below the content, then brought up by the margin. For this scenario you should provide a bit of space at the bottom of your content which the footer can rise into without covering anything. This can be done with a bit of padding or margin on your content.

    The only drawback to footerStickAlt is that you must know the exact height of your footer (whether it be in absolute or relative pixels). However, you have to know this roughly with the original version anyway, in order to make room for the footer at the bottom of the content. It’s generally a non-issue with footers anyway, as they have limited information and a sparse layout.

    Cameron Adams – footerStickAlt