Skip to content

Instantly share code, notes, and snippets.

@micahgodbolt
Created June 24, 2013 16:08
Show Gist options
  • Select an option

  • Save micahgodbolt/5851228 to your computer and use it in GitHub Desktop.

Select an option

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

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

@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

jpavon commented Jun 24, 2013

Copy link
Copy Markdown

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

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

@micahgodbolt

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

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

jpavon commented Jun 24, 2013

Copy link
Copy Markdown

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

@lajlev

lajlev commented Jun 25, 2013

Copy link
Copy Markdown

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

@micahgodbolt

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

jwebcat commented Jun 28, 2013

Copy link
Copy Markdown

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

@micahgodbolt

Copy link
Copy Markdown
Author

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

@jslegers

Copy link
Copy Markdown

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