A few weeks ago in the comments on my post about css formatting, Brett and David pointed me to a couple of articles and a presentation I hadn’t yet seen. All had interesting ideas about css practices and I thought I would offer some of my thoughts on them.
One of the articles, Donโt use IDs in CSS selectors?, makes the argument for using classes over IDs as css styling hooks. Since I covered another article with similar of arguments I won’t cover Oli’s article here, but would recommend you give it a read.
In this post I want to talk about a presentation Brett pointed me to. I’ll get to the article David pointed me to next week. The presentation is one give by Jeremy Clarke on the topic of DRY CSS.
DRY CSS Principles
I wasn’t quite sure what to make of Jeremy’s presentation. I’ve seen some of his other presentations and generally like both Jeremy and his ideas. He’s certainly worth listening to. While I agree with the basic principle of don’t repeat yourself, I found myself unsure of the methods set out in the presentation and if they really solved the problem we’re trying to solve.
Some of my doubt is probably due to a lack of practical application on my part so keep that in mind. Let me walk you through Jeremy’s DRY ideas and then point out what I did and didn’t like about them.
If you’re not familiar with DRY, it stands for don’t repeat yourself, which is hopefully something we can all get behind. It’s why we want variables and functions. Many are moving to css preprocessors for this reason though Jeremy doesn’t seem to care for them He suggests they lead to destandardization and dependence on external libraries. I’m not sure either is really true.
Jeremy offered 2 principles for writing good css.
- Keep style separate from content
- Avoid specificity by harnessing the cascade
These should look familiar as they’re essentially the same principles of OOCSS and SMACSS. However Jeremy sees IDs and classes a little differently. He thinks IDs are fine for styling hooks and that both should be named based on the content as opposed to how the content looks.
This goes against what Oli says in the article linked to above and the one I covered a couple weeks back by Nocolas Gallagher, both of whom say it’s fine and preferred to name classes after how an object looks and suggest we skip using IDs for styling hooks
So how does it work?
How DRY CSS Works
DRY CSS comes down to 3 things:
- Group reusable css properties together
- Name these groups logically
- Add your selectors to the various css groups
Each group should be defined by shared properties. For example one group might describe the background color and border color for a content box used throughout your design while another might describe a consistent set of type characteristics used throughout your design.
Each property/value pair should be defined only once, though in his code examples Jeremy does repeat pairs. Each group would also get multiple selectors. I think this makes more sense with an example and here’s one Jeremy used in his presentation.
Group reusable properties — Below we’re simply grouping a couple of background and border colors that would be used in a number of places across the site.
{code type=css}
{
background-color: #fff;
border-color: #ccc;
}
{
background-color: #fff;
border-color: #bbb;
}
{/code}
Name groups logically — I’m not sure these are great names and Jeremy was quick to point out they could be better, but hopefully you get the idea.
{code type=css}
#LIGHT-WHITE-BACKGROUND,
.light-white-background
{
background-color: #fff;
border-color: #ccc;
}
#MEDIUM-WHITE-BACKGROUND,
.medium-white-background
{
background-color: #fff;
border-color: #bbb;
}
{/code}
The all caps ID is to make this block of code easier to find in Firebug, which doesn’t show comments. The lower case class at the end is to enclose the selectors that will later be in between and to make it less likely you forget the commas at the end of all but the last selector rule. I wasn’t crazy about creating extra IDs and classes that really exist for a lone developer tool. I’d prefer comments above and below the group.
Add selectors to various groups — With groups defined and named, you add all the selectors that need to be displayed with the property/values of the group.
{code type=css}
#LIGHT-WHITE-BACKGROUND,
.translation,
.entry .wp-caption,
#full-article .entry img,
.recent-comment .comment-text,
.roundup h3,
.post-header-sharing,
#post-categories td.label,
#post-archive roundup h3,
.subscription-manager ol,
.light-white-background
{
background-color: #fff;
border-color: #ccc;
}
#MEDIUM-WHITE-BACKGROUND,
textarea:focus,
input:focus,
#author-email-form .input-focus,
#respond p input:focus,
.wpfc7 input:focus,
.medium-white-background
{
background-color: #fff;
border-color: #bbb;
}
{/code}
The above is a simplistic example for the sake of demonstration. The general idea is to think in terms of style patterns. You have a box in your design that holds content. You write the styles necessary to create it visually and place them together in a group. You give the group a name, and then add the css selectors that will visually be displayed using the pattern.
One of the questions I immediately had was would all these selectors really be needed? What advantage does this offer over having each group be a class that’s added where needed in the html. Sure it would reduce the need for classes, but is that a bad thing?
I’ve mentioned a few times in recent posts that it’s really about coupling and have pointed to some articles showing how a class couples css and html less than the descendent selectors that are being used here.
Additional Thoughts
Throughout the presentation Jeremy mentions some of the benefits of his DRY approach. Here are a few of them along with some of my thoughts
It encourages you to think in terms of style patterns (groups) rather than individual objects. I agree. I think this is a good goal and is also encouraged by OOCSS and SMACSS
The naming of groups encourages rational organization of design. I’m not sure about this. The examples didn’t feel all that organized to me with so many selectors in each group. I think it would make it more difficult to find the selector you want.
It encourages optimization and generalization of selectors. Again good goals and I think DRY CSS would help accomplish this.
It doesn’t require changes to html. True to an extent, but is this really more beneficial? I no longer thing so, though I know many do.
There shouldn’t be any performance issues. I think we’d be dealing with whatever performance issues we deal with now as part of using descendent selectors. I think jeremy quickly glossed over any potential downside here, though I don’t know that css selector performance is something most of us need to be overly concerned with.
DRY and OOCSS
Jeremy tried to show how DRY and OOCSS were compatible. He points out that the basic principles of both are mostly the same and that you can group styles in a way that adheres to OOCSS ideas. I’m not so sure this is true as the use of decedent selectors goes against OOCSS. Essentially DRY is replacing a single class with a variety of descendent selectors so as not to have to alter the html.
In the case of DRY when you want to change the style of a content box, you’d cut and paste it’s selector in the css from one group to another. In OOCSS you’d change a class name in the html. In either case you might need to define or redefine some styles.
Is one approach better than the other? To me using classes as in OOCSS seems a lot cleaner, easier to read, and more flexible. I’ve also become convinced that classes reduce coupling which is the real enemy here.
However if you’re someone who disagrees and thinks adding classes everywhere is the wrong approach you might want to give DRY CSS a look as it offers many of the same advantages of OOCSS in a different way.
Without having used either in practice to any great degree it’s hard for me to authoritatively state one approach is better than the other, though my sense is OOCSS is the better approach. Again I’m convinced that classes reduce coupling and are preferred. I also think OOCSS more readable.
presentations from Jeremy Clarke
Summary
Overall I think the basic ideas behind DRY CSS make sense. Don’t repeat yourself is a good general principle to follow and eliminating duplication of css code should naturally be part of that.
DRY CSS shouldn’t be too hard to understand if you followed the example code above. Create the groups, name them, and then add the selectors.
The main difference I can see between DRY and either OOCSS and SMACSS is that the first continues to use the same descendent selectors we’ve been using for years, while the latter two ask us to make greater use of classes. I think the class approach the better one and so I probably won’t be using DRY CSS in practice.
Not everyone agrees with the class approach though, and if you’re one of those people then I think you might enjoy DRY CSS. It aims trying to achieve the same basic goals of the class based approaches. I can certainly see the appeal of writing css this way.
Have you used DRY CSS? What to do you think? Do you prefer it to moving toward more class based css?
Download a free sample from my book, Design Fundamentals.
Hey man, thanks for doing such a detailed writeup of the talk. I’m glad you got the main gist of it all and thought it mostly made sense.
A couple of things that I’ll emphasize ’cause as you can tell I’m a verbose dude:
The fact that DRY doesn’t make you edit HTML is most direly needed (rather than philosophically desirable) when you are working with HTML that you don’t control. In WordPress/Drupal land it can be an enormous, complex pain to insert classes into the output without hacking the core files (which you should never do). This actually makes me wonder how anyone could faithfully use OOCSS with WordPress. Sure maybe it works if you are building an app from scratch or using a loose framework, but all the most popular CMS do some stupid things with HTML, and I’m not really interested in implementing a CSS methodology that completely ignores the issue. Without this consideration my argument that editing HTML sounds a lot less convincing.
ย I agree that people shouldn’t use ID’s in their CSS if they can avoid it. That’s a principle of OOCSS that I can totally get behind. My examples have ID’s in the selectors but they are mostly either legacy from before I started thinking about it, or caused by WordPress not using classes (thus beyond my control). The only IDs I encourage as part of DRY CSS are the names at the top of groups, which are totally outside the actual choosing of selectors ๐
The same goes for descendant selectors. That’s exactly what I talk about when I say harness the cascade and be general. If my examples have definitions that are too-deep it’s just another case of legacy CSS that I wrote a long time ago or WordPress+plugins giving me no other choice. Ideally you’d apply the same cutthroat approach recommended by OOCSS and have almost nothing but single classes as your DRY selectors, though IMHO you should still make those classes semantic!.
Your article is the most poingant example I’ve read so far of the biggest issue with my talk: I used the CSS file from an enormous 7-year old site with hundreds of features and hundreds of thousands of articles. I should have done like the examples most people use and created a simple demo site that emphasized the system as neatly as possible. Anyway, please don’t judge DRY by my crappy CSS!
Thanks for stopping by Jeremy. If I didn’t make it clear in my post let me say I enjoyed your presentation as well as a few others I’ve seen. Don’t worry about the verbosity. You can see I’m the same way. ๐
I can’t speak to Drupal, but is it really true that you can’t edit the html without hacking the core? I do it all the time. There are a few places where the html has been hard coded into the core somewhere, but not a lot. You have direct access to your theme files and you have access to your content. I’m not sure where in WordPress you can’t access the html.
My bad about on the ID thing. I know the code you were showing in the examples came from an existing site and wasn’t meant to be ideal. I guess I saw IDs in there and drew the wrong conclusion. I realize you said early on the presentation that the css wasn’t ideal and I also know what it’s like when you need an example. Sometimes you grab something that probably isn’t the best, but it’s what you have at hand.
No worries. I promise I won’t judge DRY by your css examples from the presentation. I think the whole concept is interesting. I’m still leaning toward classes, but you’ve made me think a lot about this. I’m certainly not against DRY at all.
Thanks again for the comment.
Thanks for this great detailed post about the talk of Jeremy.
Oocss + DRY + SMACSS + Sass are the core tools and principles I use daily.
This methodology is achievable with preprocessors like sass and stylus, this is why I love using them. With @extend, you can easily group selectors, be DRY and keep things in context..
This is great for maintainability. I actually wrote a whole book about that, if you can read French I’d be glad to send you a copy.
Thank Jeremy. He did the hard part. All I had to do was watch his presentation and take notes while I did. ๐
How do you find OOCSS, SMACSS, and DRY work together? They all have similar principles at their core, but it strikes me that each does things differently enough that you can’t use all of them together. Do you use parts of each and mix some of their ideas a little?
I’m still trying to wrap my brain around a few of these things as you might guess.
Look at slide 9, then look at the article again, look at slide 9…
One should never name classes by how the are formatted, think of the situation when you want to move from light-grey to light blue.
Very bad example…
Agreed. I don’t know if you watched the presentation, but many (maybe all) of these examples came from an existing site and I think Jeremy had to work with what was already there. He mentions early in the presentation that these aren’t great class names and that we shouldn’t focus on them over the ideas behind DRY. I don’t think he would use these names in developing a new site.
Agreed. What is the difference between these two snippets?
1.
2.
Absolutely nothing. Both are incorrect.
Doug, the snippets never came through. WordPress ate them. If you want to email me the snippet, I’ll add them back to your comment.
I only read the article, first impressions count… People might copy and paste or pay more attention to the examples that the details. And if the author hasn’t paid attention to these details or not followed his own recommendations I have to doubt the validity/quality of his statements.
Fair point. In Jeremy’s defense he didn’t write an article and post code. The examples are part of a presentation and not copy/pastable. They also clearly apply to a specific site so realistically no one could copy and paste his code into a real project.
In my defense since I did make things copy and pastable, again this code is so specific to one site that it wouldn’t be useful and I did question the the exact css used in the examples.
I know people grab code from sites and paste it into a project without reading the details around the code. I’ve done it myself at times. If the code doesn’t work in those cases I don’t think it’s the author’s fault. It’s on us in those cases for not taking the time to read the details.
I do agree (and I’m sure Jeremy does too) that the specific css in these examples isn’t ideal. A better example could have been chosen, but this article and the original presentation aren’t about the example. Both are about a set of underlying principles and I think anyone reading or watching can understand those principles even with the existing example code. But yes, the example code could be better.
We can separate structure and skin (the OOCSS approach) with any preprocessor, but Sass makes it even DRYer thanks to @extend.
Sometimes, you don’t want to end up with too much classes on your html elements (1 to 5 is okay, 10 may be too much). That’s where you want to extend a common class (ie. : a class for a CSS gradient, rounded cornersโฆ). This way, the CSS output is much lighter.
Same applies for OOCSS modules and SMACSS states : we can reference the parent selector with &.
I like to use parts of those approaches that fit my workflow and makes it more productive, elegant & maintainable.
No approach is fundamentally better than an other, we should just go with what can improve our workflow so we become better developers who can make clients (or bosses) happier.
Thanks Kaelig. That all makes sense to me. I guess it’s more about following the underlying principles all these different techniques share. We want to do better at separating structure and skin and we want to do better and making selectors less location dependent.
All of these techniques do that it in similar ways and like you said none is fundamentally better. They’re all looking to solve the same basic problems.
Thanks. I appreciate the extra info.
Excellent article on improving the quality of css code.thanks
DRY CSS has it’s own pros and cons, ones that should be weighed as you are developing a site. I wouldn’t recommend building a site solely with DRY CSS but I also wouldn’t recommend building a site solely with OOCSS. Each have areas where they will be more usefully.
In terms of Jeremy Clarke’s DRY CSS approach, one place I use it is when I am using a custom web font. Rather than writing font-family: ‘Droid Sans’, sans-serif; over and over in my style sheet each time I want to use it, or creating a class, “.droid-sans” and adding that to each element I want droid sans on, I use the DRY CSS approach and declare font-family: ‘Droid Sans’, sans-serif; once. Then chain my selectors with which elements I want to use that font.
h1, h2, .sub-title, label{font-family: ‘Droid Sans’, sans-serif;}
To me this is very efficient. My css is simple and DRY. If I had gone the OOCSS approach and added a .droid-sans class to all my h1, h2, .sub-title, and label elements, it would not make much since if I later decided to use a different font, say Oswald. This could be alleviated somewhat by abstracting my class name more, maybe instead of .droid-sans, I could use, .font-face1.
Another benefit of DRY CSS is that you only have one file to update. Rather then needing to pull down an HTML or PHP file and the CSS file to update your styles, you can just pull down your CSS file. This is a minor benefit, but it will save you time in the long run.
There are also times where DRY CSS can get out of hand. Stephen Tudor has an example about how using the @extend method in SASS to extend a clearfix class can get out of hand. Look at case 2 in the link below.
http://smt.github.com/blog/2011/07/09/responsible-sass-authoring/
Another issue people may have with DRY CSS is selector performance when you have so many selectors for one rule. http://smacss.com/book/selectors#comment-416997913
Johnathan Snook says, “The browser creates a lookup table of selectors and looks through the entire list. You’re creating a little overhead but it’s one of the fastest things that the browser has to do. That means that a long list might end up taking 2ms instead of 1ms. In other words, don’t worry about it.”
I think the best approach is knowing when to use one technique over another. Projects don’t have to be solely built with one CSS approach, and can often benefit from a blend of approaches. I often find myself using a blend of Johnathan Snook’s SMACSS approach and Jeremy Clarke’s DRY CSS approach on my projects. It’s about knowing which tool is right for the job. Work smarter, not harder. I think you’re spot on with wanting to do better at separating structure and skin and wanting to do better and making selectors less location dependent. Looking forward to more of your articles on this topic.
Thanks Brett. As I’ve been going through all this methods I’m coming to the the same place you are. Each has some good stuff to take, but I don’t think I’d follow any of them exclusively. To me it’s more about understanding the underlying problems they attempt to solve and picking your solution to that problem.
I’m still making up my mind about using a chain of selectors vs using a class. I can see benefits to both approaches. I’m leaning toward classes, but I’m still early in experimenting with all this stuff and slowly working it all into my practice.
Thanks for the links. The first I just added as reference for a post I’m hoping to get to.
I completely agree that it’s about knowing when to use one technique over another. I know even after going through all these different practices I’ll still be confronted with decisions that require more than blindly following one method. Part of the reason why I’ve been looking at all these different approaches is to add more techniques to my bag.
Ok, what I’m gonna say now is not unique in any respect, but still. It all depends on how you got used to work. As we know old habits die hard… So, whatever works for you may just be too bad for another person. There’s no accounting for taste. Nuf said ๐
Very true about habits. They don’t die easily. Part of why I wrote this and some related posts was to help break me out of my own habits. A small change here and another one there and you can guide your habits toward better ones.
Alex, you’re basically right, but I think that if you try hard enough, you can (and should) kill your old habits because you yourself win if you do that. Perhaps, you should (from the very gitgo) decide what is good and what is bad in terms of your CSS habits.
And guys it really looks that the conversation is moving towards philosophy rather than CSS or whatever ๐
I agree, though instead of killing old habits I try to modify them into newer and better habits.
I code therefore I am. ๐
This is interesting, and very different from later approaches. I had just read Jens Meier’s article on DRY and code optimization* and for him, the key to CSS optimization is to use “every declaration just once”.
Has more changed since?
* http://meiert.com/en/blog/20141009/css-dry-and-optimization/
I have a question. I have a lot of elements with
width: 100%;
Should I create a class only for one declaration like this:
.fullWidth
{
width: 100%;
}
And use it anywhere I need to?
You could certainly do that. I can’t say what you should do though. That depends on the rest of your code. I would think there’s a better way to set your elements to 100% width than using a class, but I’ve written classes before that do one thing and then assign the class where I want in my HTML.