# Object-Oriented CSS: What, How, and Why

Read Time: 21 min

It sounds like an oxymoron, or at least an impossibility, doesn't it? How can a static language that's really more like markup than programming be object-oriented? In this tutorial, I'm going to introduce you to the idea of object-oriented CSS, show you how it works, and try to convince you that you should be using it too!

## What is Object-Oriented CSS?

Object-oriented CSS, at its core, is simply writing cleaner, DRYer CSS. It's not a different language: still the same old CSS we all know and love. It's just a paradigm shift. Really, object-oriented CSS is a few simple patterns and best practices.

So why call it object-oriented? Well, according to Wikipedia,

Object-oriented programming (OOP) is a programming paradigm that uses "objects" — data structures consisting of datafields and methods — and their interactions to design applications and computer programs.

If we were to re-write that definition for object-oriented CSS, it might say something like this:

Object-oriented CSS is a coding paradigm that styles "objects" or "modules"—nestable chunks of HTML that define a section of a webpage—with robust, reusable styles.

This basically means that you have a standard "object" (an HTML structure). Then, you have CSS classes that you apply to objects, which define the design and flow of the object.

Confused? Let's look a bit of theory.

## What is the Theory Behind it?

There are two main principles [in object-oriented CSS]: the first is to separate the structure from the skin and the second is to separate the container from the content.

I quote Nicole Sullivan, whose brainchild object-oriented CSS is. So how do these two principles play themselves out?

Separating the structure from the skin means that your layout styling and your design styling are separate. One very practical way to do this is to use a grid system; there are many options, or you can create your own. If you're not using a grid system, you'll probably just define the structure on the primary object on your page; that's what we'll be doing today.

Separating the container from the content means that any object (the container) should be able to adapt itself to accept any content; for example, it shouldn't need to have an h3 at the top, followed by an unordered list for it to look right. This allows flexibility and reusability, which is paramount.

## Why Should I Code This Way?

There are a few good reasons why you would want to write your CSS in an object-oriented way. One of the biggest benefits—and we've already mentioned it—is that your CSS will be more reusable. But your stylesheets should also become much smaller. Object-oriented CSS should make it easier to change the design of a site.

Writing your styling this way can also give you peace of mind: it will be much easier to change parts of your site without breaking things. Object-oriented CSS also enables you to change your site consistently.

## How do I Practice Object-Oriented CSS?

Well, if you've come this far, you're interested in how exactly you write CSS with an object-oriented mindset. Here we go!

The first step is really prep for the CSS: you have to determine your HTML object. Generally, your object will have a header, a body, and a footer, although the header and footer are optional. Here's a very basic object.

 1 2 
 3 
 4 
 5 
 6 


Before you scream "DIVITIS!" realize that this isn't as bad as it looks; consider this:

 1 2 
 3 
 4 
 5 
 6 


Using HTML5, we now have got an object with semantic meaning and no soup-like characteristics. Actually, this is the object we'll use today.

If we're going to write some CSS, we'll need something to style, so let's whip up a very basic template: a blog home page, and a single post page. We'll be using a few HTML5 elements and some CSS3 styling today!

#### index.htm

 1 2   3   4   5   6  Object Oriented CSS  7   8   9   10   11   12   13   14 
 15 
 16 

Object Oriented CSS

 17 

(really just a bunch of best practices and patterns; not a new language)

 18   26 
 27 28 
 29 
 30 
 31  September 10, 2009  32 

Check out WorkAwesome!

 33 
 34 
 35   36 

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse quis urna dui,  37  ut tempus tortor. Aliquam enim massa, porta a vehicula in, vehicula at lectus. Ut turpis  38  diam, porttitor a iaculis quis, bibendum non lectus. Nullam vitae erat a felis pulvinar  39  tempor ut id leo. Aenean accumsan feugiat ultrices. Duis rhoncus eros id odio faucibus  40  imperdiet. Nulla nibh mauris, placerat sagittis placerat sed, commodo in mi.

 41 
 42 
 43 
 44 
• Read More . . .
•  45 
• Retweet!
•  46 
•  47 
 48 
 49 
 50 
 51 
 52  September 7, 2009  53 

The Intro Post

 54 
 55 
 56   57 

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse quis urna dui,  58  ut tempus tortor. Aliquam enim massa, porta a vehicula in, vehicula at lectus. Ut turpis  59  diam, porttitor a iaculis quis, bibendum non lectus. Nullam vitae erat a felis pulvinar  60  tempor ut id leo. Aenean accumsan feugiat ultrices. Duis rhoncus eros id odio faucibus  61  imperdiet. Nulla nibh mauris, placerat sagittis placerat sed, commodo in mi.

 62 
 63 
 64 
 65 
• Read More . . .
•  66 
• Retweet!
•  67 
•  68 
 69 
 70 
 71 
 72 
 73  September 5, 2009  74 

Welcome

 75 
 76 
 77   78 

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse quis urna dui,  79  ut tempus tortor. Aliquam enim massa, porta a vehicula in, vehicula at lectus. Ut turpis  80  diam, porttitor a iaculis quis, bibendum non lectus. Nullam vitae erat a felis pulvinar  81  tempor ut id leo. Aenean accumsan feugiat ultrices. Duis rhoncus eros id odio faucibus  82  imperdiet. Nulla nibh mauris, placerat sagittis placerat sed, commodo in mi.

 83 
 84 
 85 
 86 
• Read More . . .
•  87 
• Retweet!
•  88 
•  89 
 90 
 91 
 92 
 93   136 137 
 138 
 139 
• Standard
•  140 
• Footer
•  141 
• Information
•  142 
•  143 
•  144 
•  145 
 146 
 147 148 
 149   150  

I know it's kind of long, so here's a diagram of our basic structure:

Look familiar? That's our object, with an aside added for our sidebar. We'll look at the single post page a bit later, but let's hop into some CSS right now!

You'll notice that we are linking to three stylesheets: reset.css, text.css, and styles.css. Reset.css is Eric Meyer's reset. Text.css is important: the second step of object-oriented CSS is styling a few key basic elements; usually, these are text elements, like headers and lists. Styling these objects is important because it determines the consistent look and feel of the site; these elements, for the most part, won't receive any additional direct styling.

Here's what we've got in our text.css:

 1 2 body { font: 13px/1.6 Helvetica, Arial, FreeSans, sans-serif;}  3 h1, h2, h3, h4, h5, h6 { color:#333; }  4 h1 { font-size: 50px; text-shadow:1px 1px 0 #fff; font-family:arial black, arial}  5 h2 { font-size: 23px; }  6 h3 { font-size: 21px; }  7 h4 { font-size: 19px; }  8 h5 { font-size: 17px; }  9 h6 { font-size: 15px; }  10 p, h1, h2, h3, h4, h5, h6, ul { margin-bottom: 20px; }  11 article, aside, dialog, figure, footer, header, hgroup, menu, nav, section { display: block; } 

(Hats off to the 960 Grid System, whose text.css file this is spun off.)

Now we'll start building styles.css; this is where the object-oriented magic begins. However, I'll first just throw in a few top-level styles, just to set a body background and some link and list styles.

 1 2 body  3  { background:url(../img/grad.jpg) repeat-x #c0c0c0;  4  }  5 /*Note: All the image will be in the downloadable source code. */  6 a  7  { text-decoration:none;  8  color:#474747;  9  padding:1px;  10  }  11 a:hover  12  { background:#db5500;  13  color:#fff;  14  }  15 .selected  16  { border-bottom:1px solid #db5500;  17  }  18 li  19  { padding-left:15px;  20  background:url(../img/bullet.png) 0 5.9px no-repeat;  21  } 

Our first order of business is to define the structure of the page:

 1 2 #container  3  { margin:40px auto;  4  width:960px;  5  border:1px solid #ccc;  6  background:#ececec;  7  }  8  #container > header, #container > footer  9  { padding:80px 80px 80px;  10  width:800px;  11  overflow:hidden;  12  border: 1px solid #ccc;  13  border-width:1px 0 1px 0;  14  }  15  #container > header  16  { background:url(../img/header.jpg) repeat-x #d9d9d7;  17  }  18  #container > header li, #container > footer li  19  { float:left;  20  padding:0 5px 0 0;  21  background:none;  22  }  23  #container > section  24  { background:#fdfdfd;  25  padding:0 40px 40px 80px;  26  float:left;  27  width:493px;  28  border-right:1px solid #ccc;  29  }  30  #container > aside  31  { padding-top:20px;  32  float:left;  33  width:346px;  34  }  35  #container > footer  36  { padding:40px 80px 80px;  37  background:#fcfcfc;  38  }  39  #container > footer li:after  40  { content:" |"  41  }  42  #container > footer li:last-child:after  43  { content:""  44  } 

Notice that we're styling our container object by starting all our selectors with #container. However, that's a special case: usually, you will want to use classes, because they are freely reusable.

We can use class selectors for our post styling:

 1 2 .post  3  { overflow:visible;  4  margin-top:40px;  5  }  6  .post > header  7  { margin:0 0 20px 0;  8  position:relative;  9  }  10  .post .date  11  { padding:2px 4px ;  12  background:#474747;  13  color:#ececec;  14  font-weight:bold;  15  transform:rotate(270deg);  16  -moz-transform:rotate(270deg);  17  -webkit-transform:rotate(270deg);  18  position:absolute;  19  top:60px;  20  left:-105.5px;  21  }  22  .post img  23  { float:left;  24  margin-right:10px;  25  }  26  .post.ext img  27  { float:right;  28  margin:0 0 0 10px;  29  }  30 .post footer  31  { overflow:hidden;  32  }  33  .post footer li  34  { float:left;  35  background:none;  36  } 

Let's look at what makes this CSS object-oriented. Firstly, we have not limited the class to a specific element; we could add it to anything. This gives us the most flexibility possible. Then, notice that we haven't set any heights or widths; that is part of separating the structure from the skin; we already wrote the sturcture styling, so this object will fill whatever space the structure gives it.

Also, we have styled all the elements involved in an independant way: the parent elements don't require certain children to look right; although we have styled child elements, nothing will break if they aren't there. And the child elements are, for the most part, not dependant on their parents; I haven't styled the h2 in a post object, because it should be consistent across the site; we already took care of that in text.css.

There's another important bit, the part most like object-oriented programming: extended classes. You probably saw that we have styling for both .post img and .post.ext img. I'm sure you know what they will do, but here's the proof:

Simply by adding another class to your object, you can change minor parts of the look and feel; I should mention that Nicole Sullivan would have created a class called .postExt, and then applied both to the object; I prefer to do it this way, because it allows me to use the same class name ("ext") for all my extensions, and I think it makes the HTML look cleaner. You just have to remember not to put a space in the selector; ".post .ext" will look for an element in class ext inside an element in class post. Without the space, it will look for an element in both classes.

## On to the Sidebar

Now that we have the main content area set out, let's look at the sidebar. We've got two objects in the sidebar: an archives list and a recent comments list. To begin, we'll create a .side-box class for them:

 1 2 .side-box  3  { padding: 20px 80px 20px 40px;  4  }  5  .side-box:not(:last-child)  6  { border-bottom:1px solid #ccc;  7  }  8  .side-box > header h3  9  { margin-bottom:0;  10  }  11  .side-box > header p  12  { text-transform:uppercase;  13  font-style:italic;  14  font-size:90%;  15  } 

Again, you should take note that we're being careful to follow the two rules: we've separated the structure from the skin by not setting the height or width; the object flows to fill whatever space it needs to take. And we've separated container from content by not making child elements required for proper styling. Yes, I have adjusted the h3 styling, which makes that particular h3 look dependant on the class side-box; in most cases, that's undesireable, but in this case, I haven't done too much.

But let's create an extension for this; however, since we want to do a large visual adjustment, we won't extent the side-box class directly; we'll create a new class.

 1 2 .pop-out > section > *  3  { display:block;  4  background:#fefefe;  5  border:1px solid #474747;  6  padding:20px;  7  position:relative;  8  width: 120%;  9  left:20px;  10  } 

So what does this do? Notice the selector: we are targeting every element directly inside the body of our object; when styling an object, you always apply the class to the object itself. This CSS will "pop" the content out to the right.

"HEY, you set a width! What about separating struture from skin?" I set a width because we are targeting the elements inside the body of our object; since the object has padding, that inner element is a bit narrow by itself. That sounds like an excuse for breaking the rule, but I don't think I really broke the rule: I set the width as a percentage, which still depends on structure styling further up the cascade.

Here's what that looks like.

I just told you that you should always apply classes to the top-level objects, and use child selectors to mold the inner elements. But part of object-oriented CSS is being able to mix and match styles easily. It's quite possible you'll want to use a similar header on two objects that aren't really related in any way. It's ideal to have a collection of header and footer classes that you apply directly to the header or footer of an object. This way, you aren't adding similar code to multiple non-related classes, but abstracting that away and applying it in the relevent place. Let's create an abstracted header.

You'll notice that we gave the header of our recent comments object a class called 'post-it.' Let's create that class now.

 1 2 .post-it  3  { border:1px solid #db5500;  4  padding: 10px;  5  font-style:italic;  6  position:relative;  7  background:#f2965c;  8  color:#333;  9  transform:rotate(356deg);  10  -moz-transform:rotate(356deg);  11  -webkit-transform:rotate(356deg);  12  z-index:10;  13  top:10px;  14  box-shadow:1px 1px 0px #333;  15  -moz-box-shadow:1px 1px 0px #333;  16  -webkit-box-shadow:1px 1px 0px #333;  17  } 

A poor semblance of a post-it note!

It's important to stress that even though we plan to use this for a header, we haven't specified that in the selector. If this resembles a common design aspect of our site, we may end up wanting this style for something else; for example, we could extend it with classes that adjust the colour and rotation, and use them on a wall or bulliten board or something similar.

Don't lock down your selectors; you never know when you'll want those styles!

Often you'll want to take it further than just header and footer classes; a component library is a huge part of object-oriented CSS; a basic rule might be this: whenever you want to apply the same style in multiple un-related places, abstract. Of course, you might find after hard coding something into an object that it would be more useful if you could use it elsewhere; don't be afraid to refactor. It's always to your benefit.

You'll see these components in the page header and the recent comments box.

 1 2 .meta  3  { font-size:75%;  4  font-style:italic;  5  }  6 .subtitle  7  { text-transform:uppercase;  8  font-size:90%;  9  font-weight:bold;  10  letter-spacing:1px;  11  text-shadow:1px 1px 0 #fff;  12  } 

Well, we're done with our index page; let's look at a bit more object-oriented-ness on a single post page. Just copy that index page, rename it 'post.htm' and swap out the page header and section for this code.

 1 2 
 3 

Object Oriented CSS

 4 

(really just a bunch of best practices and patterns; not a new language)

 5   13 
 14 
 15 
 16 
 17  September 10, 2009  18 

Check out WorkAwesome!

 19 
 20 
 21   22 

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse quis urna dui,  23  ut tempus tortor. Aliquam enim massa, porta a vehicula in, vehicula at lectus. Ut turpis  24  diam, porttitor a iaculis quis, bibendum non lectus. Nullam vitae erat a felis pulvinar  25  tempor ut id leo. Aenean accumsan feugiat ultrices. Duis rhoncus eros id odio faucibus  26  imperdiet. Nulla nibh mauris, placerat sagittis placerat sed, commodo in mi.

 27 

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse quis urna dui,  28  ut tempus tortor. Aliquam enim massa, porta a vehicula in, vehicula at lectus. Ut turpis  29  diam, porttitor a iaculis quis, bibendum non lectus. Nullam vitae erat a felis pulvinar  30  tempor ut id leo. Aenean accumsan feugiat ultrices. Duis rhoncus eros id odio faucibus  31  imperdiet. Nulla nibh mauris, placerat sagittis placerat sed, commodo in mi.

 32 

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse quis urna dui,  33  ut tempus tortor. Aliquam enim massa, porta a vehicula in, vehicula at lectus. Ut turpis  34  diam, porttitor a iaculis quis, bibendum non lectus. Nullam vitae erat a felis pulvinar  35  tempor ut id leo. Aenean accumsan feugiat ultrices. Duis rhoncus eros id odio faucibus  36  imperdiet. Nulla nibh mauris, placerat sagittis placerat sed, commodo in mi.

 37 

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse quis urna dui,  38  ut tempus tortor. Aliquam enim massa, porta a vehicula in, vehicula at lectus. Ut turpis  39  diam, porttitor a iaculis quis, bibendum non lectus. Nullam vitae erat a felis pulvinar  40  tempor ut id leo. Aenean accumsan feugiat ultrices. Duis rhoncus eros id odio faucibus  41  imperdiet. Nulla nibh mauris, placerat sagittis placerat sed, commodo in mi.

 42 
 43 
 44 
 45 
• Digg!
•  46 
• Share!
•  47 
• Like!
•  48 
 49 
 50 
 51 
 52 

 53 
 54 
 55 

First-commenter

Sept 10

 56 

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse quis urna dui,

 57 
 58 
 59 

Sept 12

 60 

diam, porttitor a iaculis quis, bibendum non lectus. Nullam vitae erat a felis pulvinar

 61 
 62 
 63 

Second-commenter

Sept 10

 64 

tempor ut id leo. Aenean accumsan feugiat ultrices. Duis rhoncus eros id odio faucibus

 65 
 66   70 
 71 

Fourth-commenter

Sept 12

 72 

imperdiet. Nulla nibh mauris, placerat sagittis placerat sed, commodo in mi

 73 
 74 


Now we can see where some reusability comes in; we can use the post class for the blog posting here; that's the same post class we used for the home page; because we didn't specify the structure, but let the object expand to take in whatever we give it, it can handle the whole post.

Now let's turn our attention to the comments on this page; comments are a great place to use object-oriented CSS. We'll start by adding this:

 1 2 .comment  3  { border:1px solid #ccc;  4  border-radius:7px;  5  -moz-border-radius:7px;  6  -webkit-border-radius:7px;  7  padding:10px;  8  margin:0 0 10px 0;  9  }  10  .comment > header > p  11  { font-weight:bold;  12  display:inline;  13  margin:0 10px 20px 0;  14  } 

This alone gives us some psuedo-attractive comments; but we can do more. Our HTML has classes for replies and author comments.

 1   2 .reply.comment  3  { margin-left:80px;  4  }  5 .author.comment  6  { color:#ececec;  7  background:#474747;  8  } 

Make sure you don't have a space between the two class names. This is a bit different from what we did earlier: instead of changing the styling of the comment class, we are actually extending it (So maybe these are the real extended classes).

And the finished comments . . .

And while we're here, let's add a comment form to our component library.

 1 2 .comments-form p  3  { padding:5px;  4  border-radius:5px;  5  -moz-border-radius:5px;  6  -webkit-border-radius:5px;  7  }  8 .comments-form p:hover  9  { background:#ececec;  10  }  11 .comments-form label  12  { display:inline-block;  13  width:70px;  14  vertical-align:top; }  15 .comments-form label:after  16  { content: " : ";  17  }  18 .comments-form input[type=text],  19 .comments-form button,  20 .comments-form textarea  21  { width:200px;  22  border:1px solid #ccc;  23  border-radius:5px;  24  -moz-border-radius:5px;  25  -webkit-border-radius:5px;  26  padding:2px;  27  }  28 .comments-form button[type=submit]  29  { margin-left:70px;  30  } 

This gives us a nice rounded-corner form with a soft hover effect.

I'm kind of torn here; a fundamental concept of object-oriented CSS is the ability to add a class to different elements; but what about this case? This class would basically be useless on anything but a form; should we change the selectors to form.comments-form as a kind of security? What do you think?

Well, that really covers the ideas of object-oriented CSS.

## Review the Main Steps

1. Determine your object.
2. Set your reset, base elements, and base object styles.
3. Apply classes to objects and components for the desired look and feel.

I didn't use the standard message example, but it's really a great way to get into object-oriented CSS. Try creating an message class that you can apply to different elements, like a paragraph, a list item, or a complete object. Then, extend it with error, warning, and info classes. See how flexible and reuseable you can make it.

## Is Object-Oriented CSS Always Useful?

I don't think the answer to this question is a simple "yes" or "no"; that's probably because object-oriented CSS isn't a language, but a collection of patterns and best practices. You may not always want to apply the idea of the standard HTML object, but most of the CSS principles are always valid. If you think about it, you'll see it's really about where you want to optimize: you could code you're HTML minimalistically, with a few ids for handles, and be able to style it easily; but the CSS won't be reusable, and the site might break later when you come to change things. Or you could write a bit more HTML and optimze the CSS with the principles we've looked at in this tutorial.

I'm willing to expand my HTML a bit so that I can write CSS that is reusable, flexible, and DRY. What's your opinion?