SassyHash

Introducing SassyHash

In Sass 3.3 maps were introducted. When creating a map from within a Sass extension you need to pass in a hash that has its keys and values be instances of Sass::Script::Value::*.

hash = {Sass::Script::Value::String.new('foo') => Sass::Script::Value::String.new('bar')}
map = Sass::Script::Value::Map.new(hash)

SassyHash is a courier class for transforming ruby hashes into something that Sass maps can accept.

Examples

Standard Example

hash = {:foo => :bar}
map = Sass::Script::Value::Map.new(SassyHash[hash])
map.class #=> Sass::Script::Value::Map

It also works with nested hashes lists etc..

hash = {:foo => :bar => :baz}
map = Sass::Script::Value::Map.new(SassyHash[hash])
map.value[Sass::Script::Value::String.new('foo')].class #=> Sass::Script::Value::Map

Links

Remove Cruft From Raspberry Pi

Below is the apt-get remove for cleaning all the gui packages off the default raspberian install

xserver* x11-common x11-utils x11-xkb-utils x11-xserver-utils xarchiver xauth xkb-data console-setup xinit lightdm libx{composite,cb,cursor,damage,dmcp,ext,font,ft,i,inerama,kbfile,klavier,mu,pm,randr,render,res,t,xf86}* lxde* lx{input,menu-data,panel,polkit,randr,session,session-edit,shortcut,task,terminal} obconf openbox gtk* libgtk* alsa* nano python-pygame python-tk python3-tk scratch tsconf

Introduction to Building Websites Using Susy and Compass’s Vertical Rhythm

Preface

I’m going to be making assumptions that you know the following concepts: Responsive design, and Grid based layout. If you do not have a good grasp on these concepts you may want to do some research before diving in to this exercise.

What is susy?

via Susy Homepage

Susy is different – a simple grid system that is fully customized to your markup, your grid, your designs, the way you want them. All gain, no pain.

via 24 ways

What is Vertical Rhythm?

The spacing and arrangement of text as the reader descends the page

Getting Started

For this tutorial I’m going to use susy in a rails environment but every thing I do should be possible in a stand alone configuration

First, Add the susy gem to your Gemfile below compass

gem 'compass'
gem "compass-susy-plugin", "~> 0.9", :require => 'susy'

Next, open your stylesheets directory and create a _susy_defaults.scss file. The contents of this file should look something like this:

//**
//  Susy: Un-obtrusive grids for designers
//  By: Eric A. Meyer and OddBird
//  Site: susy.oddbird.net
//**

// Settings --------------------------------------------------------------
// Susy & Compass use HTML hacks to support IE 6 and 7. You can turn that off:
// $legacy-support-for-ie6 : false;
// $legacy-support-for-ie7 : true;

// Font Sizes --------------------------------------------------------------
$relative-font-sizing : false;
$base-font-size       : 13px;
$base-line-height     : 20px;

// Grid --------------------------------------------------------------

$total-cols         : 16;
$col-width          : 40px;
$gutter-width       : 20px;
$side-gutter-width  : 10px;

// Don't move this @import above the GRID variables.

@import "susy";

Note: I didn’t use the compass command line tool to install the partials

Lets recap what is going on in this file.

  • $relative-font-sizing is part of compass’s vertical rhythm module that allows you to enable the use of em’s or px’s I always work in pixels for my fonts so I set it to false (Default is true).
  • $base-font-size describes the font size of your primary text though out the site and is also part of vertical rhythm module.
  • $base-line-height tells compass to generate a horizontal grid that is in this case 20px high and contains a default font of 13px.
  • $total-cols describes how many columns your grid will have if this doesn’t make much sense the graphic should visualize this better.
  • $col-width describes the width of each column.
  • $gutter-width describes the distance between each column.
  • $side-gutter-width describes the left and right most gutter of the gird layout (see below).
  • @import "susy"; this import directive loads susy and starts the magical fun times!

Grid Example

Please note that this graphic is a bit misleading I have modified susy’s susy-grid-background mixin to show my vertical rhythm (below)

@mixin susy-grid-background {
  @include grid-background($total-cols, $col-width, $gutter-width, $base-line-height, $side-gutter-width, $force-fluid: true);
}

Hooking it up to your application

