Skip to content

Embed URL

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
This gist demonstrates some uses of the new sass feature: Passing content blocks to mixins.
@mixin ie6 { * html & { @content } }
#logo {
background-image: url("/images/logo.png");
@include ie6 { background-image: url("/images/logo.gif"); }
}
=ie6
* html &
@content
#logo
background-image: url("/images/logo.png")
+ie6
background-image: url("/images/logo.gif")
#logo { background-image: url("/images/logo.png"); }
* html #logo { background-image: url("/images/logo.gif"); }
@mixin keyframes {
@-moz-keyframes { @content; }
@-webkit-keyframes { @content; }
}
@include keyframes {
0% { opacity: 0; }
100% { opacity: 1; }
}
=keyframes
@-moz-keyframes
@content
@-webkit-keyframes
@content
+keyframes
0%
opacity: 0
100%
opacity: 1
@-moz-keyframes {
0% { opacity: 0; }
100% { opacity: 1; }
}
@-webkit-keyframes {
0% { opacity: 0; }
100% { opacity: 1; }
}
@mixin respond-to($media) {
@if $media == handhelds {
@media only screen and (max-width: 479px) { @content; }
}
@else if $media == wide-handhelds {
@media only screen and (min-width: 480px) and (max-width: 767px) { @content; }
}
@else if $media == tablets {
@media only screen and (min-width: 768px) and (max-width: 959px) { @content; }
}
}
#sidebar {
float: left;
width: 300px;
@include respond-to(handhelds) { float: none; }
@include respond-to(wide-handhelds) { float: none; }
@include respond-to(tablets) { width: 240px; }
}
=respond-to($media)
@if $media == handhelds
@media only screen and (max-width: 479px)
@content
@else if $media == wide-handhelds
@media only screen and (min-width: 480px) and (max-width: 767px)
@content
@else if $media == tablets
@media only screen and (min-width: 768px) and (max-width: 959px)
@content
#sidebar
float: left
width: 300px
+respond-to(handhelds)
float: none
+respond-to(wide-handhelds)
float: none
+respond-to(tablets)
width: 240px
#sidebar { float: left; width: 300px; }
@media only screen and (max-width: 479px) { #sidebar { float: none; } }
@media only screen and (min-width: 480px) and (max-width: 767px) { #sidebar { float: none; } }
@media only screen and (min-width: 768px) and (max-width: 959px) { #sidebar { width: 240px; } }
@ChristianPeters

Great feature! Especially the media query example demonstrates its power to improve stylesheet maintainability.

I cannot find it in the Sass changelog, though. Is it already released?

@yatil

Examples 4, 5, 6 are wrong as you need a name for your @-webkit-/-moz-keyframes section. The mixin should look like this:

@mixin keyframes($name) {
  @-moz-keyframes    $name { @content; }
  @-webkit-keyframes $name { @content; }
}

Yet I get an error when parsing this:

Syntax error: Invalid CSS after "...z-keyframes ": expected "}", was "$name { @conten..."
on line 4 of /style.scss

@ZeeAgency

Neeeeeed !

@brianmcallister

It would be really cool if you could make variables you create in your mixin available to the stuff inside the @content block. So for example, I could make a mixin that would loop over a list:

$GLOBAL_LIST: apple peach pear banana;

/*
  Mixin
*/
@mixin list-fruit() {
  @each $fruit in $GLOBAL_LIST {
    @content;
  }
}

/*
  Usage
*/
@include list-fruit() {
  .thumbnail-#{$fruit} {
    background-image: image-url('icon-#{$fruit}.png');
  }
}

/*
  Expected output:
*/
.thumbnail-apple {
  background-image: url(images/icon-apple.png);
}

.thumbnail-peach {
  background-image: url(images/icon-peach.png);
}

.thumbnail-pear {
  background-image: url(images/icon-pear.png);
}

.thumbnail-banana {
  background-image: url(images/icon-banana.png);
}
@chriseppstein

@brianmcallister I had this thought while spec'ing the feature, but decided to keep it simple for the initial release. If the use cases are compelling enough, we will consider this for a future release. The syntax would need to allow passing arguments from the mixin to the content block because the scope of the block is the caller, not the mixin. E.g.

@mixin fruit-thumbnail($fruit) {
  .thumbnail-#{$fruit} {
    background-image: image-url('icon-#{$fruit}.png');
  }
}
@mixin list-fruit() {
  @each $fruit in $GLOBAL_LIST {
    @content $fruit;
  }
}
@include list-fruit() with fruit-thumbnail;
@zigotica

Hi,

Still find some lack of implementation for basic scenarios (or maybe i'm missing something here). It would be very cool to be able to assign variables depending on media queries, like so, inside media queries:

$break-smart: 480px;
$break-tablet: 768px;
$break-wide: 1000px;

@media screen and (max-width: $break-smart) { 
    $grid-columns: 10;
    $grid-gutter-width: 10px;
    $grid-total-width: 310px; 
    $grid-col-width: ( ($grid-total-width - $grid-gutter-width) / $grid-columns) - $grid-gutter-width;
 }
@media screen and (min-width: $break-smart + 1) and (max-width: $break-tablet) { 
    $grid-columns: 10;
    $grid-gutter-width: 10px;
    $grid-total-width: 460px; 
    $grid-col-width: ( ($grid-total-width - $grid-gutter-width) / $grid-columns) - $grid-gutter-width;
 }
@media screen and (min-width: $break-tablet + 1) and (max-width: $break-wide) { 
    $grid-columns: 12;
    $grid-gutter-width: 10px;
    $grid-total-width: 740px; 
    $grid-col-width: ( ($grid-total-width - $grid-gutter-width) / $grid-columns) - $grid-gutter-width;
 }
@media screen and (min-width: $break-wide + 1) { 
    $grid-columns: 12;
    $grid-gutter-width: 20px;
    $grid-total-width: 980px; 
    $grid-col-width: ( ($grid-total-width - $grid-gutter-width) / $grid-columns) - $grid-gutter-width;
 }

It would be cool because it would save us from having to define further "target" resolutions. Previous code throws a Syntax error because variables used later in scss are not set. Alternative code (ie your respond-to mixins) is much more cumbersome:

$break-smart: 480px;
$break-tablet: 768px;
$break-wide: 1000px;

@mixin respond-to($media) {
  @if $media == smart {
    $grid-columns: 10;
    $grid-gutter-width: 10px;
    $grid-total-width: 310px; 
    $grid-col-width: ( ($grid-total-width - $grid-gutter-width) / $grid-columns) - $grid-gutter-width;
    @media screen and (max-width: $break-smart) { @content; }
  }
  @else if $media == tablet {
    $grid-columns: 10;
    $grid-gutter-width: 10px;
    $grid-total-width: 460px; 
    $grid-col-width: ( ($grid-total-width - $grid-gutter-width) / $grid-columns) - $grid-gutter-width;
    @media screen and (min-width: $break-smart + 1) and (max-width: $break-tablet) { @content; }
  }
  @else if $media == tablet-wide {
    $grid-columns: 12;
    $grid-gutter-width: 10px;
    $grid-total-width: 740px; 
    $grid-col-width: ( ($grid-total-width - $grid-gutter-width) / $grid-columns) - $grid-gutter-width;
    @media screen and (min-width: $break-tablet + 1) and (max-width: $break-wide) { @content; }
  }
  @else if $media == desktop {
    $grid-columns: 12;
    $grid-gutter-width: 20px;
    $grid-total-width: 980px; 
    $grid-col-width: ( ($grid-total-width - $grid-gutter-width) / $grid-columns) - $grid-gutter-width;
    @media screen and (min-width: $break-wide + 1) { @content; }
  }
}

…later in scss:

.main {  
            @include respond-to(smart)     { @include grid($grid-total-width); }
            @include respond-to(tablet)    { @include grid($grid-total-width);  }
            @include respond-to(tablet-wide) { @include grid($grid-total-width);  }
            @include respond-to(desktop)   { @include grid($grid-total-width);  }
}

Summarizing, a simple total width has to be defined in respond-to mixin but then called the same way for all targets! Surely I'm missing something.

It's getting better though
Thanx

@chriseppstein

Note: there's now a keyframe animation module in compass 0.13: http://beta.compass-style.org/reference/compass/css3/animation/

@levifig

@zigotica OH MY GOSH ,YES! I was just playing with mixins and @content and tried doing that because it made so much more sense! I even tweeted at Chris and Nathan about it, then googled it and got here! It's been 4 months and we still don't have it… :(

@multicelldesign

The respond-to mixin makes for much better organisation of my layout styles. One (current) drawback is the duplication of media queries though - for other visitors to this gist, there's plenty of discussion on potential fixes over at the Sass GitHub page you might like to read.

All the best, Karl

@ryanduffy

As an IE 7 & 8 media queries workaround, I'm playing with the idea below.

Does anybody see any drawbacks to this? or maybe there's a better way?

@mixin respond-to($media) {
  @if $media == handhelds {
    @media only screen and (max-width: 479px) { @content; }
  }
  @else if $media == wide-handhelds {
    @media only screen and (min-width: 480px) and (max-width: 767px) { @content; }
  }
  @else if $media == tablets {
    @media only screen and (min-width: 768px) and (max-width: 959px) { @content; }
    .lt-ie9 & { @content; }
  }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.