CSS Selectors are an essential ingredient in developing websites. They’re the hooks our css has into our html. How may different css selector patterns do you regularly use?
If you’re like me the answer is not many. I have a tendency to stick to simple selectors like html elements, classes, and ids, but there are so many more to choose from.
I thought it would be a good idea to take a look at the 42 different selector patterns we have at our disposal so we can potentially use more of them and get away from classitis and an over reliance on making selectors ever more specific. Both can be enemies of maintainability.
This will take more than a single post so to prepare you for what’s ahead the plan is to cover:
- Attribute selectors — hooking into elements through html attributes
- Combinators — combining selectors to be more specific and more powerful
- Pseudo classes — elements we can target when certain conditions are met
We’ll cover the first today and continue with combinators and pseudo classes in the coming weeks. For the sake of completion let’s begin with a quick look at some simple selectors.
Simple Selectors
Simple selectors include type selectors, the universal selector, attribute selectors, class selectors, ID selectors, and pseudo-classes. We’ll save pseudo classes for the next post.
Note: Numbers in parenthesis indicate in which level of css the selector was introduced.
Type selectors (1) E matches any element of type E — We can use any element in our html as a selector. Most every css file created has a section for how html elements should generally be styled and simple type selectors form the whole of many css resets.
Universal selector (2) * matches any element — If there’s a style you want to apply to all elements this is the one to use. The universal selector was the first css reset as it was often used to give everything a default margin and padding of 0.
Class selectors (1) E.myclass matches an element with a class of myclass — any reusable set of styles on the page should likely be a class.
ID selectors (1) E#myid matches an element with an id of myid — any set of styles you want to use for only one element on a page should likely be an id.
I’m assuming you’re familiar enough with all of the above that little explanation is required. Let’s move on to attribute selectors, which you many not be as familiar with.
Attribute Selectors
Attribute selectors were first added in css2 and more are being added in css3. I have to admit that I don’t use these as often as I could or should.
E[foo] (2) — matches an element E with a “foo” attribute
{code type=html}
{/code}
{code type=css}
a[rel] {color: green;}
{/code}
Both links above would be green as both contain the rel attribute.
E[foo=”bar”] (2) — matches an element E whose “foo” attribute value is exactly equal to “bar”
{code type=html}
{/code}
{code type=css}
a[rel=”external”] { color: green;}
{/code}
Only the first link would be green since the value of its rel attribute is “external.”
E[foo~=”bar”] (2) — matches an element E whose “foo” attribute value is a list of whitespace-separated values, one of which is exactly equal to “bar
{code type=html}
{/code}
{code type=css}
a[rel~=”friend”] {color: green;}
{/code}
Again both links are colored green as both contain the value friend within the whitespace-separated list of values.
E[foo^=”bar”] (3) — matches an element E whose “foo” attribute value begins exactly with the string “bar”
{code type=html}
{/code}
{code type=css}
a[href^=”my”] {color: green;}
{/code}
The second link is green because it’s href value begins with “my.”
E[foo$=”bar”] (3) — matches an element E whose “foo” attribute value ends exactly with the string “bar”
{code type=html}
{/code}
{code type=css}
a[href$=”php”] {color: green;}
{/code}
Again the second link is chosen since it ends in php. This selector is probably a good way to target links pointing to a certain file type. I’m not sure if you’d want to style .jpg and .png images differently, though here’s a way to do that.
E[foo*=”bar”] (3) — matches an element E whose “foo” attribute value contains the substring “bar”
{code type=html}
{/code}
{code type=css}
a[href*=”page”] {color: green;}
{/code}
Both links will be green since both have href values that include “page” as a substring
E[foo|=”en”] (3) — matches an element E whose “foo” attribute has a hyphen-separated list of values beginning (from the left) with “en”
{code type=html}
{/code}
{code type=css}
a[rel|=”internal”] {color: green;}
{/code}
Only the second link is green here as it’s value begins with “internal.”
Multiple Attribute Selectors
You aren’t limited to a single attribute as part of the selector. For example
{code type=html}
{/code}
{code type=css}
a[rel~=”friend”][rel~=external] {color: green;}
{/code}
The above matches the first link and says to style any links to external sites run by friends as green
Attributes vs. Classes or IDs
One question you might have looking through the above is what advantage do attribute selectors have over classes and ids. If you have to add an arbitrary attribute to use the selector then none really.
However many elements in your html will have an attribute for other reasons.
Links will always have an href attribute and often a title attribute. Images will have an alt attribute. Form elements use the type attribute. There are already a lot of attributes in your html so why not take advantage of them where you can.
We may also be making more use of attributes in the future as a way to add html5 microdata to our pages. Again why not take advantage of them.
Browser Support
Outside of IE6, browser support for all of the above is good. You can check the links below for which browser and version supports which selector.
- CSS contents and browser compatibility
- CSS3 Attribute Selectors
- CSS selectors: basic browser support
- Can I Use: Selectors
- CSS3 Selectors Test
Summary
Selectors are a basic part of css syntax and they’re how we hook our css into our html. I’m sure you’ve used elemental selectors, class and id selectors, and perhaps the universal selector as well.
What you may not take advantage of is the attribute selectors. I know I don’t even while I know I should. Attribute selectors allow you to take advantage of code you’re already using instead of having to add arbitrary classes or ids to our html.
Next week we’ll run through combinators and some pseudo class selectors.
Download a free sample from my book, Design Fundamentals.
It’s great to know that someone will actually bother to read the specs and take the time to teach the rest of us! Thanks for the illuminating conversation – now if I could only remember them.
Glad to help DJ. I’m certainly not the only person who’ll read specs, but I will read them when trying to learn how the code works.
Funny, Yeah I’ll have to remember all these too and remind myself that I can use them. In think that’ll just require some practice.
Everything except “a[rel] {color: green}” spells green right. The rest are missing the e.
Thanks Odanomi. What’s strange is everything is spelled right on the admin side. I’m seeing the ‘n’ missing from most of the green in the code, but I swear it’s actually there.
I’m not sure why it’s getting cut off, but I’ll try to figure it out. If I can’t then green may become another color in this post.
Looking forward to the rest of the series.
Thanks Peter. The next post is coming Monday and I’ll finish up the Monday after that.
Great one :), Special thanks for the examples with description
Thanks Jezz. I’m glad you liked the post.
I am feeling kinda dumb now. After all the months of writing HTML and CSS code, I never came across using RegEx to select certain attributes. This is great! And who would’ve thought, that IE6 doesn’t support this. 😉
These aren’t actually regex. Just stuff built in to css.
What? IE6 doesn’t support something? That can’t be right. 🙂
I think the problem with a lot of selectors is the lack of IE6 support meant no one bothered to use them and are now forgotten. Plus the fact that many have such specific niche uses that by the time you ever come to one of those situations you just use a class and be done with it.
Having said that, input[type=”…”] is really, really useful.
Interesting point Scott. Maybe that is part of what happened. Some of it is also that there are so many different ways to select an element and we’ve all developed habits that take us away from attribute selectors.
Yes, I’ve been using them for quite awhile. Most assuredly handy and time-saving!
Great post on attribute selectors, Steve. Not many people know about them and it’s nice to see someone take the time to explain them. One thing that concerns me is that you did not address the poor performance of this type of selector. Granted, it’s generally not perceptible, but I think it should at least be noted. The order of performance is:
ID, e.g. #header
Class, e.g. .promo
Type, e.g. div
Adjacent sibling, e.g. h2 + p
Child, e.g. li > ul
Descendant, e.g. ul a
Universal, i.e. *
Attribute, e.g. [type=”text”]
Pseudo-classes/-elements, e.g. a:hover
More info can be found here: http://csswizardry.com/2011/09/writing-efficient-css-selectors/
Good point Chad. I had meant to link to a post about the performance of these selectors and guess I forgot. I may end up writing something after I get through this short series on selectors about performance and other general thoughts.
I agree with you that even if it the performance hit is small it’s still worth talking about and understanding.
Thanks for the link.
This method seems much more practical than finding an alternate (jQuery or other) way to add an id or class to the element you’re trying to style. Thanks for bringing up this bit of CSS many of us overlook.
Great post! I really appreciate the examples. I am going to play around with these attributes to deepen my understanding and usage of them in the future.
Thanks! The things I learned with your article will safe me a lot of time in the future!
Keep it up and coming 🙂
> “Attribute selectors were first added in css2 and more are being added in css3.”
Attribute selectors are freely used. You can use any attribute you want. Even when it’s not ‘valid’. I don’t think a new CSS version adds new attribute selectors, because you can already use all of them. Right?
You’re right Rudie. Probably not the best wording on my part. It’s more the specific pattern that was added, so being able to target an element with an attribute or with an attribute equal to a specific value. You still get to define the attribute and value.
Another great article, Steve. Just finished the series (in reverse order). Learned a lot. Thank you.
Thanks Michael. Other than the occasional reference to an earlier post I don’t think you miss anything reading them in reverse order.
I’m glad they were useful.
I found this guide helpful while I’m getting my feet wet in CSS. Thanks!
Thanks Meredith. Are you enjoying the summer sun and heat after all the rain we had in the spring?
Thanks a lot for sharing, very good guide.