Sass Documentation

If you want to use your own naming conventions, or if you're just curious to see how the Sass for Unsemantic works "under the hood," this page covers how Sass is been used to build the CSS output.


Breakpoints

Within the _unsemantic-grid-responsive.scss file, three other Sass partials are assembled within media queries, to create a responsive CSS file. These partials can also be compiled together without a @media query (or compiled separately), for handling older IE versions.

The $media-mobile-max variable is set to a default of 767px, and $media-desktop-min defaults to 768px. This 767|768 breakpoint is where the Unsemantic grid will pivot between a "mobile" or "desktop" layout.

768px is the narrowest width of an iPad (arguably the most popular tablet) in portait orientation, allowing it to have a "desktop" layout. Whereas, anything below that width gets a "mobile" layout, which can be tailored to smaller screens.

/* ============================================ */
/* This file has a mobile-to-desktop breakpoint */
/* ============================================ */

$media-mobile-max: 767px !default;
$media-desktop-min: 768px !default;

@import "unsemantic-vars";
@import "unsemantic-ie-snap";

@include unsemantic-grid-placeholders;
@include unsemantic-grid-base(mobile, desktop);

@media screen and (max-width: $media-mobile-max) {
  @include unsemantic-grid-placeholders(mobile);
  @include unsemantic-grid-scoped(mobile);
}

@media screen and (min-width: $media-desktop-min) {
  @include unsemantic-grid-placeholders(desktop);
  @include unsemantic-grid-scoped(desktop);
}

The _unsemantic-grid-responsive-tablet.scss file is similar, except it also adds support for a tablet width, between the mobile and desktop breakpoints. This file has additional variables named $media-tablet-min and $media-tablet-max. This makes for two breakpoints: 767|768 and 1024|1025.

/* ================================================================== */
/* This file has a mobile-to-tablet, and tablet-to-desktop breakpoint */
/* ================================================================== */

$media-mobile-max: 767px !default;
$media-tablet-min: 768px !default;
$media-tablet-max: 1024px !default;
$media-desktop-min: 1025px !default;

@import "unsemantic-vars";
@import "unsemantic-ie-snap";

@include unsemantic-grid-placeholders;
@include unsemantic-grid-base(mobile, tablet, desktop);

@media screen and (max-width: $media-mobile-max) {
  @include unsemantic-grid-placeholders(mobile);
  @include unsemantic-grid-scoped(mobile);
}

@media screen and (min-width: $media-tablet-min) and (max-width: $media-tablet-max) {
  @include unsemantic-grid-placeholders(tablet);
  @include unsemantic-grid-scoped(tablet);
}

@media screen and (min-width: $media-desktop-min) {
  @include unsemantic-grid-placeholders(desktop);
  @include unsemantic-grid-scoped(desktop);
}

Default Variables

At the top of the _unsemantic-vars.scss file, there are several variables upon which some of the other Sass files depend. These are provided with initial values, in lieu of a specific value being defined. This is done via the !default keyword.

$unsemantic-ie7-support: true !default;

$unsemantic-prefix-suffix-support: true !default;

$unsemantic-push-pull-support: true !default;

$container-max-width: 1200px !default;

$gutter-half: 10px !default;

$lang-forward: left !default;

$lang-reverse: right !default;

Since all of these values are set only if the variables are not already defined, to override them simply create your own _vars.scss partial (or name it whatever you like), and @import it before the any of Unsemantic's Sass files. Anything you set will take precedence, and anything you leave undefined will get a default value. Here is an example…

// ==============================
// Example application.scss file.
// ==============================

// Turn off IE7 support.
$unsemantic-ie7-support: false;

@import "partials/vars";
@import "partials/reset";
@import "partials/text";
@import "partials/site";
@import "partials/unsemantic-grid-responsive";

The following is an explanation of what each variable pertains to.

$unsemantic-ie7-support

This variable defaults to true, causing code to be generated to support Internet Explorer 7. This fakes box-sizing and addresses some rounding errors when dealing with CSS percentages. In the respository download, there are flat CSS versions of Unsemantic with, and without, IE7 support. They are differentiated by no-ie7 in the file name.

You can see the differences by comparing these two files…

Specifically used to patch IE7 deficiencies, expression(…) code is omitted from the no-ie7 version.

If you don't need to support IE7, just set this variable to false at the highest level scope. Be sure it preceeds Unsemantic's *.scss files in @import order. As a result, no CSS specific to IE7 will be generated.

$container-max-width

This is the widest that grid-container will go, after which it will remain at a "fixed" width. Setting a max-width ensures that line lengths stay within a readable range. If you'd rather this be narrower or wider, you can just create a variable with the same name, in your own _vars.scss file.

$gutter-half

This value controls how much padding each grid-x unit recieves on the left/right. It defaults to 10px. If you set this value to 0 to override the default, the corresponding padding-left and padding-right will not be generated in CSS (smaller file size).

$lang-*

The $lang-forward and $lang-reverse variables are to aid in writing one codebase that can be "flipped" to support either left-to-right or right-to-left languages. They default to left and right respectively (for languages like English and Spanish), but can be defined ahead of time to support right-to-left languages such as Hebrew or Arabic.

//
// For right-to-left languages.
// (Hebrew, Arabic, etc.)
//
$lang-forward: right;
$lang-reverse: left;

@import "partials/unsemantic-grid-responsive";

Depicted above are the contents of the unsemantic-grid-base-rtl.scss file. This causes all grid-x units to float to the right, instead of to the left. It also reverses the direction of all prefix-x, suffix-x, push-x, and pull-x classes.


Scope

Due to some changes in how the compiler works in Sass 3.3 and newer, scoped placeholders are made available by passing a single parameter to unsemantic-grid-placeholders.

If you want to make these placeholders available in the global scope, that would look like this…

@import "unsemantic-vars";

@include unsemantic-grid-placeholders;

// Your code can now use %grid-container, etc.

.grid-container {
  @extend %grid-container;
}

If you wanted to make these placeholders available within the scope of @media query, you could do this…

@import "unsemantic-vars";

@media screen and (max-width: 767px) {
  @include unsemantic-grid-placeholders(mobile);

  // Your code can now use %mobile-grid-50, etc.

  .mobile-grid-50 {
    @extend %mobile-grid-50;
  }
}

Placeholders

Everything revolves around the concept of Sass placeholder selectors (sometimes referred to as silent classes) generated by invoking the unsemantic-grid-placeholders mixin contained in the _unsemantic-vars.scss file.

%grid-container

This is used by the grid-container class, and keeps the grid layout centered within the browser viewport if the browser is wider than the $container-max-width. It also has 10px of padding on the left/right by default.

%#{$scope}grid-container {
  @extend %#{$scope}clearfix;
  margin-left: auto;
  margin-right: auto;

  @if $container-max-width != none {
    max-width: $container-max-width;
  }

  // Set if gutter is non-zero.
  @if $gutter-half != 0 {
    padding-left: $gutter-half;
    padding-right: $gutter-half;
  }
}

%grid-columns-all

This is the placeholder extended to add left/right padding to all grid-x units, as well as changing their box-sizing to border-box, allowing us to have a fluid, percentage based width coupled with additional padding on each side (without increasing the overall width).

%#{$scope}grid-columns-all {
  @include box-sizing(border-box);

  // Set if gutter is non-zero.
  @if $gutter-half != 0 {
    padding-left: $gutter-half;
    padding-right: $gutter-half;
  }
}

%grid-parent

This is used by the grid-parent class, to zero out left/right padding on a grid-x unit that also contains grid-x children, since the child elements have their own padding already.

// Remove padding, if it's being used
// as a parent for other grid columns.
%#{$scope}grid-parent {
  padding-left: 0;
  padding-right: 0;
}

%grid-columns-push-pull

This is used by all push-x and pull-x classes, which need to be relatively positioned in order for left and right offsets to have any effect. By default, all grid-x units inherit the browser native static positioning.

// Allows columns to be offset +/- left.
%#{$scope}grid-columns-push-pull {
  position: relative;
}

Sass Loops

The folowing code is contained in the _unsemantic-vars.scss file. It loops through and generates placeholders for %grid-x, %prefix-x, %suffix-x, %push-x, and %pull-x for multiples of 5 up to 100.

These placeholders are used when the unsemantic-grid-scoped mixin is invoked, where the styles are paired with classes by the same name.

If called with a scope parameter — such as mobile, tablet, or desktop — then the respective placeholders that are generated would look like: %mobile-grid-x, %tablet-grid-x, and %desktop-grid-x.

// For 5 through 95 percent.
@for $i from 1 through 19 {
  $num: $i * 5;
  $decimal: $num / 100;
  $percent: $num * 1%;

  %#{$scope}grid-#{$num} {
    float: $lang-forward;
    width: $percent;
  }

  %#{$scope}prefix-#{$num} {
    margin-#{$lang-forward}: $percent;
  }

  %#{$scope}suffix-#{$num} {
    margin-#{$lang-reverse}: $percent;
  }

  %#{$scope}push-#{$num} {
    #{$lang-forward}: $percent;
  }

  %#{$scope}pull-#{$num} {
    #{$lang-forward}: $percent * -1;
  }
}

This next loop does essentially the same thing as the preceeding code, except it applies to %grid-33, %grid-66, %prefix-33, etc.

// For one-third and two-thirds.
@for $i from 1 through 2 {
  $num: $i * 33;
  $one-third: 1 / 3;
  $decimal: $i * $one-third;
  $percent: ($num + $decimal) * 1%;

  // Percentage based widths.
  %#{$scope}grid-#{$num} {
    float: $lang-forward;
    width: $percent;
  }

  // Prefix, to add extra columns before.
  %#{$scope}prefix-#{$num} {
    margin-#{$lang-forward}: $percent;
  }

  // Suffix, to add extra columns after.
  %#{$scope}suffix-#{$num} {
    margin-#{$lang-reverse}: $percent;
  }

  // Push & Pull, to rearrange column order (for potential "SEO").
  %#{$scope}push-#{$num} {
    #{$lang-forward}: $percent;
  }

  %#{$scope}pull-#{$num} {
    #{$lang-forward}: $percent * -1;
  }
}

Extending

For these placeholders to be used, they must be called with @extend. If they are not used, then no code for them is ever generated. While the Unsemantic codebase itself of course makes use of all the placeholders, you could easily mix and match, generating only the CSS you need.

Here's an example of how Unsemantic's class names make use of the various placeholders, in the _unsemantic-vars.scss file.

// For 5 through 95 percent.
@for $i from 1 through 19 {
  $num: $i * 5;

  // Percentage based widths.
  .#{$class}grid-#{$num} {
    @extend %#{$scope}grid-#{$num};
  }

  // Prefix, to add extra columns before.
  .#{$class}prefix-#{$num} {
    @extend %#{$scope}prefix-#{$num};
  }

  // Suffix, to add extra columns after.
  .#{$class}suffix-#{$num} {
    @extend %#{$scope}suffix-#{$num};
  }

  // Push, to rearrange column order (for potential "SEO").
  .#{$class}push-#{$num} {
    @extend %#{$scope}push-#{$num};
  }

  // Pull, to rearrange column order (for potential "SEO").
  .#{$class}pull-#{$num} {
    @extend %#{$scope}pull-#{$num};
  }
}

Roll Your Own

However, let's say you had a simple two column layout, with a main content area and a sidebar, contained by a parent element. Presupposing this HTML…

<div class="layout">
  <div class="main">
    This is my main content
  </div>
  <div class="sidebar">
    This is my sidebar
  </div>
</div>

You could generate some custom CSS by putting this in your own Sass file…

$media-mobile-max: 767px;
$media-desktop-min: 768px;
$unsemantic-ie7-support: false;

@import "partials/unsemantic-vars";
@import "partials/unsemantic-ie-snap";

/* =========== */
/* All screens */
/* =========== */

@include unsemantic-grid-placeholders;

.layout {
  @extend %grid-container;
}

.main,
.sidebar {
  @extend %grid-columns-all;
}

/* ===================== */
/* "Mobile" screen width */
/* ===================== */

@media screen and (max-width: $media-mobile-max) {
  @include unsemantic-grid-placeholders(mobile);

  .main,
  .sidebar {
    @extend %mobile-grid-100;
  }
}

/* ====================== */
/* "Desktop" screen width */
/* ====================== */

@media screen and (min-width: $media-desktop-min) {
  @include unsemantic-grid-placeholders(desktop);

  .main {
    @extend %desktop-grid-75;
  }

  .sidebar {
    @extend %desktop-grid-25;
  }
}

That would generate just enough CSS for a mini responsive page layout…

@media screen and (max-width: 400px) {
  @-ms-viewport {
    width: 320px;
  }
}

/* =========== */
/* All screens */
/* =========== */

.layout:before,
.layout:after {
  content: ".";
  display: block;
  overflow: hidden;
  visibility: hidden;
  font-size: 0;
  line-height: 0;
  width: 0;
  height: 0;
}

.layout:after {
  clear: both;
}

.layout {
  margin-left: auto;
  margin-right: auto;
  padding-left: 10px;
  padding-right: 10px;
  max-width: 1200px;
}

.main,
.sidebar {
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
  padding-left: 10px;
  padding-right: 10px;
}

/* ===================== */
/* "Mobile" screen width */
/* ===================== */

@media screen and (max-width: 767px) {
  .main:before,
  .sidebar:before,
  .main:after,
  .sidebar:after {
    content: ".";
    display: block;
    overflow: hidden;
    visibility: hidden;
    font-size: 0;
    line-height: 0;
    width: 0;
    height: 0;
  }

  .main:after,
  .sidebar:after {
    clear: both;
  }

  .main,
  .sidebar {
    clear: both;
    width: 100%;
  }
}

/* ====================== */
/* "Desktop" screen width */
/* ====================== */

@media screen and (min-width: 768px) {
  .sidebar,
  .main {
    float: left;
  }

  .sidebar {
    width: 25%;
  }

  .main {
    width: 75%;
  }
}