Responsive Web Design with Sass+Compass – First, an experiment – What's a team to do?



Responsive Web Design with Sass+Compass – First, an experiment – What's a team to do?

2 3


RWD-with-Sass-Compass

My talk on Responsive Web Design with Sass+Compass

On Github Snugug / RWD-with-Sass-Compass

Responsive Web Design with Sass+Compass

Slides available at

http://snugug.github.io/RWD-with-Sass-Compass/

Who Am I?

First, an experiment

Hold up your hand if you own a smartphone

Lower it if you have the exact same phone (make, model, carrier, and OS version) as your neighbors

Put your hands back up

Lower it if you only use your phone while you're distracted, on the go, and want a dumbed-down or lite experience

Responsive Web Design isn’t about current devices and known unknowns, it’s about future devices and unknown unknowns.

What's a team to do?

We start with our content first

It’s not about mobile first (or just small screen first) – it's about content first. But it happens that thinking about what works for mobile does work for other things as well.

Jeffery Zeldman

We design using mobile as a focusing lens

But don't take that the wrong way…

[T]here is no mobile web. There are plenty of mobile devices. And equally there is no desktop web. It is just the web. [O]ne web.

Jeremy Keith

We use web standards, progressive enhancement, and modern best practices

All while staying device agnostic, avoiding common user experience pitfalls, and staying future friendly.

The point of creating [responsive] sites is to create functional (and hopefully optimal) user experiences for a growing number of web-enabled devices and contexts.

Oh, and throw away “Pixel Perfect”

Of Course Responsive Web Design is Hard.

It's Design.

Mason Wendell

The Web is an Inherently Unstable Medium

Ethan Marcotte Let's Embrace the Entropy

What Do You Need for RWD?

As outlined in Ethan Marcotte's Phrase-Coining A List Apart article, Responsive Web Design needs the three following things:

  • Media Queries
  • Fluid Grids
  • Flexible Media

Using Compass Extensions

gem 'extension', '~>X.Y.Z'
require '{extension}'
@import '{extension}';

Media Queries

Start with the small screen first, then expand until it looks like shit.

TIME FOR A BREAKPOINT!

Stephen Hay

Breakpoint

gem 'breakpoint', '~>2.4.0'
require 'breakpoint'
@import 'breakpoint';

Basic Media Queries - Sass

// Your basic media queries, min-width and min/max width, are super easy!
$small: 543px;
$medium: 794px;
$fence-sm: $small $medium;

#foo {
  content: 'No Media Queries';

  @include breakpoint($small) {
    content: 'Small Media Query';
  }

  @include breakpoint($fence-sm) {
    content: 'Fenced Media Query';
  }
}

Basic Media Queries - CSS

 /* Nested Breakpoint calls become separate media queries */
#foo {
  content: 'No Media Queries';
}

@media (min-width: 543px) {
	#foo {
		content: 'Small Media Query';
	}
}

@media (min-width: 543px) and (max-width: 794px) {
	#foo {
		content: 'Fenced Media Query';
	}
}

Basic Media Queries - CSS

 /* Setting $breakpoint-to-ems: true will write Media Queries in Ems! */
@media (min-width: 33.9375em) {
	#foo {
		content: 'Small Media Query';
	}
}

@media (min-width: 33.9375em) and (max-width: 49.625em) {
	#foo {
		content: 'Fenced Media Query';
	}
}

Advanced Media Queries - Sass

// Advanced "and" media queries and "or" media queries made simple
$print-land: print monochrome (orientation landscape);

$fenced-landscape: screen 321px 543px, handheld (orientation portrait);

#foo {
  @include breakpoint($print-land) {
    content: 'Monochrome Print in Landscape';
  }

  @include breakpoint($fence-landscape) {
    content: 'Screen media type between 300px and 500px or Handheld media type in Portrait';
  }
}

Advanced Media Queries - CSS

 /* Advanced "and" media queries and "or" media queries made simple */
@media print and (monochrome) and (orientation: landscape) {
	#foo {
		content: 'Monochrome Print in Landscape';
	}
}

@media screen and (min-width: 321px) and (max-width: 543px), handheld and (orientation: portrait) {
	#foo {
		content: 'Screen media type between 300px and 500px or Handheld media type in Portrait';
	}
}