Now that we have susy and the vertical rhythm configured lets set up our screen.scss to actually apply these settings.

@import "compass" ;
@import "compass/reset";
@import "susy_defaults";

// My Override mixin
@mixin susy-grid-background {
  @include grid-background($total-cols, $col-width, $gutter-width, $base-line-height, $side-gutter-width, $force-fluid: true);
}

// establish your vertical baseline grid.
@include establish-baseline;


// extend this class to show your grid.
.grid {
  @include susy-grid-background;
}

section.content {
  // calling susy's container mixin will apply the grid to that element.
  @include container;
}

Lets recap what is going on in this file.

  • @import "compass" loads compass.
  • @import "compass/reset" resets the browsers default style sheet.
  • @mixin susy-grid-background is the override mixin I created to show my horizontal lines.
  • @include establish-baseline sets the body’s line height to what ever you set $base-line-height to above.
  • .grid is an extendable class you can use if you need to see the grid visibly while your developing ill get into this a bit later.
  • section.content is out main content container for our application and calling the @include container mixin will apply the susy grid scoped to that container so you can actually have multiple grids on a page but I do not recommend this.

Understanding the helper functions and mixins

Susy

Sadly, this is the part that really confused me for awhile susy’s documentation of the mixins and functions it provides are a bit lackluster the tutorial as some information but not much. There is a gist that describes them but it was never published on the susy website. Most of the content here is copied from that gist for easy reference.

Terms

  • Container: The root element in a Susy Grid. Anything inside it is a potential Grid Element.
  • Context: Either root (default) or the number of columns spanned by the parent Grid Element.
  • Root Context: When the Container is the nearest Grid Element ancestor.
  • Column: The main unit of horizontal content measurement.
  • Alpha: Any Grid Element spanning the first Column in its Context.
  • Omega: Any Grid Element spanning the last Column in its Context.
  • Full: Any Grid Element spanning both the first and last Columns in its Context.
  • Gutter: The space between Columns. Added as margin after each Grid Element, and included in the internal width of a Grid Element that spans multiple Columns.
  • Side Gutter: Space between the Susy Grid and the edge of the document on either side. Added as margin before Alpha and after Omega elements in the Root Context.

Mixins

  • container()

    • Apply to the outer grid-containing element. This element will act as the Container for your Susy Grid.
  • columns(number [, context, from-direction])

    • Apply to any element to align it to the Susy Grid. This is now a Grid Element.
    • number ($n): Required number of Columns to span. This will become the Context for any children Grid Elements.
    • context ($c): Current nesting context if other-than-root. Default: false.
    • from-direction ($from): Direction from which the context flows. Default: $from-direction
  • alpha([context, from-direction])

    • Apply to any element with columns if that element will span the first Column in a given context. Alpha is only used to apply a Side Gutter in the Root Context, so it is never needed in any other Context.
    • context ($nested): The context, if other-than-root. Should always be false. Default: false.
    • from-direction ($from): Direction from which the context flows. Default: $from-direction
  • omega([context, from-direction])

    • Apply to any element with columns if that element will span the last Column in a given Context.
    • context ($nested): The context, if other-than-root. Default: false.
    • from-direction ($from): Direction from which the context flows. Default: $from-direction
  • full([context])

    • Shortcut for columns, alpha, and omega when an element should span its entire Context.
    • context ($nested): The context, if other-than-root. Default: false.
  • prefix(number [, context, from-direction])

    • Add Columns of empty space as padding before an element.
    • number ($n): The number of Columns for the Prefixed padding to span.
    • context ($c): The context, if other-than-root. Default: false.
  • suffix(number [, context, from-direction])

    • Add columns of empty space as padding after an element.
    • number ($n): The number of Columns for the Suffixed padding to span.
    • context ($c): The context, if other-than-root. Default: false.
  • pad([prefix-number, suffix-number, context, from-direction])

    • Shortcut for adding both Prefix and Suffix padding.
    • prefix-number ($p): The number of columns for the Prefixed padding to span.
    • suffix-number ($s): The number of columns for the Suffixed padding to span.
    • context ($c): The context, if other-than-root. Default: false.
  • susy-grid-background()

    • Apply to your Container in order to see the Susy Grid as a background-image. This is only meant as a debugging tool.

Functions

Where a mixin returns property/value pairs, functions return simple values that you can put where you want. Don’t like Prefix and Suffix applied to padding? Add some Columns to your margin instead.

  • columns(number [, context, from-direction])

    • Identical to columns mixin, but returns the math-ready % multiplier.
    • example: width: columns(3,6);
  • gutter([context])

    • The % width of one gutter in any given context.
    • context ($c): The context, if other-than-root. Default: false.
    • example: margin-right: gutter(6) + columns(2,6);
  • side-gutter([context])

    • The % width of one side gutter in a given context. Context should always be root.
    • context ($c): The context, if other-than-root. Default: false.
    • example: margin-right: gutter() + columns(3) + side-gutter();

Vertical Rhythm

A complete list of compass’s vertical rhythm functions and mixins are located on the typography documentation page. I will cover the most used ones here so you don’t have to keep fliping back and forth

Terms

  • Rhythm: An imaginary unit that defines the Vertical Rhythm
  • leader: A vertical spacing that comes before the selected text either a top margin or padding
  • trailer: A vertical spacing that comes after the selected text either a bottom margin or padding

Mixins

  • establish-baseline([$font-size])

    • Establishes a font baseline for the entire document
    • This returns an html style and an html>body style so it must be called at the root of your style sheet.
  • adjust-font-size-to($to-size [, $lines, $from-size])

    • Adjust a block to have a different font size and leading to maintain the rhythm.
    • $lines is a number that is how many times the baseline rhythm this font size should use up. Does not have to be an integer, but it defaults to the smallest integer that is large enough to fit the font.
    • Use $from_size to adjust from a non-base font-size.
  • leader($lines [, $font-size, $property])

    • Apply leading whitespace as margin
    • $lines is a number that is how many times the baseline rhythm leader size should use up.
    • $font-size defaults to $base-font-size
    • $property either margin or padding
  • trailer($lines [, $font-size, $property])

    • Apply trailing whitespace as margin
    • $lines is a number that is how many times the baseline rhythm this trailer should use up.
    • $font-size defaults to $base-font-size
    • $property either margin or padding

Functions

  • rhythm($lines [, $font-size])
    • Calculate rhythm units
    • returns a raw unit of measurement suitable for math operations.

Basic layout

Annotated Basic Layout

So what is going on in this image first lets look at the style sheet (Note: this isn’t the full style sheet only an example)

... assume content from screen.scss above is in this file also

section.content {      
  @include container;
  @extend .grid;
  @include clearfix;
  @include border-radius(5px);
  background-color: rgb(250,250,250);
  @extend .grid;

  h1 {
    @include trailer;
    @include leader;
    @include adjust-font-size-to($base-font-size * 3, $lines:2);
  }

  p {
    &:first-child {
      @include leader;  
    }
    @include trailer;
    @include full;
  }
}

Lets recap whats going on in this file and image.

  • The h1 shown inside the green box is a very common example of using the adjust-font-size-to mixin you will notice that the rhythm is preserved and the text is centered vertically appropriately.
  • The orange box is a leader applying a top margin to the first p tag in section.content.
  • the red box’s are trailers applying a bottom margin to each p tag in section.content.
  • The purple boxes on the sides of the page is susy’s $side-gutter-width which is applied as a margin buy using the susy mixin full.
  • The black box is an example of what height: rhythm(3); would do if it wasn’t being already defined by the text content.

Configuring Rails 3.1 and Compass Sprite_load_path

By default compass sprites are put in to the app/assets/images directory which is copied to public/assets on precompile/deploy. By moving the files to their own sprite folder only the generated images get moved in to public/assets when deploying to production which should save some file space.

Instructions

First create the directory app/assets/sprites

Then create the initializer below in config/initilaizers/sprite_load_path.rb:

Compass.add_configuration({:sprite_load_path => Compass.configuration.sprite_load_path + [Rails.root.join('app', 'assets', 'sprites')]}, 'sprites')

Caveats

This will not work with the stand alone compass command line since it will require rails to load in order to configure compass if you are using a compass.rb you can set the sprite_load_path like so:

sprite_load_path = Compass.configuration.sprite_load_path + [Rails.root.join('app', 'assets', 'sprites']