Skip to content

Instantly share code, notes, and snippets.

@micahgodbolt
Created June 24, 2013 16:08
Show Gist options
  • Star 19 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save micahgodbolt/5851228 to your computer and use it in GitHub Desktop.
Save micahgodbolt/5851228 to your computer and use it in GitHub Desktop.
Another stab at Filament Group's Element Query challenge.
// ---
// Sass (v3.2.9)
// ---
@mixin respond-to($queries...) {
$length: length($queries);
@for $i from 1 through $length{
@if $i % 2 == 1 {
@media screen and (min-width: nth($queries, $i)) {
#{nth($queries, $i+1)} {
@content;
}
}
}
}
}
@include respond-to(32em, ".content", 90em, aside) {
.schedule-component {
float: left;
width: 100%;
position:relative;
}
.schedule-component ul,
.schedule-component li {
list-style: none;
position: absolute;
margin: 0;
padding: 0;
}
}
@media screen and (min-width: 32em) {
.content .schedule-component {
float: left;
width: 100%;
position: relative;
}
.content .schedule-component ul,
.content .schedule-component li {
list-style: none;
position: absolute;
margin: 0;
padding: 0;
}
}
@media screen and (min-width: 90em) {
aside .schedule-component {
float: left;
width: 100%;
position: relative;
}
aside .schedule-component ul,
aside .schedule-component li {
list-style: none;
position: absolute;
margin: 0;
padding: 0;
}
}
@scottjehl
Copy link

Nice! So would this work with any media query or only min-width queries? We use a lot of max-width and resolution queries in particular.

@scottjehl
Copy link

@micahgodbolt rather, it looks like the min-width part is baked into this example. Any way that could be pulled out in favor of a full mq (anything after the @media and before the {, basically?

@jpavon
Copy link

jpavon commented Jun 24, 2013

@scottjehl, I have modified a bit @micahgodbolt's code to add custom media queries:

@mixin respond-to($queries...) {
    $length: length($queries);
    @for $i from 1 through $length{
        @if $i % 2 == 1 {
            @media #{nth($queries, $i)} {
                #{nth($queries, $i+1)} {
                  @content;
                }
            }
        }
    }
}

$s: 'only screen and (min-width : 30em)';
$m: 'only screen and (min-width : 90em)';
@include respond-to($s, '.content',
                    $m, 'aside') {
    .schedule-component {
        float: left;
        width: 100%;
        position:relative;
    }
    .schedule-component ul,
    .schedule-component li {
        list-style: none;
        position: absolute;
        margin: 0;
        padding: 0;
    }
}

Output:

@media only screen and (min-width: 30em) {
  .content .schedule-component {
    float: left;
    width: 100%;
    position: relative;
  }
  .content .schedule-component ul,
  .content .schedule-component li {
    list-style: none;
    position: absolute;
    margin: 0;
    padding: 0;
  }
}
@media only screen and (min-width: 90em) {
  aside .schedule-component {
    float: left;
    width: 100%;
    position: relative;
  }
  aside .schedule-component ul,
  aside .schedule-component li {
    list-style: none;
    position: absolute;
    margin: 0;
    padding: 0;
  }
}

@scottjehl
Copy link

Hey @jpavon - that looks pretty close to me! We'll test it out. Thanks :)

@micahgodbolt
Copy link
Author

Yup! Nice work. You can build this up many different ways to add more flexibility, but it looks like @jpavon got it just to the way you need it. Thanks for giving me an excuse to learn more about the nth() function.

@scottjehl
Copy link

I just tested this and it works really, really great.

We'd like to have it somewhere public and easy to find. Would you mind if we put it in a @filamentgroup repo or would one of you prefer to post it to your own? If it's on ours, we'll be sure to credit you both for the work in the readme.

@jpavon
Copy link

jpavon commented Jun 24, 2013

It's ok with me if you create the repo @scottjehl, more people will see it that way.

