Skip to content

Instantly share code, notes, and snippets.

@chriseppstein
Created September 14, 2011 04:27
Star You must be signed in to star a gist
Save chriseppstein/1215856 to your computer and use it in GitHub Desktop.
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
Copy link

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
Copy link

yatil commented Oct 30, 2011

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
Copy link

Neeeeeed !

@brianmcallister
Copy link

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
Copy link
Author

@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
Copy link

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
Copy link
Author

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

@levifig
Copy link

levifig commented Oct 21, 2012

@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… :(

@kddawson
Copy link

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
Copy link

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; }
  }
}

@securitybd
Copy link

Help me to make my web http://www.security.com.bd >> problem is content wide than screen. my email is securelinebd@gmail.com. I just pest my css.

*{
margin:0px;
font-family:arial;
font-size:13px;
line-height:130%;
}
body{
background:#ccc url(../images/128-129.jpg) fixed;
}

#wrapper{
width:900px;
margin:0px auto 10px;
/* background-color:#ed1f24; */
display:table;
border-radius:8px;
overflow:hidden;
}

#banner{
height:110px;
background-color:#000000;
width:900px;
margin:0 auto;
border-radius:0 8px;
border-bottom:1px red dotted;
border-top:1px red dotted;
background-image:url(../images/hb1.jpg);
background-repeat:no-repeat;
background-position:right top;
}
#banner #logo{
width:;
float:left;
height:95px;
margin-top:5px;
margin-left:15px;
}

#banner h2{
position:relative;
margin-left:340px;
padding-top:20px;
color:#ed2025;
font-size:35px;
text-transform:uppercase;
word-spacing:7px;
letter-spacing:2px;
text-shadow:2px 1px 3px #000;

}
#banner span{
font-size:35px;
color:#fff;

}
#banner #slogan{
color:#fff;
letter-spacing:12px;
margin-left:319px;
font-size:14px;
}
#slide{
height:310px;
background-color:#999;
margin:5px 0 10px 0;
}

#content{
display:table;
background-color:rgba(255,255,255,0.5);
}
#left_c{
float:left;
width:65%;
border-right:5px #fff solid;
box-sizing:border-box;
padding:90px 0;
min-height:600px;
min-width:585px;

}
#left_c div{
padding:7px 50px;
text-align:justify;
background:#fff;
font-size:14px;
line-height:20px;
}
#right_c{
float:right;
width:315px;
padding:90px 0;
}
#right_c h1{
text-align:center;
font-size:20px;
color:white;
font-weight:normal;
background-color: #000;
}
#right_c h1 span{
font-weight:bold;
font-size:18px;
color:white;
}
#right_c .featured_p{
width:260px;
height:200px;
margin:35px 25px;
border-radius:10px;
border:2px solid #BA5757;
padding:1px;
background-color:#fff;
}
#footer{
height:60px;
clear:both;
margin-top:10px;
background-color:#ed1f24;
text-align:center;
color:white;
padding:0 50px;
}
#footer p, #footer span{
line-height:50px;
}
#footer a{
color:#000;
}
/contact.php/
#left_c dt{
margin-left:20px;
}
#left_c dd{
margin-left:40px;
}
#q1_dd,#q2_dd,#q3_dd,#q4_dd{
display:none;
}

#left_c form{
width:490px;
margin:0 auto;
display:block;
}
#left_c input[type="text"],#left_c input[type="email"]{
width:490px;
height:35px;
margin-bottom:5px;
}
#left_c textarea{
width:490px;
height:350px;
margin-bottom:5px;
}
#left_c input[type="submit"]{
width:120px;
height:40px;
float:right;
}

/contact.php/

/gallery/
.gallery_box{
background-color:rgba(255,255,255,0.5);
padding:10px 16px;
}
.gallery_box .vlightbox1_thumb{
width:160px;
height: 120px;
}
/gallery/

@brndto
Copy link

brndto commented Jul 12, 2018

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment