Object Oriented CSS methodology

In this post, we will discuss the Object Oriented CSS methodology created by Nicole Sullivan in 2008. It’s an approach that has a lot in common with the object-oriented programming approach, which is why it can be particularly interesting for people used to object-oriented writing.

What is a CSS object?

The reason for introducing CSS objects is the desire to obtain reusability of the code (HTML, CSS, JS) by creating independent fragments, called objects. According to the description, such an object consists of four elements:

  • one or more HTML nodes
  • CSS selectors responsible for appearance, starting from assigned to the main node
  • external elements needed for display (e.g. background photos)
  • JavaScript code that determines the behaviour of the CSS object

According to this methodology, we create default objects (we could otherwise call them ‘base’), which then ‘expand’ by specific reusable CSS classes giving them a specific appearance depending on the needs according to the rules, which I will discuss later.

About non-semanticity

A characteristic feature of the Object Oriented CSS is quite a lot of freedom, because there are only two rules, which, combined with the lack of the imposed naming convention, provide a great opportunity to adapt the methodology to your needs in the project.

Classes are the basic tool for styling. A partial loss of their semanticity is often encountered, i.e. at the expense of reuse, we lose styling of HTML fragments based on what they do. Objects are called based on what they are and not their role in the application. Let’s look at examples illustrating what I mean by that:

<div class="alert alert-green">I am not a semantic alert displaying successful operation</div>
<div class="success-alert">I am a semantic alert displaying successful operation</div>

<article class="row">I am not a semantic post row</article>
<article class="post">I am a semantic post row</article>

I leave the discussion about the validity of the semantic or non-semantic approach for another occasion. Nevertheless, this is a very interesting issue and I encourage you to explore this topic for example on maintainablecss.com, css-tricks.com, or medium.com.

It is worth explaining why I wrote that we are only partially losing the semantics of CSS classes. The methodology itself does not impose a specific naming, although there are standards to follow. The creation of certain global styles requires the use of a universal, and therefore non-semantic, name. There are no contraindications not to use semantic names for extension classes.

Two main principles

The Object Oriented CSS methodology is based primarily on two principles: separation of structure from skin, and separation of containers and content.

Separation of structure from skin

Each element on the page consists of two layers: a structured one, which includes, among other things, the width, height, margin, padding of the element and the visual one, which includes, for example, background, colour, font size, and border. Our goal is to separate these two layers when creating classes that style a given element. Thanks to this, we can easily manipulate the appearance of a given group of elements through:

  • changing the styles of a given class,
  • change of the class assigned to it.

Let’s illustrate this principle with a suitable example:

<input class="form-control form-control-purple" type="text"></input>
<input class="form-control form-control-green" type="text"></input>
<input class="form-control form-control-white" type="text"></input>
.form-control {
    margin: 1rem auto;
    padding: 0.5rem;
    border-radius: 5px;
}

.form-control-purple {
    background: purple;
    color: white;
    border-color: purple;
}

.form-control-green {
    background: green;
    color: white;
    border-color: green;
}

.form-control-white {
    background: white;
    color: black;
    border-color: white;
}

We see that in the .form-control class there is a general structure of the object (in this case input), while the next classes describe its different versions of the appearance. Now, if we want to modify the green shade in all of these objects, all we have to do is change the .form-control-green class. We obtain a default object with a specific structure and create only its visual variants.

It is worth mentioning a quite often used version of this approach, namely the size of the CSS object. It consists in the fact that we create different versions of its size, for example:

.form-control-sm {
    padding: 0.3rem 0.5rem;
}

.form-control-md {
    padding: 0.5rem 0.8rem;
}

.form-control-lg {
    padding: 0.8rem 1.2rem;
}

Separation of containers and content

According to this rule, we should not make the appearance of items inside the container dependent. Let us introduce, for example, bad practice and then good. We will use the HTML structure known from the previous entry:

<article class="post">
    <header>
        <h2>Post title</h2>
    </header>
    <section>
        <img src="...">
        <div>                   
            <p></p>
            <p></p>
        </div>
    </section>
    <footer>
        Post footer
    </footer>
</article>

Badly applied styles could look like this:

.post header, .post footer {
    width: 50%;
    margin: 10px auto;
}
.post h2 {
    font-family: Arial, sans-serif;
    font-size: 18px;
    background: grey;
    color: red;
}
.post img {
    height: 200px;
    width: 300px;
    filter: blur(3px);
}
.post p {
    font-family: Georgia, sans-serif;
    font-size: 14px;
    color: blue;
}

These styles are not bad themselves. The problem with them is that they are non-reusable. In case we would like to add another <h2></h2> tag in another place and apply the same styles except for the colour and the background, we would either have to copy the code or overwrite the styles. We see that the <h2>tag is heavily dependent on where it is located. You can get rid of it – let’s look at well-applied styles:

.header, .footer {
    width: 50%;
    margin: 10px auto;
}
.h2 {
    font-family: Arial, sans-serif;
    font-size: 18px;
    background: transparent;
    color: green;
}
.img {
    height: 200px;
    width: 300px;
    filter: blur(3px);
}
.p {
    font-family: Georgia, sans-serif;
    font-size: 14px;
    color: blue;
}
.post-heading {
    background: grey;
    color: red;
}

We see that by applying specific classes for tags, we become independent from the container. If we need to make modifications to the ‘basic’ style, we create a class that will make changes (in this case, the class is .post-heading. Note that its name is semantic, although we could also use a non-semantic name). In this situation, all you need to do is add two classes to the <h2> tag: .h2 and .post-heading to get the desired effect.

Summary*

In this post, we’ve learned about the OOCSS methodology: the general concept of what a CSS object is and the two rules governing this methodology. Next entry will be about Scalable and Modular Architecture for CSS, abbreviated as SMACSS. If you want to go deeper into the OOCSS secrets, follow those links:

* In the summaries of the methodology entries, I omit the presentation of their advantages and disadvantages, because I want to leave each of you the opportunity to evaluate independently

Previous articles from the CSS series:

Tags:

Michał Wajer

Software Developer at Aspire Systems Poland. He began his adventure with Angular in the summer of 2018. In his free time, he learns the secrets of Vue, RxJS and TypeScript. Enthusiast of sport (most of all running) and speedway.