A Harder-Working Class
14 Comments
Comments are ordered by helpfulness, as indicated by you. Help us pick out the gems and discourage asshattery by voting on notable comments.
Got something to add? You can leave a comment below.
Adrien Lavoillotte
Cobey Potter
Excellent article. I have been using the attribute selectors rather extensively in the last few projects we’ve been doing and have extolled around DC a bit about their awesome power (mini-REGEX).
Glad to see you did a speed test as well and came to some good conclusions.
One thing people should be aware of is when you write:
[class*=“pod”] it will choose both .pod-heading as well as .podium. Basically, you need to be pretty sharp on your naming conventions. To combat this, I’ve started namespacing using something like: [class*=“pod—”] (two dashes) to ensure it only picks up the right namespace.
Thanks for the article!
@pete_b
I’m a fan of this concept, though to technically nitpick it’s not robust enough to target css class prefixes by using the attribute sub-string selector alone.
Something more verbose like the following would be safer:
@[class^=“foo-”], [class*=” foo-”]@
Jacob Rask
It would be really cool if a preprocessor would add a simpler syntax for this.
@.pod*@ could translate to @[class^=“pod”]@ and @.*pod@ to @[class$=“pod”]@ and @.*pod*@ to @[class*=“pod”]@.
Gunnar Bittersmann
‘*=’ considered harmful, as ‘[class*=reed]’ not only matches all elements of the class “reed”, but also all elements of the class “freedom”. Use with care.
The equivalent to ‘.reed’ is ‘[class~=reed]’.
You’re better off matching the beginning with ‘^=’ or the end with ‘$=’.
http://www.w3.org/TR/selectors/#attribute-selectors
Wray Bowling
This is my favorite article for 2012’s 24ways. Well.. they’re all pretty awesome, but this one is so fundamentally empowering using a language that I thought I already knew. Wow.
Nathan Ford
@Cobey, @Pete, @Gunnar: Good points (though I am not sure this technique is harmful, just nuanced). In my examples, you will see that I also use dashes to namespace. I wanted to mention it, but I felt it might be going too deep for this introduction.
For those that may not be familiar with “namespacing”: you should use a dash (or other valid character in class names) as a separator between values you want to match. That way, you can use that character as a hook to make sure you do not unintentionally match other elements.
For example:
[class*=name] would match .name and .class-name, but [class*=-name] would only match .class-name
I shy away from using ^= and $= as they specify that the class MUST be at the beginning or the end, which you may not always have control over. Namespacing your classes seems more versatile.
The article I link to from Eric Meyer does a great job of explaining more about these nuances.
Carlo Rizzante
Very interesting, Nathan, thanks for sharing.
I run through the css of a project I’m working on, while reading bit a bit your post here on 24ways. I’ve to admit that I should rethink a little bit the whole in order to get more than a tiny improvement applying attribute selectors to the logic. And I’m doing it!
It’s great to discover and learn new things. Thank!
Matthew Irish
Great article, I’m excited to start using some of these techniques.
Could you make your tests available somewhere? I’d love to check those out as well.
Cheers,
Matthew
Nicolas Chevallier
It is very difficult to recover because the change in level is very important between using “traditional” CSS and use this new way, more logical but also harder to understand.
Paolo Priotto
And all the hassle because the [class|=pod] selector is so dumb. Why can’t it recognize “bar pod-bar” ? It does recognize “pod-bar bar”!
Anyway, I think as long as markup and styling are in one hand, you can pretty easily ensure (or even lint/hint/validate) that your module library classes (pod, pod-bar etc.) are always the first ones in the class string, and that your class string has no whitespaces. So I’m gonna go with this fine and overlooked selector.
Great article by the way!
John Macpherson
Great article indeed, i love the trick to increase specificity by chaining.
Also will now be using specific classes than elements for performance.
Best 24ways article this year for me!
Nathan Ford
@Matthew You can view the running results here: http://ncfwork.com/selectortest/
Pete Schuster
Pretty huge man. Definitely alleviates some of the “class soup” that people criticize OOCSS for. I plan on incorporating this technique in my workflow. Cheers!
Each advanced attribute selectors has its shortcomings, because of the potential multiplicity of class names.
http://codepen.io/joe/pen/Ilhsp
If you want to handle all cases, you end up with something that looks like this:
[class|=“pod”],
[class*=” pod-”],
[class*=” pod “],
[class$=” pod”]