SMACSS in the Mix

Who am I?

@iamfiscus

iamfiscus.com

 

Player Product Team Lead @ Invodo 

Our Problem

  • CSS embedded on page client page
  • CSS for large scale app
  • Cross Team Standards
  • Whitelabeling

Solution

  • SASS / libSASS
  • SMACSS
  • Object Oriented
/* Config */
// Company
$css-prefix: 'preso';

// CSS3 defaults
// *-------------------------------------------------------------------------------
// $default-box-sizing: border-box;


/////// Typography configuration
// *-------------------------------------------------------------------------------
$font-size: 14;

$heading-1: 46;
$heading-2: 32;
$heading-3: 28;
$heading-4: 18;
$heading-5: 18;
$heading-6: 18;

$line: $font-size * 1.5;
$small-point-size: 10;
$large-point-size: 14;

$primary-font-family: #{"Helvetica Neue", Arial, sans-serif};
$secondary-font-family: #{"Helvetica Neue", Arial, sans-serif};
$heading-font-family: #{"Helvetica Neue", Arial, sans-serif};

/////// Default directory prefix
// *-------------------------------------------------------------------------------
$prefixDir: "preso/";

/////// Default webfont directory
// *-------------------------------------------------------------------------------
$fontDir: $prefixDir+"fonts/";

/////// Default image directory
// *-------------------------------------------------------------------------------
$imageDir: $prefixDir+"images/";

/////// Default icon directory
// *-------------------------------------------------------------------------------
$iconDir: $prefixDir+"icons/";

/////// OOCSS generic base colors
// *-------------------------------------------------------------------------------
$alpha-primary:   #9CCC3D;        // green
$bravo-primary:   #3e4147;        //
$charlie-primary: #FF0000;        // red
$delta-primary:   #2a2c31;        // blue
$echo-primary:    #dfba69;        // accent

$alpha-gray:      #666;           // gray

$error-primary:   $charlie-primary; // red

/////// Color math
// *-------------------------------------------------------------------------------
@import "color-scale";


/////// Semantic variables
// *-------------------------------------------------------------------------------
// abstract 'white' value to easily applied to semantic class objects
$white:                                #fff;
$black:                                #000;

// primary header font color
$primary-header-color:                 $alpha-gray;

// default heading font weight
$heading-font-weight:                  normal;

// primary font color for the app
$primary-text:                         $alpha-gray;

// default `href` link color
$href-color:                           $delta-color;

// default shadow colors
$shadow-color:                         fade-out($alpha-color, 0.5);

// default border color
$border-color:                         $alpha-color;

$bg-opacity:                           .55;


/////// HTML 5 feature colors
// *-------------------------------------------------------------------------------
// used with the `ins` tag
// http://www.w3schools.com/tags/tag_ins.asp
$ins-color:                            $alpha-primary;

// used with the `mark` tag
// http://www.w3schools.com/html5/tag-mark.asp
$mark-color:                           $alpha-primary;

// webkit tap highlight color
$webkit-tap-hightlight:                $alpha-primary;

// overrides the default content selection color in the browser
$selection-color:                      $alpha-primary;
$selection-text-color:                 $white;


/////// @media breakpoint defaults
// *-------------------------------------------------------------------------------
$tablet:                    "screen and (max-width: 64em)";
$tablet-portrait:           "screen and (max-width: 50em) and (orientation: portrait)";
$tablet-landscape:          "screen and (max-width: 50em) and (orientation: landscape)";

$mobile:                    "screen and (max-width: 30em)";
$mobile-portrait:           "screen and (max-width: 30em) and (orientation : portrait)";
$mobile-landscape:          "screen and (max-width: 30em) and (orientation : landscape)";

// MODULES
/////// Grid
// *-------------------------------------------------------------------------------
$grid-columns  : 12;
$grid-max-width: 65em;


/* Import */
@import 'base/manifest';
@import 'layout/manifest';
@import 'modules/manifest';
@import 'states/manifest';
@import 'themes/manifest';
  • Config
  • Import

Sturcture

/* SASS Variable */
$css-prefix: 'preso-';


/* SASS Mixin */
@mixin vertical-align($value: 50) {
    position: relative;
    top: 50%;
    transform: translateY(-#{$value}%);
}

  • Variables
  • Mixins

SMACSS

Written by Jonathan Snook

 

 

  • Base
  • Layout
  • Modules
  • States
  • Theme

Sturcture

  • Master
  • Configuration
  • Folder
  • Manifest
  • Naming Rules
/* Naming Rules */

prefix
- js
- css
- test

Base

  • Reset
  • Elements
  • Typography
  • Icons
  • Animations
/* Reset */
// normalize.css : http://necolas.github.io/normalize.css/

/* Element */
a {
    color: green;
}

/* Typography */
.#{$css-prefix}-primary-font {
  font-family: $primary-font-family;
  font-weight: $heading-font-weight;
  color      : $primary-text;
}


/* Icons */
@font-face {
    font-family:"icons";
    src:url("fonts/icons-a30cdf980443d9e6f8d38daeb7a9c17d.eot");
    font-weight:normal;
    font-style:normal;
}
@font-face {
    font-family:"icons";
src:url("fonts/icons-a30cdf980443d9e6f8d38daeb7a9c17d.eot");
src:url("fonts/icons-a30cdf980443d9e6f8d38daeb7a9c17d.eot?#iefix") format("embedded-opentype"),
		url("fonts/icons-a30cdf980443d9e6f8d38daeb7a9c17d.woff") format("woff"),
		url("fonts/icons-a30cdf980443d9e6f8d38daeb7a9c17d.ttf") format("truetype"),
		url("fonts/icons-a30cdf980443d9e6f8d38daeb7a9c17d.svg?#icons") format("svg");
font-weight:normal;
font-style:normal;
}

.#{$css-prefix}-icon {
    font-family:"icons";
    display:inline-block;
    position: relative;  // added this style to work with absolute positioning of other things related to icon
    vertical-align:middle;
    line-height:1;
    font-weight:normal;
    font-style:normal;
    speak:none;
    text-decoration:inherit;
    text-transform:none;
    text-rendering:optimizeLegibility;
    -webkit-font-smoothing:antialiased;
    -moz-osx-font-smoothing:grayscale;
}

.#{$css-prefix}-icon.#{$css-prefix}-icon--cc:before {
    content: "\f101";
}

/* Animation */
// animate.css : http://daneden.github.io/animate.css/

Layout

  • Header
  • Nav
  • Main
  • Footer
  • Side Bar
  • Grid
.sidebar {
    margin: 20px;
}


// Container
.#{$css-prefix}-wrapper {
  width: 95%;
  max-width: $grid-max-width;
  margin: 0 auto;
}
.#{$css-prefix}-wrapper,
.#{$css-prefix}-row {
  @extend %clearfix;
  box-sizing:border-box;
  -moz-box-sizing:border-box;
  -webkit-box-sizing:border-box
}
.#{$css-prefix}-wrapper:after,
.#{$css-prefix}-row:after {
  content: "";
  display: table;
  clear: both;
}
[class*=#{$css-prefix}-col-] {
  float: left;
  padding: .10em;
  width: 100%;
  min-height: 1px;
}
// GRID MEASURMENTS
@for $i from 1 through $grid-columns {

  .#{$css-prefix}-col-#{$i} {
    width: 100% / $grid-columns * $i;
  }

}

Module

  • Naming Conventions
  • Sub Module
  • Sub Container
/* Module */
.#{$css-prefix}-btn {
  background-color: $alpha-gray;
  height: 47px;
  width: 100%;
  color: $white;
  padding: 10px;
}
// Sub Module
.#{$css-prefix}-btn {
  &.#{$css-prefix}-btn--alpha {
    background-color : $alpha-primary;
  }
}
// Sub Container
.#{$css-prefix}-modal {
  .#{$css-prefix}-modal__header {
     ...
  }
  .#{$css-prefix}-modal__main {
     ...
  }
  .#{$css-prefix}-modal__footer {
     ...
  }
}

State

/* Module */
.#{$css-prefix}-btn:disabled {
  cursor: 
}
// Sub Module
.#{$css-prefix}-btn--alpha-is-invalid {
    border: 1px solid $error-color;
}
  • Peusudo
  • Is notation

Theme

.#{$css-prefix}-theme--grass {

    .#{$css-prefix}-btn:disabled {
        background-color: green; 
    }
    
    .#{$css-prefix}-btn--alpha-is-invalid {
        border: 1px solid green;
    }
}