Agent 5 CSS Refactor
Overview
- Current State
- Why Refactor
- OOCSS
- Practical Application
- Results
Current State
- 4 Files
	- bootstrap.css
- styles.css (our stuff)
- kendo.css
- print.css (print-specific styles)
 
- Size of styles.css - 208kB
- # Rules - 1898
- # Selectors - 2903
Why Refactor?
Codebase was a mess
@import "form_add-cc.less";
@import "form_create-case.less";
@import "form_create-contact.less";
@import "form_modal_create-contact.less";
@import "form_create-solution.less";
@import "form_edit-case.less";
@import "form_edit-contact.less";
@import "form_edit-employee.less";
@import "form_edit-site.less";
@import "form_edit-solution.less";.cc-listing .alert {
  padding: 4px 35px 4px 14px;
}
.add-cc-form .contact-picker .contact-input-control {
  margin-left: 0px;
}
form_add-cc.less
form_create-case.less
div.contact-input-control {
  padding-bottom: 12px;
  .pick-contact {
    width: 100%;
    margin-bottom: 0;
  }
}
div.site-input-control {
  padding-bottom: 25px;
  .pick-site {
    margin-bottom: -10px;
  }
}
.content-row{
  margin-bottom: @baseLineHeight;
  padding-top: @baseLineHeight;
  position: relative;
}solution-description.less
.nav-header {
  // 28 lines
  &:hover {
    .badge{
      background-color: @grayDarker;
      color: @grayLight;
      //right: 14px;
    }
  }
  .badge{
    .badge-gray();
    background-color: darken(@grayLight, 5%);
    top:6px;
  }
  &.active{
  // 8 lines
  .badge{
    background-color: @blue;
    color: @grayLight;
  }
}
// 12 lines
.nav-header {
  a.due-soon-navbadge{
    // 13 lines
    .badge{
    background: @grayDarker;
    top: 18px;
    color: @grayLight;
    }
    &:hover{
      background-color: @blue;
      color: @white;
      .badge{background-color: @white; color: @blue;}
      text-shadow: none;
      i{text-shadow: none;}
    }
  }
}
// At bottom
.badge{
  .badge-gray();
  background-color: darken(@grayLight, 5%);
  text-indent: 0;
}.toolbar-wrapper{
  line-height: 10px;
  color: @grayDark;
  background-color: @white;
  float: right;
  margin-left: 15px;
  margin-bottom: 15px;	
  margin-top:-25px;
  margin-right: -25px;
  //...
}mixins.less
.account-and-addresses{
  //...
  .toolbar-wrapper {
    margin-top: -15px;
    margin-right: -15px;
  }
}containers.less
.history {
  .toolbar-wrapper{
    margin-top: 0;
    z-index: 1;
  }
}tab_history.less
.toolbar-wrapper{
  margin-top: -10px;
  margin-right: -15px;
  float: right;
  position: relative;
  .cases-linked-badge {
    float: left;
    margin-right: 5px;
    margin-left: 0;
    margin-bottom: @baseLineHeight;
  }
  .icon-toolset-menu {
    float: right;
    margin: 0 5px;
  }
}tools-menus.less
- We used to have bootstrap and our styles build into one stylesheet. Why split them?
- IE9 is smart

Summary
- Code organization was terrible (hard to find rules you wanted to)
- Rules were all over the place (hard to find which rule you cared about in your specific situation)
- Specificity wars galore
Let's Try Something Different
(You guys are gonna hate the name)
Object Oriented CSS
OOCSS History
- Created by Nicole Sullivan in 2009
- Claim to fame was helping Facebook go on a stylesheet diet (19% less css, 44% less html, 50% gain in loading performance)
- Challenges css "best-practices"
	- Use specificity
- Create modules
 
OOCSS Goals
- Code reuse
- Easy dev introduction
- Robust
OOCSS Principles
- Separate Structure & Skin
- Separate Content & Container
Structure vs Skin
.notification-info {
  border: 1px solid black;
  height: 200px;
  width: 400px;
  background: blue;
  color: black;
}
.popup-red {
  border: 1px solid black;
  height: 200px;
  width: 400px;
  background: red;
  color: white;
}
.box-narrow {
  border: 1px solid black;
  height: 200px;
  width: 200px;
  &.red {
    background: red;
    color: white;
  }
  .blue {
    background: blue;
    color: black;
  }
}.box {
  border: 1px solid black
  height: 200px;
}
.box-wide {
  width: 400px;
}
.box-narrow {
  width: 200px;
}
.box-red { // Bad naming
  background: red;
  color: white;
}
.box-info {
  background: blue;
  color: black;
}
<div class="box box-wide box-red"></div><div class="box box-narrow box-info"></div>Content vs Container
A Heading should not be a Heading on another part of the page
h1 { ... }
#module1 h1 { ... }
#module2 h1 { ... }
/* It's impossible to have a normal h1 in #moduleX now */.nav-header {
  // 28 lines
  &:hover {
    .badge{
      background-color: @grayDarker;
      color: @grayLight;
      //right: 14px;
    }
  }
  .badge{
    .badge-gray();
    background-color: darken(@grayLight, 5%);
    top:6px;
  }
  &.active{
  // 8 lines
  .badge{
    background-color: @blue;
    color: @grayLight;
  }
}
// 12 lines
.nav-header {
  a.due-soon-navbadge{
    // 13 lines
    .badge{
    background: @grayDarker;
    top: 18px;
    color: @grayLight;
    }
    &:hover{
      background-color: @blue;
      color: @white;
      .badge{background-color: @white; color: @blue;}
      text-shadow: none;
      i{text-shadow: none;}
    }
  }
}
// At bottom
.badge{
  .badge-gray();
  background-color: darken(@grayLight, 5%);
  text-indent: 0;
}Practical Application
- Identify common elements
- Think in terms of structure and skin, not in modules
- Don't be afraid to have many classes on an element



.a5-card {
  .border-box;
  display: block;
  height: 190px;
  max-height: 190px;
  max-width: 33%;
  min-height: 190px;
  min-width: 32%;
}
.a5-card-small:extend(.a5-card) {
  height: 120px;
  max-height: 120px;
  min-height: 120px;
}
.a5-card-med:extend(.a5-card) {
  height: 150px;
  max-height: 150px;
  min-height: 150px;
}
.a5-card-full-width:extend(a5-card) {
  min-height: 20px;
  min-width: 95%;
}Naming is Hard
.box {...}
.box-blue { background: blue; }
.box-red { background: red; }.box {...}
.box-info {...}
.box-error {...}.box {...}
.box-blue { background: teal; }
.box-red { background: orange; }Enabling Customization
// Agent 5 Variables
// ------------------------------
// Colors
@grayLightest:          #f9f9f7;
@grayBorder:            #c3c3c3;
@greenDarkest:          #368959;
@greenLight:            #74cf9b;
@greenLightest:         #b1f4ce;
// Variables
// ------------------------------
@a5-card-bg: @white;
@a5-card-border-color: @grayLight;
@a5-card-wrapper-bg: @grayLighter;
// Structure
// ------------------------------
.a5-card-default {
  .border-radius(4px);
  background: @a5-card-bg;
  border: 1px solid @a5-card-border-color;
}variables.less
a5-cards.less
@a5-card-bg: gray;
@grayLightest: #c9c9c9;custom.less
Results
Red Flags
- Overwriting rules through specificity
- Re-declaring attributes often (float, margin, color, border, etc.)
- Using "!important"
- Getting deeper than 3 levels

Wrap-up
- Old way
	- Code base gets bloated, unorganized over time
- Have to be an expert in css just to add simple styles
- Specificity Wars
 
- New way
	- Easy developer ramp-up
- Easy customization
- More reuse
- Smaller code base
- Avoid specificity wars
- Possible HTML bloat
- More classes to know
 
Resources
- Me
- https://fronteers.nl/congres/2009/sessions/object-oriented-css
Any Questions?
Agent5 CSS
By Craig Jennings
Agent5 CSS
- 184
