SASS variable with #media in css not working - css

variables.scss:
$large-screen: 1200px;
$screen-large: #{($large-screen - 1)};
$large-down: 'screen and (max-width: #{$screen-large})';
#debug $screen-large;
In another scss file:
#import '../../styles/variables.scss';
#media #{$large-down} {
my styling…
}
Problem: It doesn’t apply the "My styling" part.
If I replace the #media line with #media only screen and (max-width: 1199px) { it does work.
Any idea what I am doing wrong?
Update: I discovered that $screen-large: #{($large-screen - 1)}; results in "1200px - 1" rather than "1199px". Is there a way in SASS to make it do the calculation instead of take it as a string?
I've tried $screen-large: calc($large-screen - 1); but it still returns that whole line as a string rather than do the calculation.

Found the solution:
variables.scss:
$large-screen: 1200px;
$screen-large: ($large-screen - 1); // Now it no longer interpolates to a string.
$large-down: 'screen and (max-width: #{$screen-large})';
In another scss file:
#import '../../styles/variables.scss';
#media #{$large-down} {
my styling…
}

Related

SCSS syntax error in safari only hack

While converting a .css file to .scss I am getting a Sass syntax error in safari only hack section.
At the following part of the code its throwing Invalid CSS after "...tio:0) { #media": expected media query (e.g. print, screen, print and screen), was "{" error.
#media screen and (min-color-index:0) and(-webkit-min-device-pixel-ratio:0) { #media
{
// some code here
}}
Your media query is invalid, you have a media query inside your media query which has no conditions.
Try this:
#media screen and (min-color-index:0) and(-webkit-min-device-pixel-ratio:0) {
// some code here
}
#media screen and (min-color-index:0) and(-webkit-min-device-pixel-ratio:0) { #media { // some code here }}
should be
#media screen and (min-color-index:0) and(-webkit-min-device-pixel-ratio:0) { // some code here }}
You have a media query inside a media query, which is invalid.
https://www.w3schools.com/css/css_rwd_mediaqueries.asp
You can use javascript to properly detect safari, something like this:
function isiPad() { return (
(navigator.userAgent.toLowerCase().indexOf(/iPad/i) > -1));}

sass load mixin conditionally based on media query

Is it possibile to load/unload mixins based on a media query? Something like this:
#if #media (min-width: 768px) {
#include mixin1;
}
#else {
#include mixin2;
}
if the condition is met, mixin2 should not be loaded at all.
Not really, the sass compiles server side, not knowing the clients screen size. The compiled css will be used for all screen widths, thus:
#include mixin2;
#media (min-width: 768px) {
#include mixin1;
}

Pass properties to less function

I'm trying to write a mixin which handles different screen sizes. I want to make it as generic as possible to try follow the DRY principle.
So far I have tried:
.vary_width(#prop, #val1, #val2, #val3) {
#media(max-width: 1023px) {
#{prop}: #val1;
}
#media(min-width: 1024px) {
#{prop}: #val2;
}
#media(min-width: 1080px) {
#{prop}: #val3;
}
}
This is failing to compile. I have also tried a suggestion (although I think it was aimed at a less version >1.4) to use use the Ignore: ~"a;#{prop}:#{value}"; command, this is not working either, compiling with to Ignore: a;margin: 5px; in CSS.
Many thanks.
Edit:
The error being received when running lessc master.less master.css:
ParseError: Unrecognised input in /path/to/file/mixins.less on line 46, column 16:
45 #media(max-width: 1023px) {
46 #{prop}: #val1;
47 }
I was using the wrong version of lessc. Credit to #seven-phases-max for the guidance.

Possible Bug in Nested Mixins in Media Queries using LESS

EDIT: RESOLVED
I am working on a way to easily write LESS code that takes parameters but still works with media queries. This is turning out to be rather convoluted, but I have gotten it working – on all sizes except one. The medium and large sizes work, but small is for some reason not printing the parameter, leaving me with css like font-size: ;.
Here I define my media sizes:
#m-small = ~"screen and (max-width: 799px)";
#m-medium = ~"screen and (min-width: 800px) and (max-width: 1299px)";
#m-large = ~"screen and (min-width: 1300px)";
Then, the main function I call, where #attr is the CSS property (e.g. font-size) and #parameter is the variable (e.g. fs-medium). To use this, I can write .media('font-size', 'fs-medium'), which is significantly less verbose than defining every media query.
Edit: There was a bug here, hence the problem; I have fixed it.
.media(#attr, #parameter) {
#media #m-small {
.small(#attr, #parameter);
}
#media #m-medium {
.medium(#attr, #parameter);
}
#media #m-large {
.large(#attr, #parameter);
}
}
These functions store the default values for parameters at various sizes, allowing me to consolidate where I define my variables, grouped by media query:
.small(#attr, #parameter) {
#fs-small : 1.4rem;
#fs-medium : 2.0rem;
#fs-large : 3.4rem;
#logo-width : 10rem;
.guards();
}
.medium(#attr, #parameter) {
#fs-small : 1.4rem;
#fs-medium : 2.4rem;
#fs-large : 3.8rem;
#logo-width : 12rem;
.guards();
}
.large(#attr, #parameter) {
#fs-small : 1.4rem;
#fs-medium : 1.8rem;
#fs-large : 5rem;
#logo-width : auto;
.guards();
}
In the above code, I call .guards() to render the content. This checks through my list of guards for one with a matching attribute, because LESS does not allow variables to be used in CSS property names. In these guards, I dynamically call the parameter, so that if I passed fs-medium, it will render #fs-medium's value.
.guards() when (#attr = 'font-size') {
font-size: ##parameter;
}
.guards() when (#attr = 'width') {
width: ##parameter;
}
Now, as I said, this works fine for the medium and large sizes, so I feel like there is either a typo in my code (I've checked) or a bug in LESS. One piece of code that uses this is as follows:
nav {
.media('font-size', 'fs-medium');
}
Which renders the following content:
#media screen and (max-width: 799px){
nav{ font-size:; }
}
#media screen and (min-width: 800px) and (max-width: 1299px){
nav{ font-size:2.4rem; }
}
#media screen and (min-width: 1300px){
nav{ font-size:1.8rem; }
}
Why is the small font-size missing?
I have discovered that I do indeed have a typo in my question, where I typed 'paremeter' under the .small mixin. I have edited it in the original post, but I am leaving it here for others trying to use media queries in LESS in a generalized way.
Verdict: typo.

Is it possible to use Foundation semantic grid mixins inside mediaqueries?

I've made a small example grid with the foundation framework(http://foundation.zurb.com/). The grid is made out of four floating elements on a desktop mode(_setting, $rowWidth 1140px)
*markup
<div id="container">
<div id="main">
<div id="column">
*scss
#container{
#include outerRow();
}
.column{
#include column(3);
}
Above mixins based on these sources: http://foundation.zurb.com/docs/sass-mixins.php
Now I want to change the column structure when the example will be viewed on a tablet in portrait mode. I've made something like this:
#media screen and (min-width: 768px) and (orientation: portrait) {
#container{
#include outerRow();
}
.column{
#include column(6);
}
}
The following error occurs:
> DEPRECATION WARNING on line 21 of /Library/Ruby/Gems/1.8/gems/zurb-foundation-3.2.3/scss/foundation/mixins/_semantic-grid.scss:
> #extending an outer selector from within #media is deprecated.
> You may only #extend selectors within the same directive.
> This will be an error in Sass 3.3.
> It can only work once #extend is supported natively in the browser.
Can anybody tell me what the working method is to re-define the column structure for each different media query in a foundation based project?
Generally speaking, all you should need to do is redefine the extend mixins like %clearfix within your media query. If those classes are defined within another file, importing the file would also work (provided you aren't placing it within some sort of control block, like an if/else statement).
Looking at the source of the project, what you're looking to do probably shouldn't be done that way (see: https://github.com/zurb/foundation/blob/master/scss/foundation/mixins/_semantic-grid.scss)
Both of the mixins referenced in your sample code generate their own media queries, so avoid invoking them twice on the same element or you'll end up with a lot of duplicate/unused CSS. Instead, just overwrite the properties that actually need modifying:
.exampleA {
#include outerRow();
#media screen and (min-width: 768px) and (orientation: portrait) {
// do not #include outerRow() again here!
// these are the only properties that are variable in the outerRow() mixin:
width: $tabletWidth;
min-width: $tabletMinWidth;
}
}
The other thing you need to realize is that once you've defined your $totalColumns, you're stuck with it when using the column mixin (see: https://github.com/zurb/foundation/blob/master/scss/foundation/mixins/_semantic-grid.scss#L64 and https://github.com/zurb/foundation/blob/master/scss/foundation/mixins/_semantic-grid.scss#L19). You can't have 6 total columns by default and then 4 for your tablet. If you need to be able to this, you could simply run the gridCalc() function yourself:
.exampleB {
#include column(6);
#media screen and (min-width: 768px) and (orientation: portrait) {
width: gridCalc(2, 6); // columns, totalColumns
}
}
If you're ok with the number of $totalColumns for your media query, pass $totalColumns as the 2nd argument.

Resources