The Skinny on CSS Attribute Selectors

CSS has the ability to target HTML elements based on any one of their attributes. You probably already know about classes and IDs. Check out this bit of HTML:

<h2 id="title" class="magic" rel="friend">David Walsh</h2>

This single element has three attributes: ID, class, and rel. To select the element in CSS, you could use an ID selector (#first-title) or a class selector (.magical). But did you know you can select it based on that rel attribute as well? That is what is known as an attribute selector:

h2[rel="friend"] {
/* woohoo! */
}

There is a lot more to attribute selectors though, so let's look closer at all the different options and try to cover some "real world" scenarios on when they might be useful.

Attribute Exactly Equals Certain Value

In the example we used above, the attribute of the h2 element was "friend". The CSS selector we wrote targeted that h2 element because it's rel attribute was exactly "friend". In other words, that equals sign means just just what you think it does... an exact match. See another basic example:

<h1 rel="external">Attribute Equals</h1>

h1[rel="external"] { color: red; }

A great real world example of this is styling a blogroll. Let's say you had a list of links to friends sites like this:

Then you wanted to style each link slightly differently. The traditional way would probably be to give each link a class name in which to target, but that requires additional markup which is always a nice thing to avoid (semantics and all). Another way might be to use :nth-child, but that requires their order to never change. This is the perfect use for attribute selectors... the links already have a unique attribute in which to target!

a[href="http://perishablepress.com"] { color: red; }

I believe the most common use of regular attribute selectors is on inputs. There are text, button, checkbox, file, hidden, image, password, radio, reset, and submit (did I miss any?). All of them are <input>'s, and all of them are very different. So doing something like input { padding: 10px; } is a bad idea most of the time. It's very common to see things like:

It's really the only way to get your hands on certain types of inputs without screwing up the others and without adding extra markup.

Note on Quotes: You can usually get away without using quotes in attribute selectors, like [type=radio], but the rules for omitting quotes are weird and inconsistent across actual browser implementations. So, best practice, just use quotes, like [type="radio"]. It's safer and always works.

Attribute Contains Certain Value Somewhere

This is where it starts getting more interesting. The equals sign in attribute selectors may be prefaced by other characters which alter the meaning a bit. For example, "*=" means "match the following value anywhere in the attribute value." Look at this example:

<h1 rel="xxxexternalxxx">Attribute Contains</h1>

h1[rel*="external"] { color: red; }

Remember that classes and ID's are attributes too, and can be used used with attribute selectors. So let's say you were writing CSS for a site where you couldn't control the markup and a sloppy developer had three DIVs you need to target:

Attribute Begins with Certain Value

<h1 rel="external-link yep">Attribute Begins</h1>

h1[rel^="external"] { color: red; }

A real world example of using this would be, say, that you wanted to style every single link to your friends site different than other links. Doesn't matter if you are linking to their homepage or any subpage, any links to them you want to style up.

a[href^="http://perishablepress.com"] { color: red; }

That will match a link to their homepage, but also any other subpages as well.

Attribute Ends with Certain Value

We can select based on how attribute values begin, why not end?

<h1 rel="friend external">Attribute Ends</h1>

h1[rel$="external"] { color: red; }

A good use case for these is labeling file download anchor links with icons based on what type of file they are. For example, PDF's get a PDF icon and Word Documents get a Word icon:

Attribute is within Space Separated List

You probably already knew that you could apply multiple classes to elements right? Well if you do that, you can still use .class-name in CSS to target any one of them. Attribute selectors aren't that easy. If your rel attribute has multiple values (e.g. values in a space separated list) you'll need to use "~=":

<h1 rel="friend external sandwich">Attribute Space Separated</h1>

h1[rel~="external"] { color: red; }

You might be thinking, why would I use this when *= would also match this and be more versatile? Indeed it is more versatile, but it can be too versatile. This selector requires the spaces around the value where as *= would not. So if you had two elements one with rel=home friend-link and one with rel=home friend link you are going to need the space-separated selector to target the second one properly.

Attribute is the start of a Dash Separated List

This will select if the start of a dash-separated list of attribute values matches the selector.

<h1 rel="friend-external-sandwich">Attribute Dash Separated</h1>

h1[rel|="friend"] { color: red; }

Note that even though it matches based on the start of the selector, the entire first part of the string before the first dash needs to match. So in the above example, if the rel attribute was friend2-external-sandwich, it would not be a match while the ^= attribute selector would have.

Multiple Attribute Matches

Vital to note is that you can use multiple attribute selectors in the same selector, which requires all of them to match for the selector itself to match.

<h1 rel="handsome" title="Important note">Multiple Attributes</h1>

h1[rel="handsome"][title^="Important"] { color: red; }

Browser Support

Every single example above works in all modern browsers: Safari, Chrome, Firefox, Opera, and IE. Internet Explorer has perfect support for all of these down to version 7, but zero support in 6. To test in your browser, see the test page. If the line/selector style is in red, it works.

Share On

Comments

Awesome Chris – I never knew that. I will definitely be using this method more in future! Strange, I’ve never seen a website use this form of code in style sheets either. Maybe it isn’t as well known as we expect.

Quickly target all external links using CSS. Love it! Also, saw your name on the front cover of .net today and nearly feinted… I would have bought it (it’s a great zine), but didn’t have time as I was at the train station.

Thanks so much for this article, it’s proved to be a massive timesaver!

I’ve used these tips to create a stylesheet targeting <a> tag attributes, that I now apply to large webpages I’m marking up. The CSS applies different background colours to links depending on a huge number of conditions, e.g.

This means when I’m checking these massive web documents against the plain Word document the client originally sent, it’s immediately apparent which <a> tags require attention AND what needs to be done. You can use the same technique to target any HTML element.

Hope you read this Chris, but I’ve been hardcoding the target attribute in all my links. I really don’t see a problem with this, and won’t get into the whole debate, but should I start using rel=”external” and such?

I think most usability engineers agree on the fact that no link should ever launch a new window, because that makes a choice that really is up to the user and more importantly because it breaks the back button.

Thanks, Chris, for another application of regex. CSS becomes more dynamic every time I look. These examples will come in handy. My only nitpick: “There is a lot more too attribute selectors” uses the wrong homophone.

Hey, how about using http://code.google.com/p/ie7-js/ ? Ofcourse, it could slow down everything, but it’s the price ie6 user will pay :) And i think this time it’s not something like rounded corners, which you can ommit, it’s usability at sake, and we should provide it even to those ignorant IE users :))

It would be nice if you could use != for ‘not equal’. Since WordPress uses the http: for all links you can’t use a[href^=http://] to target external links. However it would be nice if you could do something like: a[href!=http://css-tricks.com] instead.

I picked up the book “Advanced CSS” last week and they talk about a lot of these advanced selectors we don’t know (or think about) It’s amazing how powerful some of these selectors are, yet most of them aren’t used very often anywhere.

Great explanation of the different CSS attribute selectors. These are not something that I have used in the past out of shear ignorance of when or how to use them. This is a huge help and I see that I will be making use of this much more in the future.

I’ve never thought of doing things this way, never even crossed my mind to fall away from using classes etc. Is it cross browser friendly? There seem to be some people saying yes some no! Would be interesting to run some browser testers on all the different variations.

It’s not working for me in internet explorer 7. I’m working on a site where we’re have lots of logos displayed for informational purposes. One of the logo owners want’s theirs taken down until we get licensing. So instead of re-writing back end code, I tried this to remove the logo for this case only.

div.foo .bar[style*=xyz] {
background-image:none !important;
}

Does not remove the background image in IE7. I have to use !important because it’s an inline style that adds the background (I know that’s not separating content from style, but worked better this way for programming).

CSS Attribute selectors are great and use them everyday, though i didnt know about the “in dashed” and “in space delimited” variations. Thanks for the tips.

However, you missed on something extremely important. IE7 can be crashed with a specific selector. Yup you heard me right. Just place the following CSS either in your page or style sheet and it will take down IE7 without even logging a windows event regarding the crash.

Fully agree that using rel is better than introducing a new class, however I do have to nitpick a little.

In the real world, most of the time you are not saving any markup. In my experience, almost no links have the rel atttibute in place. So by not using classes and switching to rel you are only switching one attribute for another. Conceptually much better, but there is no real saving IMHO.

By introducing the rel attribute you are killing two birds with one stone. You can remove the target (assuming you are using rel=”external”) and you are styling external links, which is much more efficient than having <href=”#” rel=”nofollow”>. Again, preventing yourself from introducing a new class and allowing yourself to remove the target attribute.

What I think he was getting at was not just for links but for anything like H1 or img tags as well. Instead of using class=”” you are only basically switching it for rel=”” in which case doing it purely to reduce markup is redundant. However using this to select specific tags based on their attributes is what Chris was hinting at. Especially good for forms IMO. instead of giving each tag it’s own class to target it you can do it by input[type=text/submit/button] etc. Which is where it comes in handy.

For “Attribute Ends with Certain Value,” I often find myself using that to style certain links based on their filetype.a[href$=pdf] { padding-right:16px; background: url(/images/icon_pdf.gif) top right no-repeat; }

A perfect real world example of ‘h1[rel$=external]’ (matching the end), is one I just did after reading your post. I used it to style pdf download links with a pdf icon: a[href$=pdf]. Works an absolute treat. Cheers!

I’d been aware of these for a while, but they were one of those CSS things that I generally ignored as not being cross-browser enough. But I see it’s only IE6 now that doesn’t support them, which I’m starting to ignore now, so I’m going to have to start playing about! Thanks for the kick up the backside.

I’ve been using this for some time, but only in JQuery because the lack of support in IE6 … yes, I hate ie(6) as much as the rest of you, but I do want everybody to see the same website …

Hey Chris,
I don’t know you already had this poll, maybe this would be a good one:

Webdevelopers should make there websites …
1. the same for every browser (mobiles excluded)
2. degrade nicefully on older browsers
3. webdevs should give a rats ass for browsers that aren’t even supported anymore by there own developers (like IE6)

I’m currently using time[datetime*="01T"] through time[datetime*="31T"] to set the background-position of a calendar icons sprite for each post listed in the David Chambers Design archives. I love using attribute selectors to keep my markup free of unnecessary class names!

The Rel$=external could be very useful for recognizing file types. For example, if you have links to PDF’s and normal webpages, you could place icons in front of the links to show that it is a web page or a pdf, because you will know the link ends on .pdf or not.
Quite a useful example in the real world I guess

This comment thread is closed. If you have important information to share, you can always contact me.

Treehouse is where you go to learn HTML, CSS, and how to build iOS apps. It's a complete education in modern web and app technology, designed to get you ready for a hot new job or to kickstart your own business.

The Lodge is a member login only area with access to video training on how to build websites from scratch using the best modern tools.

How many people touch the CSS in your current main project?

What now? I have some ideas for you.

Go explore CodePen!

As a front end designer and developer, you should have an account on CodePen so you can save your snippets, present your ideas, and engage with the rest other front end folk. I'd encourage you to go PRO as well, to unlock the full power of CodePen.

Get the newsletter!

You should sign up for the CSS-Tricks newsletter. It's a clean copy of all the blog posts each week, combined together, right to your inbox. If email isn't your thing, there is an RSS feed, iTunes, and lots of other ways to subscribe.

Listen to ShopTalk!

Subscribe to The Lodge!

The Lodge is a members-only, ad-free video learning area here on CSS-Tricks. Just like the free screencasts, but organized into four large complete series. Membership is also the #1 best way to support CSS-Tricks.

We can do the real footer now.

Site Links

Colophon

CSS-Tricks* is created, written by, and maintained by Chris Coyier. It is built on WordPress, hosted by MediaTemple, and the assets are served by MaxCDN. The fonts are Source Sans and Source Code Pro. It is made possible by viewers like you who subscribe to The Lodge and through advertising for products and services I like.