tl;dr
.button {
background-color: #03121b;
color: #fff;
cursor: pointer;
display: inline-block;
font-size: 1rem;
line-height: 1;
padding: 0.5em 1em;
text-align: center;
}
.button-primary {
background-color: #006ea0;
}
.button-large {
font-size: 1.1rem;
}
<a href="#" class="button">Default</a>
<a href="#" class="button button-primary">Primary</a>
<a href="#" class="button button-large">Large</a>
<a href="#" class="button button-large button-primary">Large Primary</a>
OOCSS with Sass
%button {
cursor: pointer;
display: inline-block;
line-height: 1;
padding: 0.5em 1em;
text-align: center;
}
%button-primary {
background-color: #03121b;
color: #fff;
}
%button-default {
font-size: 1rem;
}
%button-large {
font-size: 1.1rem;
}
.button-primary {
@extend %button;
@extend %button-default;
@extend %button-primary;
}
.button-large {
@extend %button;
@extend %button-large;
}
What is OOCSS (Object-Oriented CSS)?

Nicole Sullivan first introduced the world to Object-Oriented CSS (OOCSS) at Web Directions North in 2008. Since then it has emerged as one of the leading modular systems for organizing your CSS.
OOCSS is like other CSS methodologies including SMACSS or BEM. All separate content from the structure by placing styles in reusable modular/component blocks. In fact, you don’t need to pick one method over the other. I usually mix both SMACSS with OOCSS when I code.
Object-oriented programming isn’t new.
Object-oriented programming isn’t a new idea. It’s been around since the late 1950s starting at MIT in the environment of the artificial intelligence group. According to Wikipedia,
Object-oriented programming (OOP) is a programming paradigm that represents concepts as “objects” that have data fields (attributes that describe the object) and associated procedures known as methods. Objects, which are instances of classes, are used to interact with one another to design applications and computer programs.
Massachusetts Institute of Technology
OOP has become widely used in both JavaScript and backend languages for several years now, but organizing CSS according to its principles is still relatively new. In layman’s terms, OOP is the practice of making your code reusable, efficient, and fast.
Object-oriented programming with CSS.
It’s a repeating visual pattern, that can be abstracted into an independent snippet of HTML, CSS, and possibly JavaScript.
Nicole Sullivan
When building OOCSS, abstraction is the first thing to consider. There’s two basic principles to follow:
- Separate structure and skin. You should keep the structure and position in a base object and the visual features (like
background
orborder
) in extender classes. This way you’d never have to overwrite visual properties. - Separate container and content. Never mimic the structure of your HTML in CSS. In other words, don’t refer to tags or IDs in your stylesheets. Instead, try to create and apply classes that describe the use of the tag in question. And keep nested classes to a bare minimum.
Why use OOCSS?
It’s scalable. It allows the creation of fast, maintainable CSS, with the benefit of a standards-driven approach. It adds much-needed predictability to CSS so that even beginners can participate in writing beautiful websites.
Not only is it scalable, but also helps:
- It’s scalable. OOCSS allows you to freely mix and re-apply classes on different elements without much regard for their context. Instead of piling on CSS, newcomers to a project can reuse what their predecessors have already abstracted out.
- Boost in site speed. Cutting down on repetition helps applications run faster. CSS files have a habit of expanding exponentially as websites grow in complexity, thus increasing web page size.
- It’s maintainable. Adding or rearranging HTML markups no longer requires you to rethink your entire CSS flow. This is especially helpful for larger ongoing projects.
- It’s readable. When other programmers see your CSS, they’ll be able to quickly understand its structure.
- It’s a proven approach. Understanding the object-oriented methodology makes it easier to learn programming languages like PHP. Conversely, anyone who already understands PHP can quickly pick up OOCSS.
OOCSS isn’t perfect.
Although there are many benefits to using OOCSS, there are some drawbacks:
- It’s overkill for small projects. Scalability, readability, and maintainability isn’t necessarily needed for small projects.
- It increases the number of element classes. You may need to add multiple classes to an element to account for all of the styling elements. This can cause some confusion to those who aren’t familiar with OOCSS and can clutter your markup.
- There’s a learning curve. If you’re using OOCSS and your co-workers aren’t familiar with it, this will require the need for them to learn how to use it before proceeding, which takes time.
Best practices for OOCSS.
To start, there are some “best practices” you’ll want to adhere to — think Legos:
- Minimize selectors. Keep a low specificity
[0-0-1-0]
to have better control over selectors. - Separate structure from the skin. This is a fundamental principle of OOCSS. Create abstract objects for blocks structure and use the class to dress these blocks, regardless of their nature.
- Separate container from the content. Another fundamental principle of OOCSS. Create a 1:n relationship separating the container from its content.
- Extend objects with multiple classes. Class/objects are just like Legos you put together to build the expected result.
- Create a library per component. Each component,
button
,table
, link, image, etc., should be a piece of a Lego — combinable and re-usable as you wish. - Design transparent modules. The module/component is the container that could be used with any content.
- Learn to love grids. Grids allow you to control the width. Height is generally defined by the content.
- Be flexible. Height and width should be extensible and adapt themself.
- Organize your stylesheet into sections. Consider adding a table of contents.
What to avoid with OOCSS.
When creating OOCSS, there are some things you’ll want to avoid:
- Don’t depend on context. There is nothing less flexible but a
article > p:nth-child(2) > span.plop
selector. - Don’t overspecify selectors.
div.my-class
is uselessly overspecific as.my-class
is sufficient enough. However, it becomes relevant if you want to override a class styling for some specific elements –strong.error
will override the defaults rules of.error
for this special use -. - Don’t use IDs. What an ID can do, a class can do better. Furthermore, IDs contribute to creating unexpected specificity mess.
- Don’t use shadows or border-radiuses on irregular backgrounds. It could have unexpected results.
- Don’t create huge sprites. It’s not very optimal in certain cases as you need to deal with image rendering exclusively in CSS.
- Don’t precisely adjust the height. An element height is controlled by its content. Separate container from content will make your life easier.
- Don’t use images for text. Accessibility matters.
- Avoid redundancy. Two components that look too close to be differentiated on the same page look too close to be used on the website,. choose one.
- Avoid using
!important
. Except in some rare cases.
Element IDs: IDs for JavaScript targeting is ideal, but not for styling because they’re too specific. If one object uses an ID for CSS, styling can never be replicated since IDs are unique.
How to code OOCSS.
Now that you know what OOCSS is, why to use it and the best practices to follow, let’s dive into the code. We’ll start with the 2 main principles:
- Separating structure from the skin
- and separating containers from the content.
Structure from skin.
The structure of an component refers to things that are “invisible” to the user such as instructions for element size and positioning. These properties include:
- Height
- Width
- Margins
- Padding
- Overflow
An application’s skin refers to the visual properties of elements such as:
- Colors
- Fonts
- Shadows
- Gradients
In other words, the structure consists of the instructions for how things are laid out, and the skin defines what the layout looks like. OOCSS defines them separately.
Let’s take a look at the wrong way to do this using a common component, the button:
#button {
display: inline-block;
padding: 4px 12px;
margin-bottom: 0;
font-size: 14px;
line-height: 20px;
color: #333333;
text-align: center;
vertical-align: middle;
cursor: pointer;
background-color: #d5d5d5;
}
#button-primary {
display: inline-block;
padding: 4px 12px;
margin-bottom: 0;
font-size: 14px;
line-height: 20px;
color: #ffffff;
text-align: center;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
vertical-align: middle;
cursor: pointer;
background-color: #006dcc;
}
#button-large {
display: inline-block;
padding: 8px 16px;
margin-bottom: 0;
font-size: 18px;
line-height: 28px;
color: #333333;
text-align: center;
vertical-align: middle;
cursor: pointer;
background-color: #d5d5d5;
}
#button-activation {
display: inline-block;
padding: 8px 16px;
margin-bottom: 0;
font-size: 18px;
line-height: 28px;
color: #ffffff;
text-align: center;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
vertical-align: middle;
cursor: pointer;
background-color: #006dcc;
}
<a href="#" id="button">Default</a>
<a href="#" id="button-primary">Primary</a>
<a href="#" id="button-large">Large</a>
<a href="#" id="button-activation">Large Primary</a>
The example above shows a lot fo redundancy. For instance, the #button-activation
is nothing but a large version of #botton-primary
.
The refactored, right way to accomplish this using OOCSS:
.button {
display: inline-block;
padding: 4px 12px;
margin-bottom: 0;
font-size: 14px;
line-height: 20px;
color: #333333;
text-align: center;
vertical-align: middle;
cursor: pointer;
background-color: #d5d5d5;
}
.button-primary {
color: #ffffff;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
background-color: #006dcc;
}
.button-large {
padding: 8px 16px;
font-size: 18px;
line-height: 28px;
}
<a href="#" class="button">Default</a>
<a href="#" class="button button-primary">Primary</a>
<a href="#" class="button button-large">Large</a>
<a href="#" class="button button-large button-primary">Large Primary</a>
.button
define the generic properties – the “defaults” ones – for our buttons. If you override it, you come with new classes that you can combine to get the expected result, just like Legos!
Now all the elements are using classes, the common styles are combined into a reusable “skin” and nothing is unnecessarily repeated. We just need to apply the “skin” class to all the elements and the result will be the same as what the first example would produce, except with less code and a possibility for further reuse.
Make class names generic. When coding OOCSS, it’s important to make all styles you create as generic and adaptive as possible. A general rule of thumb is to try and never use defined widths and heights. The content should be able adapt accordingly while keeping the same look. This is true for most all styles in OOCSS.
Separation of Containers and Content
The second principle of OOCSS is the separation of containers and content. We should rarely use location dependent styles, because those styles then become locked into specific selectors. The “skin” of an object should look the same no matter where it’s located. Separating containers from content makes for a more consistent and predictable user experience. In this context, content refers to elements such as images, paragraphs and div tags that are nestled within other elements, which serve as containers. Most containers can be represented by a structure class.
For example, you can use the class combination btn-small btn-red
to ensure that you see a small, red button regardless of the container it appears in so long as the structure class btn-medium
and skin class btn-red
are written independent of a container.
As a general rule, styles should never be scoped to particular containers. Otherwise, you’ll be unable to reuse them without applying overrides. For example, below is the standard way of setting up the elements that make up a sidebar:
[css]
#sidebar {
padding: 2px;
left: 0;
margin: 3px;
position: absolute;
width: 140px;
}
#sidebar .list {
margin: 3px;
}
#sidebar .list .list-header {
font-size: 16px;
color: red;
}
#sidebar .list .list-body {
font-size: 12px;
color: #FFF;
background-color: red;
}
[/css]
Now, here are the same coding instructions with the content and containers separated:
[css]
.sidebar {
padding: 2px;
left: 0;
margin: 3px;
position: absolute;
width: 140px;
}
.list {
margin: 3px;
}
.list-header {
font-size: 16px;
color: red
}
.list-body {
font-size: 12px;
color: #FFF;
background-color: red;
}
[/css]
Avoiding child selectors is a good strategy for maintaining separation between content and containers. Be sure to bestow unique classes to unique elements.
What about semantics and upkeep?
You shouldn’t care about being non-semantic. I care about what it means to upkeep.
The only way to make objects in plain CSS is to define non-semantic classes. However, this comes with some problems:
- We have to change our HTML almost every time we need to change styles.
- There’s not a safe way to access some of the DOM elements.
- Besides the unmaintainable HTML, everything else about OOCSS is just great. Our CSS code is scalable and easy to maintain and reusing our abstract classes makes it easy to style new content.
So we code the parts in CSS and extend them in HTML. Could it get any better?
There’s a Sass solution to OOCSS.
If you’re familiar with SASS, I’m sure you’ve heard about the @extend
directive. Thanks to placeholder selectors we can extend in Sass, creating semantic classes in CSS, solving our problem for HTML.
We must use placeholders as objects, and define classes formed only by merging them through @extend. This will result in an incredibly DRY CSS code. Let’s see an example:
[css]
/* The bad way */
a.twitter {
min-width: 100px;
padding: 1em;
border-radius: 1em;
background: #55acee
color: #fff;
}
span.facebook {
min-width: 100px;
padding: 1em;
border-radius: 1em;
background: #3b5998;
color: #fff;
}
[/css]
Applying all we’ve seen and using @extend
to mix base objects we can get clean OOCSS which is very easy to maintain and we don’t have to change the HTML all the time.
[css]
/* The best way */
%button {
min-width: 100px;
padding: 1em;
border-radius: 1em;
}
%twitter-background {
color: #fff;
background: #55acee;
}
%facebook-background {
color: #fff;
background: #3b5998;
}
.btn {
&–twitter {
@extend %button;
@extend %twitter-background;
}
&–facebook {
@extend %button;
@extend %facebook-background;
}
}
[/css]
This produces efficient code that we can use easily in our HTML:
[html]
<a href=”#” class=”btn–twitter”>Twitter</a>
<a href=”#” class=”btn–facebook”>Facebook</a>
[/html]
Pretty semantic, right? Sass has solved our problem. Remember: extend and collect non-semantic parts on Sass if you want to keep a semantic, easy to maintain HTML.
Wrapping Up
I know there’s probably a lot of you out there that fear the OOCSS ideology because it appears to go against a lot of the so-called “best practices“. Never fear! Once you understand the benefits of using OOCSS, I have no doubt that you will convert.
All comments posted on 'OOCSS — Modular theming.' are held for moderation and only published when on topic and not rude. Get a gold star if you actually read & follow these rules.
You may write comments in Markdown. This is the best way to post any code, inline like `<div>this</div>` or multiline blocks within triple backtick fences (```) with double new lines before and after.
Want to tell me something privately, like pointing out a typo or stuff like that? Contact Me.