Skip to content

Instantly share code, notes, and snippets.

@rikschennink
Last active January 29, 2019 09:44
Show Gist options
  • Save rikschennink/e2d11c73443ef7cda413ee4c9e2cb28d to your computer and use it in GitHub Desktop.
Save rikschennink/e2d11c73443ef7cda413ee4c9e2cb28d to your computer and use it in GitHub Desktop.
Sass OO Mixins: OOCSS without the HTML clutter

Sass OO Mixins: OOCSS without the HTML clutter

  • Less HTML clutter (caused by all those fragmented class names).
<button class="btn btn-primary btn-large btn-outline">Buy!</button>
  • Descriptive classes (or no classes at all) in the HTML results in cleaner and easier to read HTML.
<button class="btn-call-to-action">Buy!</button>
  • Easier to determine the look of the element by reading the @include name instead of deriving the info from all the individual properties.
@mixin button-style-ghost {
  display: inline-block;
  padding: .5rem;
  border: 2px solid #333;
  color: #333;
  font-weight:bold;
  background: transparent;
}
  • Make dependencies visible by moving the patterns to separate files and only @import them when required.

  • Use composition to build complex patterns by combining simple ones.

@mixin box-float {
  @include box-rounded;
  @include box-padded;
  background: #fff;
  box-shadow: 0 .25rem .5rem rgba(0,0,0,.25);
}
  • Keep style complexity in your CSS instead of your HTML, no need to edit the HTML when changing looks.

  • Impact of duplication in generated CSS is minimized by gzip. Also Mixins vs. Extends.

  • When old style patterns are no longer referenced they automatically stop taking up space in the CSS output.

  • The use of descriptive classes in your HTML instead of OO classes can work to enforce a more concise style. Having to name each element helps in determining if there might be too many similarly looking elements being used to achieve the same UX goal (10 different call to action button styles).

// Button styles
@mixin button-style-ghost {
color: #333;
background: transparent;
border: 2px solid #333;
// etc.
}
@mixin button-style-solid {
background-color: #333;
color: #fff;
// etc.
}
// Geometry styles
@mixin box-padded {
padding: 1.5rem;
}
@mixin box-rounded {
border-radius: .25rem;
}
@mixin box-float {
@include box-rounded;
@include box-padded;
background: #fff;
box-shadow: 0 .25rem .5rem rgba(0,0,0,.25);
}
@import 'patterns/buttons';
@import 'patterns/geometry';
// Use patterns to style generic elements
button[type=button] {
@include button-style-ghost;
}
button[type=submit] {
@include button-style-solid;
}
// When the inevitable "this link should look like a button" situation arises, it's easy to
// fix by doing this (instead of stacking all the selectors, or copy-pasting the properties)
a[download] {
@include button-style-solid;
}
// HTML class names can now be more descriptive, "message-item" is easier to read than "box-rounded box-padded box-float".
.message-item {
@include box-float;
}
@rikschennink
Copy link
Author

@craigjennings11 Thanks for the detailed comment!

I think while having to create a new selector for each element can be perceived as a disadvantage it can also be seen as an advantage. Composing all sorts of types of boxes in the HTML is indeed very easy to do with OOCSS but it also creates a lot of boxes (this sounds obvious, hangon ;-)). Being forced to name each on of them helps in determining if there might be too many similarly looking elements being used to achieve the same UX goal.

@rikschennink
Copy link
Author

@isaacnass somehow my earlier reply got lost.

Anyway, I left out the parameters on purpose. Using parameters, loops, if statements, etc. is all pretty cool and can really result in clean code but it also introduces the risk of the SCSS becoming very difficult to read when returning to a project after some time. So to keep things as simple as possible I decided to purely focus on using mixins as property groups.

@justusromijn
Copy link

@craigjennings11 mixins are functions which also accept parameters, so you won't need a separate mixin for subtle differences. You can parameterize a couple of things if they make sense for their usage. If you look at the text color example:

@mixin colored-text ($color) {
    color: $color;
}
.my-blue-box {
  @include box-padded;
  @include box-rounded;
  @include colored-text(blue);
}

That solves at least that problem.

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