Introduction

Another very useful feature of Sass are mixins. Mixins allow you to re-use chunks of CSS. Like functions, they can accept arguments, giving you ultimate flexibility.

Respond

The respond mixin lets your layout and supporting styles respond to various screen sizes. It is the heart and soul of Gumby's responsive grid. Don't break Gumby's heart, or else.

You may be asking yourself "How does one yield such power with both love and care? Doesn't true love sometimes mean breaking someones heart for their betterment?" Well, we have no idea, but here's how to use the respond mixin:

What does it mean to respond?

The ultimate goal is to make your site viewable, readable and fast at any screen size. Responding to different screen sizes is one tool towards this goal.

Using the respond mixin, we can optimize our styles for phones, tablets, desktop and any other screen sizes. This is what it means to "respond" - styles will respond accordingly to any screen size. Under the hood, Gumby is using Sass to generate the correct media queries.

Respond Examples

Time for a revelation: Phones have small screens! Because of this, longer headers might get pushed off-screen. Let's say we want to word wrap our headers so that they fit within the smaller layout of a phone. Here's what that could look like:

/* This is actually already in Gumby */
@include respond(all-phones) {
  h1,h2,h3,h4,h5,h6 { word-wrap: break-word;}
}

Another revelation: Some people have huge screens! Let's give them really big headlines, because big fonts are all the rage:

@include respond(large-screens) {
  /* Your font is so big, it's absurd! */
  h1,h2,h3,h4,h5,h6 {  @include font-size($absurd); }
}

Typography is all well an good, but often you need to tweak your layout on certain screen sizes. For example, if you might find yourself needing to adjust margin or padding to some elements. You can simply target your HTML with the respond mixin desired:

#image-box figure.four.columns {
  /* Change margin on tablets in portrait mode */
  @include respond(portrait-tablets) { 
    margin-bottom: 30px; 
  }
}

Perhaps you want to change the natural stacking of elements on smaller screen sizes. For example, if you want a row with 4 columns to flow down to 2 columns on tablets when in portrait mode, you might do something like this:

#pricing .four.columns {
  /* Change to 50% width so you get 2 per row */
  @include respond(portrait-tablets) { 
    width: 50%; float: left;
  }
}

Screen Sizes Available

Out of the box, the screensizes available with Gumby are:

Media Targets
portrait-phones Phone-sizes devices in portrait mode
landscape-phones Phone-sizes devices in landscape mode
all-phones All phone sizes
portrait-tablets Tablet-sizes in portrait mode
tablets All tablet sizes
desktop Desktop sizes, including tablets in landscape mode. Basically, anything greater than 768px by default.
document-width Gumby's set max-width + 20px of padding. Note that you can, like anything, set the max-width variable yourself. The default is 960px.
large-screens Large screen sizes. This defaults to 2880px.
print Because your TPS report print-outs need love too!

Custom Media Queries

Lastly, you can also pass in your own media queries to this mixin!

.something.classy {
 @include respond("max-width: 1337px") {
     /* For having just the right screen width, 
         the classiest color available! */
    color: chartreuse;
  }
}

Semantic Grid

Use this series of mixins to build flexible, semantic grids which dont require the use of non-semantic class names inside of your markup structure.

Standard Grid

These are the core mixins used in the semantic grid. Use these where to create rows and columns from your semantic markup.

<section>
  <article>
    <p>I’m speaking Russian</p>
  </article>
  <aside>
    <p>Wibbly Wobbly</p>
  </aside>
</section>

This bit of SCSS will create a full width <section> with an eight column <article> and a four column <aside> (sidebar).

section {
  @include row();
}
article {
  @include column(8);
}
aside {
  @include column(4);
}

This mixin creates rows. It supports only one argument which is optional. For a regular row, just use @include row();

@include row($nested);
// $nested: Optional. Set to ‘false’, can be ‘false’, or ‘nested’

This mixin creates columns.

@include column($columns, $alignment, $behavior, $hybrid);
@include hybrid($columns, $alignment, $behavior, $hybrid);
// $columns: an integer, the number of columns for your element
// $alignment: Optional. set to ‘false’, can be ‘false’, or ‘center’
// $behavior: Optional. set to ‘false’, can be ‘false’, or ‘collapse’
// $hybrid: Optional. set to 'false', can be 'false', or hybrid

Push

Use this to push a column to the right by a number of columns.

@include push($columns, $hybrid-grid);
// $columns: an integer, the number of columns to push your element
// $hybrid: Optional. set to ‘false’, can be ‘false’, or ‘hybrid’

Pull

Use this to pull a column to the left or right by a number of columns. Should be used in conjunction with a @include push($columns) being applied to one or more of its siblings.

@include pull($direction, $columns, $width, $hybrid-grid);
// $direction: Optional. set to ‘false’, can be ‘false’, 'none', ‘left’, or ‘right’
// $columns: Optional. set to ‘0’, can be any integer (Your Pull Width)
// $width: Optional. set to ‘0’, can be any integer (Your Column Width)
// $hybrid: Optional. set to ‘false’, can be ‘false’, or 'hybrid'

Hidden/Visible

The Hidden/Visible mixins (also referred to as the "visibility" mixins) that comes with Gumby are perfect for those times where you wish you could hide things at certain screen sizes. In a nutshell, adding this mixin allows you to control visibility of an item depending on screen size.

Here's some quick examples

Here we can see that an element with the class "dont-show-me-on-phones" will be hidden on portrait oriented tablets, but visible on landscape:

.dont-show-me-on-phones{
  @include hidden(portrait-tablets);
  @include visible(tablets);
}

You can also choose what is visible or invisible on all phones or all tablets:

.show-on-all-phones{
 @include visible(all-phones);
}

You could also use the following mixins to create your own show and hide classes.

.hide-on-tablets{
  @include hidden(tablets);
}

Then applying this class to elements in your pages will hide them when browsing on a tablet device.

Note that you can use any of the $media variables defined in the respond mixin, such as tablets, landscape-phones, desktop and so on.

Modular Scale

Gumby uses Modular Scale, which lets developers and designers scale font-sizes at a specific ratio, rather than arbitrary pixel values.

As developers, there's a few things that you should know while implementing a modular scale into your pages. For example the default ratio in Gumby is the golden ratio, or 1.618. In practice, this is what the sizes would be:

Pixels Ems Ems @ 16
87.000 1 5.438
76.245 0.876 4.765
53.770 0.618 3.361
47.123 0.542 2.945
33.232 0.382 2.077
29.124 0.335 1.82
20.539 0.236 1.284
18.000 0.207 1.125

Confusing graph, we know, but hang in there. Look on the left most side you have the gradation of pixel sizes. Up on top, is your <h1> size. 87px. Next on the list is your <h2> and so on. Making a little more sense now? Now if you look over to the next column, you'll see the latest craze in web font sizing technology. The em. (crowd ooo's and ahh's) Em's are essentially a ratio of the parent elements size. Check out this example:

body{
    font-size: 16px;
}

.inside_the_body{
    font-size: .5em;
}

So your .inside_the_body class' text size will now be 8px but it's represented as .5em, or half the 16px. Mathematical!

Now we travel back to your _settings.scss file, where we have 87px and 16px as our $importantNum and $base-font-size. The graph above is a visual representation of the the sizes in between those two numbers. With modular-scale, all this math is done for you and is easily changeable. As is the ratio. Try some out at modularscale.com. And here is Gumby's defaults on that same site for reference.

If you have designers on your team make sure they use the modular-scale before and during designing. It'll make your job as a developer much easier, as the values they used in their PSD's are already in the Gumby css. Algebraic!

Getting back to Gumby, pretty much everything you'll need out of modular-scale is handled in var/_settings.scss.

// Modular Scale Settings
// http://www.modularscale.com by Tim Brown
// https://github.com/scottkellum/modular-scale
$ratio: golden();                       // Ratio for Modular Scale
$base-font-size: 16px !default;
$importantNum: 78px !default;
$base-size: $base-font-size $importantNum;

$ratio

Change this to whatever ratio tickles your fancy. Check out a full list of the different ratios to use in Gumby.

$base-font-size

This is the font size for your body copy. We recommend 16px or higher, but this varies on individual fonts.

$importantNum

This is the size of your biggest element; your <h1>. Change this value and the entire scale will shift to reflect it.

$base-size

This variable is used by modular-scale so you shouldn't need to touch it under normal circumnstances. It is merely providing the function with the font sizes to make up the scale.

Fancy Tiles

Easily create grided layouts that respond gracefully. Fancy Tiles shift the number of columns in a grid at predefined breakpoints. The mixin accepts 3 values, the first is the number of columns to display an element at desktop resolution, the second is tablet, and the third value is mobile.

You can optionally pass in three more arguments to change the predefined breakpoints.

// This will create a product grid that is 
// 4 columns on desktop, 2 on tablets, and
// 1 column on mobile devices.

#my-product-grid-container li.product {
  @include fancytiles(4,2,1);
  min-height: 300px;
  height: auto;
}

// 4 columns on desktop, 2 at 600px and,
// 1 column on mobile devices
#my-different-grid-container li.product {
  @include fancytiles(4,2,1, $min-device-width, '600px', $row-max-width);
  min-height: 300px;
  height: auto;
}

Font Size

Recent developments in the CSS world has created the rem. While the actual font-size of an em is relative to a parent element, the actual font-size of a rem is relative to the root of an HTML document - the html tag.

Underneath the hood, Gumby uses rem, with a good old fashioned px fallback. The font-size mixin is there to make this easy.

Examples

Let's start simple. If you want to work in px, you can do so! Gumby will calculate a rem value for you. The following shows using a px value to get the appropriate rem.

.mini-title {
  /* If your base font-size is 16px, 
     you'll get a rem value of 1.125  */
  @include font-size(18px);
}

Now we can get a little more complex. Gumby uses modular-scale, which lets designers scale font-sizes at a specific ratio, rather than arbitrary pixel values.

In Gumby's settings file, we can see that modular-scale is used to set our default font-sizes as variables. These variables are convenient ways to keep your site's font-sizes consistent. Let's see that in action with some SCSS you may write:

.mini-title {
  @include font-size($med);
}

.large-title {
  @include font-size($large);
}

This is the recommended way of using the font-size mixin. You can set your default font sizes in the settings file (if you want to stray from the defaults) and then use those variables throughout your SCSS.

Of course you can pass in any modular-scale value you like, rather than a variable:

.another-title {
  @include font-size(ms(4));
}

If you're itching for more information on modular-scale, read more here, or check out the Modular Scale Github repository. Lastly, you can play with modular-scale, including testing the various available ratios, at http://modularscale.com/.

Ems

The ems mixin converts pixels to ems.

For a relational value (em), the input (px value) is calculated against the value of its context. The default context is 16px. You can change the context by passing an optional second value into the mixin.

.mycooldiv {
  width: em(300px);
  font-size: em(14, 21);
}
Outputs
.mycooldiv {
  width: 18.75em;
  font-size: 0.66667em;
}

Even

Test for even numbers, do something with the result

@mixin my-cool-mixin($cols) {
  @if even($cols) != false {
    //  do this
  }
  @else {
    // do this other thing
  }
}

Palette

Quickly compose an element which matches your color palette. The palette mixin. It accepts two arguments, $shade which creates the background color properties of the elements, and $palette-text-color which is optional and defines the text color of the element. If $palette-text-color is not defined then the text color is determined based on its $shade.

// $shade accepts all Gumby color palette strings
  // in addition to custom hex colors and color variables.

  @include palette($shade, $palette-text-color);

Shapes

Use the shapes mixin to quickly shape an element. The $shape argument accepts square, oval, circle, pill-left, and pill-right values. You can also use the optional $shape-radius argument to use the shapes mixin to define a custom border radius.

@include shape($shape, $shape-radius);

You simply have to try it.