CSS attribute selectors: Precision styling at your fingertips

You spend hours coding a template for a new content management system. The markup is pristine, frame-worthy even. You drop it into ModX or WordPress, add the content, and beam with pride. Then you activate a few plugins…
And the dream is over. Your once picture-perfect markup is suddenly desecrated by table-filled dreck that’s nearly impossible to style.
I found myself in this very situation with a plugin that automatically generated the markup for a form along the lines of this:
<form method="post">
<table>
<tr valign="top">
<td><b>Username:</b> </td>
<td><input type="text" name="username" value="" size="10" /></td>
</tr>
<tr valign="top">
<td></td>
<td><input type="submit" value="Register" /></td>
</tr>
</table>
</form>
Yikes. I planned to get rid of the table or, at the very least, add a class to the submit button and have it match the look of other form controls on the website. But the plugin’s source was encrypted and I was out of luck. So I turned to CSS attribute selectors.
What is an attribute selector?
A CSS attribute selector is a special style declaration that allows you to target elements through their attributes. For CSS 2.1, there are four ways to define how attributes are matched:
- Attribute name (
[att])
This applies the specified style to all elements with attributes of a particular name. In the example below, all heading1 elements with a title attribute would have a bottom margin set.
h1[title] {margin-bottom: 5px;}
- Attribute name with value (
[att=val])
This matches elements with attributes of a particular name and value. It’s arguably the most useful of the CSS 2.1 attribute selectors. The declaration below adds a background image to anchor elements that link to a website’s homepage. Note that there are no quotes around the value.
a[href=http://www.mydomain.com/] {background-image: url(house.jpg);}
- Attribute name with value in a space-separated list of words (
[att~=val])
This matches a particular attribute with a value that’s a list of words separated by white space, one of which is “val”. For instance, this next example would change the color of all anchor elements with a title attribute that has a value that contains the word “Water”.
a[title~=Water] {color: blue;}
- Attribute name with exact value of “val” or value that begins with “val” followed by a hyphen (
[att|=val])
This one’s a bit tricky and is primarily intended to match language codes. The example below adds padding to the left of all anchor elements with a link language attribute that’s either English (”en”) or starts with “en”, like “en-US”.
a[hreflang|=en] {padding-left: 20px;}
CSS3 allows for more complex matching patterns, including regular expressions, but these four should be enough to get you started.
Keep in mind that you can use multiple attribute selectors in a single declaration the same way you can use multiple classes. The following would hide the underline for anchor elements with a relationship attribute of external and a title attribute that contains the word “Clue”.
a[rel=external][title~=Clue] {text-decoration: none;}
Going back to the form markup I presented earlier, I was able to style the submit button without adding a class attribute by using the name/value attribute selector. I just targeted input elements with a type of “submit”, like this:
input[type=submit] {color: #fff; background-color: #cc6600;}
With CSS attribute selectors, the possibilities for precise element selection and styling really open up. Of course…
There’s always a catch
And you can probably guess what it is. Internet Explorer 6 doesn’t support attribute selectors. If you decide to use them, make sure your styles degrade gracefully. IE6 users should be able to access your content even if it doesn’t look the way you want.
The next time you need to style an element that seems out of reach, remember CSS attribute selectors. They’re a simple yet powerful option for precision styling.
How about you? How do you work with and style markup that’s less-than-perfect? Do you use attribute selectors on a regular basis or only in tight spots? Let us know in the comments.
About Jason Garrison
Jason is a freelance web designer and developer who has a healthy obsession with web standards. When he’s not knee-deep in code, you can find him in a meditative state communing with the universe.
9 Comments
Hello Jason,
I never knew that. Thank you for this great CSS tip. I absolutely love your tutorials, and your writing style is very easy to comprehend. Also, the site design looks great!
This is all new to me, I have never seen this being used any where.
Thanks for the post.
Wow! Awesome, I have never seen this before/had no idea you could do this. I’ve run into similar situations with Wordpress plugins that were difficult to style. Great reference article, thanks! :)
Really nice tips. I just can’t wait to play with attributes.
Yes, they’re awesome. But in reality you can’t use them because customers seem to almost always use IE6. So if it doesn’t look the way it should in their eight year old browser you’re screwed.
So I’m always looking for a workaround or IE6 compatible way and think to myself how awesome it would be with CSS.
Why can’t IE6 just die.
Keep in mind that Win/IE 7 does not support ALL attribute type selectors in CSS 3. Sadly only the basic ones. And I’m not sure about Win/IE 8 as well.
Thanks for your comments everyone.
Dennis – According to Microsoft’s IE compatibility chart IE7 and 8 support all attribute selectors in both CSS 2.1 and 3. Whether that’s the case in real life, I’m not entirely sure…
Working as a front end developer… I find CSS selectors very powerful way to achieve your desired output with CSS only :)
I always used to think about advance versions of CSS and here is the real avatar – CSS 3
Holy jumpin’. I never knew these existed. Thanks for the lesson!