Respond-to block

A couple of weeks back I linked to this video http://vimeo.com/32611202 in a thread about responsive design.
I’ve since used this technique for all of the media queries in a site I’m developing and it’s worked so well I wanted to share how I’m working with it.

For people who have been using Sass’ nested syntax for a while you’ll know that keeping your styles all bundled together is a really nice way to structure your CSS.
It keeps everything to do with a particular grouping of elements neatly organised and is less typing.
I still try to keep my indentation to a minimum for the same reasons as regular CSS, the more specific and longer selectors are hard to override and unnecessary.

Nesting is by far my favourite feature of Sass and it’s one reason I don’t write regular CSS anymore if I have the choice.


#header {
  nav {}
  ul {}
  a {}
}
#content {
  h1 {}
  p, ul {}
}
#testimonials {
  li {}
  a {}
  img {}
}

The respond-to mixin that Ben showed in his video solves this same problem that nesting solves.
If you keep your media queries at the end of your stylesheet or in different files it’s hard to find which collection of styles is effecting any particular element because the styles are coming from lots of places.
Keeping all of this bundled together is much easier to manage and you don’t need to jump around to do comparisons.

I’ve chosen to optimise for these switch points, but you can choose whatever resolutions you’d like.


@mixin respond-to($media) {
  @if $media == iphone {
    @media only screen and (max-width: 320px) { @content }
  }
  @else if $media == iphone-landscape {
    @media only screen and (max-width: 480px) { @content }
  }
  @else if $media == ipad {
    @media only screen and (max-width: 980px) { @content }
  }
  @else if $media == ipad-landscape {
    @media only screen and (max-width: 1024px) { @content }
  }
}

A couple of examples:


#logo {
  position: absolute;
  margin: 0;
  @include respond-to(iphone-landscape) {
    position: static;
    margin: 0 auto !important;
  }
}

Keeping these position and margin properties together shows what they are changing from and to at a glance.


#projects {
  text-align: center;
  ul {
    list-style: none;
    padding: 0;
    overflow: hidden;
    margin: 40px 0 0 -43px;
    @include respond-to(iphone-landscape) { margin: 20px 0 }
  }
  li {
    float: left;
    width: 25%;
    @include respond-to(ipad-landscape) { width: 33.3% }
    @include respond-to(ipad) { width: 50% }
    @include respond-to(iphone-landscape) {
      float: none;
      width: 100%;
    }
  }
  a {
    display: block;
    padding: 45px 0 0;
    min-height: 150px;
    color: lighten(black, 60%);
    margin: 0 0 43px 43px;
    @include respond-to(iphone-landscape) { margin: 0 0 10px }
  }
}

The list of projects displays in 4 columns by default, 3 col for ipad-landscape and lower, 2 col for ipad-portrait and linearised for iphone-landscape and under.
I’ve tried keeping my media queries separate as well but I’ve found this to work a lot better in practice.

If you want to try it out give Compass a go, it’s a neat little wrapper around Sass to make compilation painless and give you a few extra features like CSS3 mixins and sprites.

Thanks for documenting this so thoroughly Mark and when I get a chance I’ll have to have a go at trying this out :slight_smile: