Reputation: 237
I'm trying to get my breakpoints setup following this tutorial. They are working correctly when I target just one property. When I try to create a query that targets two (width and height) it only displays the latter. I've researched the Sass functions that I'm using and it should be rendering correctly so I'm not sure what the problem is. I'm using sass-rails on Ruby on Rails version 4.2.2.
Thanx
$breakpoints: (
'small' : ( max-width: 20em ),
'mobile' : ( min-width: 36.25em ),
'tablet' : ( min-width: 48em ),
'desktop' : ( min-width: 60em ),
'wide' : ( min-width: 75em ),
'height' : ( min-width: 75em ) and (min-height: 62.5em)
);
@mixin media($name) {
@if map-has-key($breakpoints, $name) {
@media #{inspect(map-get($breakpoints, $name))} {
@content;
}
}
@else {
@warn "Unfortunately, no value could be retrieved from `#{$breakpoint}`. "
+ "Please make sure it is defined in `$breakpoints` map.";
}
}
This is what is rendered:
@media (min-height: 62.5em) {
}
Upvotes: 2
Views: 3434
Reputation: 568
This is what I use when wanting to target more then one media query (obviously set your queries to what ever you wish):
$size__site_content_width : 1024px;
/* Media Queries */
$media_queries : (
'mobile' : "only screen and (max-width: 667px)",
'tablet' : "only screen and (min-width: 668px) and (max-width: $size__site_content_width)",
'desktop' : "only screen and (min-width: ($size__site_content_width + 1))",
'retina2' : "only screen and (-webkit-min-device-pixel-ratio: 2) and (min-resolution: 192dpi)",
'retina3' : "only screen and (-webkit-min-device-pixel-ratio: 3) and (min-resolution: 288dpi)",
'landscape' : "screen and (orientation:landscape) ",
'portrait' : "screen and (orientation:portrait) "
);
@mixin for_breakpoint($breakpoints) {
$conditions : ();
@each $breakpoint in $breakpoints {
// If the key exists in the map
@if map-has-key($media_queries, $breakpoint) {
$conditions: append(
$conditions,
#{inspect(map-get($media_queries, $breakpoint))},
comma
);
}
@else {
@warn "Unfortunately, no value could be retrieved from `#{$breakpoint}`. "
+ "Please make sure it is defined in `$breakpoints` map.";
}
}
@media #{$conditions} {
@content;
}
}
And us it like this in my scss:
#masthead {
background: white;
border-bottom:1px solid #eee;
height: 90px;
padding: 0 20px;
@include for_breakpoint(mobile desktop) {
height:70px;
position:fixed;
width:100%;
top:0;
}
}
and that outputs this:
#masthead {
background: white;
border-bottom: 1px solid #eee;
height: 90px;
padding: 0 20px;
}
@media only screen and (max-width: 667px), only screen and (min-width: 1025px) {
#masthead {
height: 70px;
position: fixed;
width: 100%;
top: 0;
}
}
Upvotes: 0
Reputation: 2418
Normally when storing media queries in variables or as values in a key value pair, they should be stored as strings. Check out these sites Media Queries by David Walsh and Responsive Web Design in Sass by Mason Wendell
Replace this line of code
'height' : ( min-width: 75em ) and (min-height: 62.5em)
with
'height' : "( min-width: 75em ) and (min-height: 62.5em)"
Now that the values passed to the mixin can either be a string or list, the mixin needs to recognise these changes
@mixin media($name) {
@if map-has-key($breakpoints, $name) {
$value: map-get($breakpoints, $name);
$query: if(type-of($value) == "string", $value, inspect($value));
@media #{$query} {
@content;
}
}
@else {
@warn "Unfortunately, no value could be retrieved from `#{$breakpoint}`. "
+ "Please make sure it is defined in `$breakpoints` map.";
}
}
$breakpoints: (
'small' : ( max-width: 20em ),
'wide' : "( min-width: 75em ) and (min-height: 62.5em) and (max-height: 100em)",
'height' : "( min-width: 75em ) and (min-height: 62.5em)"
);
div.gta {
@include media(wide) { ... }
}
div#mgs {
@include media(height) { ... }
}
This compiles to the following CSS
@media (min-width: 75em) and (min-height: 62.5em) and (max-height: 100em) {
div.gta { ... }
}
@media (min-width: 75em) and (min-height: 62.5em) {
div#mgs { ... }
}
This will allow the mixin to be used on any number of media queries
Upvotes: 4