One principle of object oriented design that I’ve been wanting to talk about is the single responsibility principle. It’s not an isolated principle, but rather one of five principles grouped under the acronym SOLID. Together these principles aim to help developers create systems that are maintainable and extendable.
Let’s continue what we started last week and again look to object oriented concepts to see if and how we might apply them to the design of websites. In this post we’ll take a look at the first two SOLID principles and next week we’ll continue with the remaining three principles.
Once again allow me to remind you I’m hardly an object oriented programmer and I’m bound to get a few things wrong in this discussion. Fortunately for me others have previously covered this topic in a similar fashion and I’ll be leaning heavily on their work.
- SOLID CSS
- The single responsibility principle applied to CSS
- The open/closed principle applied to CSS
The 5 SOLID Principles
Here are all five SOLID principles. They were introduced by Robert Martin with the acronym being coined by Michael Feathers.
- Single Responsibility Principle — objects should have only a single encapsulated responsibility
- Open/Closed Principle — objects should be open for extension, but closed for modification
- Liskov Substitution Principle — objects should be replaceable with instances of their subtypes without introducing problems
- Interface Segregation Principle — many client specific interfaces are better than one general purpose interface
- Dependency Inversion Principle — objects should depend on abstractions and not concretions
Again we’ll look at the first two and how they apply to css in a little more detail below and then look at the remaining three next week.
Single Responsibility Principle
The idea behind the single responsibility principle (SRP) is that every class should do only one thing and do it well. Here class means class in the object oriented sense, but I think we can apply the principle to css classes as well.
SRP calls for more classes with less code inside each.
Trying to do multiple things usually leads to doing none of them as well as possible. It also means that modifying one part of the code could have adverse affects on unrelated parts of the same code.
This idea has been central to the entire discussion of modular design we’ve been having the last few weeks. You break things down to their smallest chunks in order to improve them independently of other chunks and to be able to combine them more flexibility.
Harry Roberts, one of the people I’m heavily leaning on here, offered a good example of a class most of us have probably used that follows SRP. Have you ever done something like the following to fix and center a web page?
margin: 0 auto
The code above follows SRP, because it only does one thing. It’s not also setting backgrounds and borders or anything else. The purpose of the class is simply to group everything inside it. Here all it’s doing is centering that group of elements.
Unfortunately most of us don’t carry out this principle throughout the rest of our css. I know I don’t. Here’s a bit of css from this site for styling blockquotes.
The code is doing 3 different things (and not just because there are 3 lines of css). The first line is affecting the box model, the second affects color, and the third deals with type. Each would be better in a separate class according to SRP, since they all have different responsibilities. The following would adhere to SRP since both lines affect color and share a single responsibility.
Following the single responsibility principle should help us separate structure from skin and help us decide what to abstract from a given visual pattern. Colors would go in one abstraction, dimensions, in another., and type in yet another. Instead of placing every property for particular class or element selector, we should divide our css into groups of properties that affect different things.
You can check this list of css properties on HTML Dog to see other potential groups and some of the specific properties that would be included in each.
As defined by SRP, responsibility means a reason to change. Looking at the list above if we only include properties that affect type in one class then the only reason that class needs to change is because we’re making typographic changes. We wouldn’t need to change the class because our color scheme is changing.
If there’s a downside it’s that SRP will lead to an increase in how many classes we add to our html. If I were to separate responsibilities in the css on the blockquote I showed above, I’d be adding 3 different classes to style them. Of course, those classes wouldn’t be specific to the quote and could be used across the site.
Overall SRP calls for more classes with less code inside each. Ideally that will lead to more cohesive, reusable, and independent classes. Taken further it could lead you to write separate stylesheets, one for each responsibility.
The idea with the open/closed principle is that once a project is stable and working, making a change to a base class could introduce a lot of unexpected errors, because so much was counting on that base class to do what it was doing. Stated another way the idea is that new functionality should be added with minimal changes to existing code.
Have you ever had to modify a site you didn’t develop or maybe one you developed long ago? You make a change in the css you think will be simple only to find the site completely broken after the change? That’s an example of this principle not being followed.
Say you define a font-family on the body in your css. Later you decide that headings in the sidebar should use a different typeface. You wouldn’t want to change the font set on the body, because it would affect a lot more than the sidebar headings.
We naturally avoid doing that by adding a class or using some kind of descendent selector to target only the specific headings we want to change.
While it’s fine to fix errors in the base class or improve performance, you should only modify the class with new features by extending it with another class. The use of subclasses and chained classes would work well to follow this principle.
Ideally we’ll make good decisions about the abstractions we set up as base classes, but once chosen we should stick with them. Changing them requires changing all that depends on them. This is an argument against styling the most generic selectors. The more generic, the more they’ll html they potentially affect down the road. A change in css we add to the body affects everything across a design.
As I mentioned last week please don’t take anything here as me suggesting css or html are object oriented languages. Also accept my apologies if I misinterpreted the principles above or applied them to css in a way that makes little sense. These posts are learning experiences for me.
I’m sold on the idea of writing more modular html and css and trying to better understand how to do that. Object oriented programming would seem to offer some help and so I’m giving it a look.
We’ll consider the other three SOLID principles in more detail next week. What I take away from the single responsibility principle is a recurring theme through all this modular design talk. More chunks or classes that are smaller and more specific.
What I take away from the open/close principle is that once set up much will depend on your base abstractions, which for us are css classes. Avoid changing those classes on existing sites, since changes could affect more than you think. Instead you’d do better to extend base classes through things like subclasses or chained classes.
Overall you should be thinking classes over descendent selectors and keep your classes focused on a single category of property instead of mixing different types of properties on a single selector.
Download a free sample from my book, Design Fundamentals.