Resolution Media Queries - Sass

// Resolution media queries are a pain. Breakpoint makes them easy. We use the standard DPPX units.
$hidpi: min-resolution 1.5dppx;
$cross-reso: max-resolution 143dpi;

#foo {
  @include breakpoint($hidpi) {
    content: 'Device Pixel Ratio of at least 1.5';
  }

  @include breakpoint($cross-reso) {
  	content: 'Cross Browser Resolution Query'
  }
}

Resolution Media Queries - CSS

 /* Breakpoint will transform the DPPX unit into cross-browser compatible resolution queries and DPI units into cross-browser DPR queries! */
@media (min-resolution: 1.5dppx), (-webkit-min-device-pixel-ratio: 1.5), (min--moz-device-pixel-ratio: 1.5), (min-resolution: 144dpi) {
  #foo {
    content: 'Device Pixel Ratio of at least 1.5';
  }
}

@media (max-resolution: 143dpi), (-webkit-max-device-pixel-ratio: 1.48958), (max--moz-device-pixel-ratio: 1.48958) {
  #foo {
    content: "Cross Browser Resolution Query";
  }
}

Media Query Fallbacks - Sass

// _mqs.scss
$touch: pointer fine, 'no-query' '.no-touch';
$no-queries: 678px, 'no-query' '.no-mqs';

#foo {
  @include breakpoint($touch) {
    content: 'Fine Pointer';
  }
  @include breakpoint($no-queries) {
  	content: 'No Media Queries';
	}
}

Media Query Fallbacks - Sass

// style.scss
$breakpoint-no-queries:         false;
$breakpoint-no-query-fallbacks: false;

@import "mqs";
// touch.scss
$breakpoint-no-queries:         true;
$breakpoint-no-query-fallbacks: '.no-touch';

@import "mqs";

Media Query Fallbacks - CSS

/* style.css */
/* Only the Media Query gets printed out here! */
@media (pointer: fine) {
  #foo {
  	content: 'Fine Pointer';
	}
}

Media Query Fallbacks - CSS

/* style.css */
/* Only the Media Query gets printed out here! */
@media (pointer: fine) {
  #foo {
  	content: 'Fine Pointer';
	}
}
/* touch.css */
/* Only the Meida Queries with a .touch no-fallback get printed! */
.no-touch #foo {
	content: 'Fine Pointer';
}

Fluid Grids

Let's Cheat at CSS

// We can import all of Compass safely because it doesn't write any CSS.
@import 'compass';

// We switch our box model to Border Box.
// From Paul Irish
*, *:before, *:after {
  @include box-sizing('border-box');
}

Singularity

gem 'singularitygs', '~>1.2.0.rc.3'
require 'singularitygs'
@import 'singularitygs';

Building With Grids

Grids provide order to your design and structure to your information.

The best grids are specific to your content and your design, as they are an extension of both.

Twitter Bootstrap

Zurb Foundation

YUI Pure

All The Grids Are All The Same!

Boring Grids

Symmetric Grids - Twitter Bootstrap

@include add-grid(12);
@include add-gutter(1/3);

Symmetric Grids - Zurb Foundation

@include add-grid(12);
@include add-gutter(0.9375em);
@include add-gutter-style(split);

Symmetric Grids - YUI Pure

@include add-grid(12);
@include add-gutter(0);

Interesting Grids

Asymmetric Grid - Custom

@include add-grid(1 4 1);
@include add-gutter(1/6);
@include add-gutter-style(split)

Asymmetric Grid - Compound

// Compound function comes from Singularity Extras
@include add-grid(compound(3, 4));
@include add-gutter(1);

Asymmetric Grid - Ratio Based

// Ratio function comes from Singularity Extras
@include add-grid(ratio(golden-ratio(), 4));
@include add-gutter(golden-ratio() * 1em);
@include add-gutter-style(split);

Asymmetric Grid - Spiral Based

// Ratio spiral function comes from Singularity Extras
@include add-grid(ratio-spiral(5));
@include add-gutter(1);

Asymmetric Grid - Mixed Fixed and Fluid Grids

// Calc output style comes from Singularity Extras
@include add-grid(320px 1 2);
@include add-gutter(1em);
@include sgs-change('output', 'calc');

Semantic Grids

Singularity is what we like to call a semantic grid system, meaning that instead of grid classes being generated that you then apply to your HTML, the grid is stored entirely within your CSS and applied directly to the element you want to use it on.

Spanning The Grid - HTML

<body>
  <div class="main">Main Section</div>
  <div class="first">First Section</div>
  <div class="second">Second Section</div>
</body>

Spanning The Grid - Sass

// Simply pass the number of columns you'd like to span and what column you'd like to start from.

@include add-grid(2 8 2);
@include add-gutter(1/3);

.first {
  @include grid-span(1, 1);
}

.main {
  @include grid-span(1, 2);
}

.second {
  @include grid-span(1, 3);
}

Spanning The Grid - Display

Responsive Grid Context - Sass

// add-grid allows you to automatically change your global Grid Context at various breakpoints

@include add-grid(12);
@include add-grid(2 8 2 at 700px);
@include add-gutter(1/3);

.first {
  @include grid-span(3, 4);

  @include breakpoint(700px) {
    @include grid-span(1, 1);
  }
}

.main {
  @include grid-span(6, 7);

  @include breakpoint(700px) {
    @include grid-span(1, 2);
  }
}

.second {
  @include grid-span(3, 1);

  @include breakpoint(700px) {
    @include grid-span(1, 3);
  }
}

Responsive Grid Context - Display

Nested Grids - HTML

<body>
  <div class="main">
    <div class="one">One</div>
    <div class="two">Two</div>
    <div class="three">
      <div class="a">Three A</div>
      <div class="b">Three B</div>
      <div class="c">Three C</div>
    </div>
    <div class="four">Four</div>
  </div>
  <div class="first">First Section</div>
  <div class="second">Second Section</div>
</body>

Nested Grids (Outer Grid) - Sass

@include add-grid(2 8 2);
@include add-gutter(1/3);

.first {
  @include grid-span(1, 1);
}

.main {
  @include grid-span(1, 2);
}

.second {
  @include grid-span(1, 3);
}

Nested Grid (Outer Grid) - Display

Nested Grids (First Nesting) - Sass

@include layout(8) {
	.one {
	  @include grid-span(1, 1);
	}

	.two {
	  @include grid-span(1, 8);
	}

	.three {
	  @include grid-span(6, 2);
	}

	.four {
	  @include grid-span(2, 4);
	  clear: both;
	 }
}

Nested Grid (First Nesting) - Display

Nested Grids (Second Nesting) - Sass

@include layout(6) {
	.a {
	  @include grid-span(2, 3);
	}

	.b {
	  @include grid-span(2, 5);
	}

	.c {
	  @include grid-span(2, 1);
	}
}

Nested Grid (Second Nesting) - Display

Fluid Media

Toolkit

gem 'toolkit', '~>2.0.0.alpha.7'
require 'toolkit'
@import 'toolkit';

Basic Fluid Media

// Making images and HTML5 video fluid is pretty easy.

img, video {
	max-width: 100%;
	height: auto;
}

Intrinsic Ratios - Sass

// Using Intrinisc Ratios, you can even make embedded videos fluid!

.fluid-16-9 {
  @include intrinsic-ratio;
}
.fluid-4-3 {
	@include intrinsic-ratio(4/3);
}
<body>
  <div class="fluid-16-9">
    <iframe width="560" height="315" src="http://www.youtube.com/embed/hHloF85dQZg?rel=0" frameborder="0" allowfullscreen></iframe>
  </div>
</body>

Intrinsic Ratios - CSS

/* Intrinsic Ratio code is built for a small code footprint, so shared code is extended. */
.fluid-16-9, .fluid-4-3 {
  position: relative;
  height: 0;
}

.fluid-16-9 > *, .fluid-4-3 > * {
  display: block;
  position: absolute;
  width: 100% !important;
  height: 100% !important;
  top: 0;
  margin: 0;
  padding: 0;
}

.fluid-16-9 {
  padding-top: 56.25%;
  width: 100%;
}

.fluid-4-3 {
  padding-top: 75%;
  width: 100%;
}

Putting It All Together

Did I Mention?

Everything you just saw? Yah, it's backend independent. You can use it anywhere, with anything, for any project. Sass Rocks

Thank You

Slides available at

http://snugug.github.io/RWD-with-Sass-Compass/