@lajlev
Copy link

lajlev commented Jun 25, 2013

I like this idea. Gonna play around with it, thanks guys.

@micahgodbolt
Copy link
Author

Once again, the lack of gist notifications means that I didn't see this until today :) Obviously @filamentgroup and @scottjehl already got this set up, and that's great. Happy to have been able to contribute to a useful bit of code.

@jwebcat
Copy link

jwebcat commented Jun 28, 2013

@scottjehl @micahgodbolt @jpavon -

  • A repo would be magnificent!
  • I saw two days ago and would love to have more people see this!! It works great!

@paulirish
Copy link

@micahgodbolt
Copy link
Author

Can cross off "Have @paulirish comment on my gist" from my bucket list.

@jslegers
Copy link

I created a variation that allows the following input :

* $width
* $width, $width, $width, ...
* ($width, $class)
* ($width, $class), ($width, $class), ...
* (($width, $widthType), ($width, $widthType), ...)
* (($width, $widthType), $class)
* (($width, $widthType), $class)), (($width, $widthType), $class)), ...
* any combination of the above

Only "(($width, $widthType))" isn't supported because SCSS automaticly flattens the list to "($width, $widthType)", which doesn't allow the code to distinguish it from ($width, $class). I posted an issue reporting this at sass/sass#859 .

SCSS code :

@mixin screen($parameter, $value, $query) {
    @media screen and (#{$parameter}: #{$value}) {
        $length: length($query);
        @if ( $length > 1 ) {
            @for $i from 2 through $length {
                $class : nth($query, $i);
                #{$class} {
                    @content;
                }
            }
        } @else {
            @content;
        }
    }
}

@mixin respond-to($queries...) {
    @each $query in $queries {
        $width : nth($query, 1);
        $parameter : 'min-width';
        $value : $width;
        $lengthwidth : length($width);
        @if($lengthwidth > 1){
            $parameter : nth($width, 2);
            $value : nth($width, 1);
        } @else {
            $parameter : 'min-width';
            $value : $width;
        }
        @include screen($parameter, $value, $query) {
            @content;
        }
    }
}

@include respond-to((32em, '.content'), (60em), ((72em,'max-width'),'.test'), (90em, aside, main)) {
    .schedule-component {
        float: left; 
        width: 100%;
        position:relative; 
    }
    .schedule-component ul,
    .schedule-component li {
       list-style: none;
       position: absolute;
       margin: 0;
       padding: 0;
    }
}

OUTPUT :

@media screen and (min-width: 32em) {
  .content .schedule-component {
    float: left;
    width: 100%;
    position: relative;
  }
  .content .schedule-component ul,
  .content .schedule-component li {
    list-style: none;
    position: absolute;
    margin: 0;
    padding: 0;
  }
}
@media screen and (min-width: 60em) {
  .schedule-component {
    float: left;
    width: 100%;
    position: relative;
  }

  .schedule-component ul,
  .schedule-component li {
    list-style: none;
    position: absolute;
    margin: 0;
    padding: 0;
  }
}
@media screen and (max-width: 72em) {
  .test .schedule-component {
    float: left;
    width: 100%;
    position: relative;
  }
  .test .schedule-component ul,
  .test .schedule-component li {
    list-style: none;
    position: absolute;
    margin: 0;
    padding: 0;
  }
}
@media screen and (min-width: 90em) {
  aside .schedule-component {
    float: left;
    width: 100%;
    position: relative;
  }
  aside .schedule-component ul,
  aside .schedule-component li {
    list-style: none;
    position: absolute;
    margin: 0;
    padding: 0;
  }

  main .schedule-component {
    float: left;
    width: 100%;
    position: relative;
  }
  main .schedule-component ul,
  main .schedule-component li {
    list-style: none;
    position: absolute;
    margin: 0;
    padding: 0;
  }
}

See also https://gist.github.com/jslegers/6048554#file-jslegers-responsive-mixin-scss

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