Skip to content

Instantly share code, notes, and snippets.

@scottkellum
Created March 24, 2012 15:53
Show Gist options
  • Save scottkellum/2184518 to your computer and use it in GitHub Desktop.
Save scottkellum/2184518 to your computer and use it in GitHub Desktop.
OOCSS vs OOSass

OOCSS vs OOSass

note that this requires Sass 3.2 alpha or higher

OOCSS is awesome because it helps us organize our style sheets in clean and simple ways but it can be far too rigid for the new responsive web. How can we use preprocessors to preserve both flexibility and cleanliness of code? Can these objects be abstracted to our preprocessors?

Lets first take a look at three column widths in OOCSS to see how they compare.

CSS

.width-1 {
  width: 100px;
}
.width-2 {
  width: 200px;
}
.width-3 {
  width: 300px;
}

HTML

<aside class="width-1">

But why am I writing .width-2 and .width-3 if I am not using them? I also have the layout class applied directly to my HTML. Do I add more classes as I add more CSS for breakpoints?

How can OOSass solve these issues?

Sass

%width-1 {
  width: 100px;
}
%width-2 {
  width: 200px;
}
%width-3 {
  width: 300px;
}

aside {
  @extend %width-1;
}

Compiled CSS

aside {
  width: 100px;
}

HTML

<aside>

Adding intelligence

Clean right? And you can simply build on to classes and names that describe the content instead of adding rigid layout classes to your markup. But we can also use Sass to add intelligence to the code being written. Chances are, you want space between these elements. Lets add 10px gutters but we are using Sass, let it figure out where the columns are.

$column: 100px;
$gutter: 10px;

%column {
  float: left;
}

%next-column {
  margin-left: $gutter;
}

%width-1 {
  width: $column;
}
%width-2 {
  width: $column * 2;
}
%width-3 {
  width: $column * 3;
}

article {
  @extend %width-2;
  @extend %column;
}

aside {
  @extend %width-1;
  @extend %column;
  @extend %next-column;
}

Now we added more classes to flush out the functionality but we have to write a lot of objects and we have to figure out where we are each time. Sass can take care of this for you by simply counting what column you are on.

$counter: 0;

@mixin width($width) {
  @if $counter >= 3 { // if the counter is less than or equal to our total number of columns
    $counter: 0; // reset the counter to zero
  }
  
  // Write our conditions
  @extend %width-#{$width};
  @extend %column;
  
  // If we are not starting on the first column, extend the next-column object
  @if $counter != 0 {
    @extend %next-column;
  }
  
  // Add the width to the counter so we know what column is next
  $counter: $counter + $width;
}

This mixin keeps track of what column we are on and will extend the appropriate objects. Now all we need to do is include how wide we want our columns and Sass will figure out where we are on the grid and accommodate for that.

article {
  @include width(2);
}

aside {
  @include width(1);
}

Now if you are already familiar with Sass you know that you could write a loop to set any number of columns at any number of sizes. But this is a simple example of what can be done with OOSass.

@scottkellum
Copy link
Author

@chriseppstein, @nex3, @paulirish - Quick write up but am interested in your thoughts if you have time. This kind of goes against some of @necolas’s comments. I have issue with OOCSS because it adds annoying rigidity to RWD. I think (good) preprocessors offer some new options.

@crgwbr
Copy link

crgwbr commented Mar 25, 2012

Very good writeup, but I believe there's a flaw in how the width mixin's counter works. It uses a counter to determine whether or not to add a a gutter to the column, and increments the counter each time its called with the width of the column its adding. This works great with your example because the gutter is a left-margin, and you defined you columns from left to right. However if you defined them out of order...

aside {
  @include width(1);
}
article {
  @include width(2);
}

...the article (which would still be on the left side of the page) would have the left-margin gutter intended for the aside element. This could be fixed by sending width start and end column numbers (@include width(1, 2) # Just like an array slice) rather than just a column width.

@scottkellum
Copy link
Author

@crgwbr thanks! Yeah it requires markup order but adding a column override is easy enough. There are a few nesting bugs as well. Lots of features that can be added to this (and are in a far more advanced grid mixin I am working on).

@emrecamasuvi
Copy link

there are some situations that you cant touch markup directly, i'm one of those unfortunate guys in e-commerce theme business. aside semantic issues, i love using oosass like scott used and waiting sass 3.2 eagerly because i saw something new named "content"; it looks like the best way to deal with responsive design. Like django's {{ block.super }} or @MEGAextend. We'll see. Please excuse my poor english.

@Anderson-Juhasc
Copy link

Hello everybody,
I created something simple but can help in the creation and organization of @extend-Only Selectors: https://gist.github.com/3380509
Bye,

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment