CSS Attribute Selectors. I’d like to be able to use them.

I’m looking something like two or three years into the future to a point where I can implement a small, almost negligible upgrade to the way I serve back, next and home buttons for my galleries. Add one part coding neuroses, one part browser incompatibility and one part CSS and this article will be a small glimpse at the way I think.

This will be fun.

In my gallery pages I have something similar to the the following HTML markup on every page:

<div id="gallerynav">
  <a href="previous image link" title="Previous image" rel="prev" id="prev">Prev</a> 
<a href="main gallery link" title="Up to the Main Gallery Page" rel="toc" id="toc">ToC</a>
<a href="next image link" title="Next gallery image" rel="next" id="next">Next</a>
</div>

That’s styled with the following CSS

That's styled with the following CSS
#gallerynav a {
display:block;
width:21px;
height:18px;
position:absolute;
text-indent:-5000px;
}
a#prev:hover {
background:url(https://media.drunkenfist.com/img/back_o.gif) no-repeat;
}
a#toc:hover {
background:url(https://media.drunkenfist.com/img/home_o.gif) no-repeat;
}
a#next:hover {
background:url(https://media.drunkenfist.com/img/next_o.gif) no-repeat;
}
#prev {
background:url(https://media.drunkenfist.com/img/back.gif) no-repeat;
left:25px;
}
#toc {
background:url(https://media.drunkenfist.com/img/home.gif) no-repeat;
left:50px;
}
#next {
background:url(https://media.drunkenfist.com/img/next.gif) no-repeat;
left:75px;
}

Functionally it’s what I want- descriptive text, replaced with small graphics*, controlled by reasonably descriptive, compact markup. There’s just one thing that I’d love to be able to clean up and can’t because Internet Explorer 6 doesn’t understand CSS Attribute selectors. IE7 does. So it’s just a matter of time before I can start using them. Which is why I spend any time thinking about this at all…

What are CSS Attribute selectors, you ask?

The spec sayeth:

CSS2 allows authors to specify rules that match attributes defined in the source document.
5.8.1 Matching attributes and attribute values

Attribute selectors may match in four ways:

[att]
Match when the element sets the “att” attribute, whatever the value of the attribute.
[att=val]
Match when the element’s “att” attribute value is exactly “val”.
[att~=val]
Match when the element’s “att” attribute value is a space-separated list of “words”, one of which is exactly “val”. If this selector is used, the words in the value must not contain spaces (since they are separated by spaces).
[att|=val]
Match when the element’s “att” attribute value is a hyphen-separated list of “words”, beginning with “val”. The match always starts at the beginning of the attribute value. This is primarily intended to allow language subcode matches (e.g., the “lang” attribute in HTML) as described in RFC 1766 ([RFC1766]).

What does that all mean? From a W3c perspective, the rel attribute is a flexible method to add semantic data to links. Google uses it to great effect with the rel=”nofollow” attribute value pair.

From my perspective it means I could dump the ids on all of those anchor tags and use the following CSS instead for the same visual effect:

a[rel="prev"]:hover {
background:url(https://media.drunkenfist.com/img/back_o.gif) no-repeat;
}
a[rel="toc"]:hover {
background:url(https://media.drunkenfist.com/img/home_o.gif) no-repeat;
}
a[rel="next"]:hover {
background:url(https://media.drunkenfist.com/img/next_o.gif) no-repeat;
}
a[rel="prev"] {
background:url(https://media.drunkenfist.com/img/back.gif) no-repeat;
left:25px;
}
a[rel="toc"] {
background:url(https://media.drunkenfist.com/img/home.gif) no-repeat;
left:50px;
}
a[rel="next"] {
background:url(https://media.drunkenfist.com/img/next.gif) no-repeat;
left:75px;
}

Why bother? Well, if I could use the above code, I could drop the IDs and just use the rel attribute. Since I’m already using the rel attribute in that markup** I don’t really need the IDs for any real reason. I’m just using them as a hook for styles. Which is really no reason at all 🙂

Here’s a sample. IE6 will display a blank iframe.

For the real minimalist approach (at least in terms of markup) I could always use Adjacent Sibling Selectors. In that case I could drop both the ID and REL and just rely on source order to style the links from first to last. Of course, IE6 doesn’t support this either. IE7 does though, so if the adoption rate ever spikes***, expect to see code like this coming to a browser near you.


 #gallerynav a:hover {
/*this is the first A in #gallerynav*/ background:url(https://media.drunkenfist.com/img/back_o.gif) no-repeat;
}
#gallerynav a + a:hover {
/*this is the second A in #gallerynav*/ background:url(https://media.drunkenfist.com/img/home_o.gif) no-repeat;
}
#gallerynav a +a + a:hover {
/*this is the third A in #gallerynav*/ background:url(https://media.drunkenfist.com/img/next_o.gif) no-repeat;
}
#gallerynav a {
background:url(https://media.drunkenfist.com/img/back.gif) no-repeat;
left:25px;
}
#gallerynav a +a{
background:url(https://media.drunkenfist.com/img/home.gif) no-repeat;
left:50px;
}
#gallerynav a + a + a{
background:url(https://media.drunkenfist.com/img/next.gif) no-repeat;
left:75px;
}

Here's a sample. IE6 will display just the first link.

*one thing I'd like to do is use a single graphic and just change the background position. Cutting down on calls to the server- it's the new black.
**because it adds metadata to the links that could potentially be an aid to user agents or to myself when coding JavaScript
***I'm not holding my breath.

Posted in CSS

Leave a Reply

Your email address will not be published. Required fields are marked *