// Responsive settings, list lengths must match
$breakpoints      : 30em, 60em, 100em;    
$breakpoint-names : small, medium, large; 

@mixin respond-to ($bp-min: false, $bp-max: false, $medium: 'screen') {
    @if type_of($bp-min) == 'string' {
        $bp-min : nth($breakpoints, index($breakpoint-names, $bp-min));
    } @else if type_of($bp-min) == 'number' {
        $bp-min : $bp-min;
    }
    
    @if type_of($bp-max) == 'string' {
        $bp-max : nth($breakpoints, index($breakpoint-names, $bp-max));
    } @else if type_of($bp-max) == 'number' {
        $bp-max : $bp-max;
    }

    $media-query-string : "#{$medium}";

    @if type_of($bp-min) == 'number' {
        $media-query-string : $media-query-string + " and (min-width: #{$bp-min})";
    }

    @if type_of($bp-max) == 'number' {
        $media-query-string : $media-query-string + " and (max-width: #{$bp-max})";
    }

    @media #{$media-query-string} { @content; }
}

// -------------------------------------------

// Usage
header {
    @include respond-to(false, small) {
        background-color: red;
    }
    
    @include respond-to(small) {
        background-color: green;
    }

    @include respond-to(small, medium) {
        background-color: blue;
    }

    @include respond-to(false, false, print) {
        display: none;
    }
    
    @include respond-to(1em, 500px, all) { // numerics work directly
    	background-color: yellow;
    }
}

// Output
@media screen and (max-width: 30em) {
  header { background-color: red; } }

@media screen and (min-width: 30em) {
  header { background-color: green; } }
    
@media screen and (min-width: 30em) and (max-width: 60em) {
  header { background-color: blue; } }
    
@media print {
  header { display: none; } }
    
@media all and (min-width: 1em) and (max-width: 500px) {
  header { background-color: yellow; } }