SASS - Passing collection to sass mixin as an argument - collections

How to pass collection to a sass mixin ?
=media($type1, $size1: null)
#if ($type1) and ($size1)
#media ($type1: $size1)
#content
#elseif ($type1) and not ($size1)
$collection: $type1
#media (nth($collection, 1): nth($collection, 2)) <-- ERROR
#content
#else
#error "Upsss...."
Use case
$m: "36em"
$minw: "min-width
$tablet: ("type1": $minw, "size1": $m)
+media($tablet) <-- ERROR
p
font-size: 2em

Sorted. I had to use #{map-get($collection, $key-name)} function
=media($type1, $size1: null)
#if ($type1) and ($size1)
#media ($type1: $size1)
#content
#elseif ($type1) and not ($size1)
$collection: $type1
#media (#{map-get($collection, "type1")}: #{map-get($collection, "size1")})
#content
#else
#error "Upsss...."

Related

SASS variable with #media in css not working

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…
}

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;
}

Variable interpolation for a media query property in less - missing closing ")"

I'm trying to "translate" a sass function into a less function.
Here is the original SASS one :
#mixin bp($feature, $value) {
// Set global device param
$media: only screen;
// Media queries supported
#if $mq-support == true {
#media #{$media} and ($feature: $value) {
#content;
}
// Media queries not supported
} #else {
#if $feature == 'min-width' {
#if $value <= $mq-fixed-value {
#content;
}
} #else if $feature == 'max-width' {
#if $value >= $mq-fixed-value {
#content;
}
}
}
}
And here is the function I started to make in less as it seems every declaration can not be implemented the same as in sass :
.bp(#feature; #val) when (#mq-support = true) {
#med: ~"only screen";
#media #{med} and (#{feature}:#val) {
#content;
}
}
When I'm compiling this, I got the following error :
Missing closing ')' on line 15, column 34:
15 #media #{med} and (#{feature}:#val) {
16 #content;
So this error seems to come from the closing #{feature} closing bracket but following the documentation and several blog posts on the internet, it seems that since the 1.6.0 version of less, the css property interpolation is a feature that should work.
Does anybody have an idea of what could be wrong here ?
Is it actually possible to use a variable as a property in a media query ?
Maybe I'm doing it totally wrong but it seems the mixins guard feature in less does not work exactly the same as with SASS and the #if condition so the "translation" is a little bit different.
Thank you in advance
Sébastien
Interpolation or using variables in media queries work slightly differently in Less.
First of all, you shouldn't use the normal interpolation syntax (#{med}). Instead it should just be #med.
Next the second condition should also be set to a variable and then appended to the media query just like the #med variable or it should be included as part of the #med variable itself. I've given a sample for both approaches below.
.bp(#feature; #val) when (#mq-support = true) {
#med: ~"only screen and";
#med2: ~"(#{feature}:#{val})";
#media #med #med2{
#content();
}
}
or
.bp(#feature; #val) when (#mq-support = true) {
#med: ~"only screen and (#{feature}:#{val})";
#media #med {
#content();
}
}
Below is a sample conversion of that Sass code completely into its Less equivalent. Less does not support the #content like in Less, so it should be passed as a detached ruleset with the mixin call.
#mq-support: true;
#mq-fixed-value: 20px;
.bp(#feature; #val; #content) {
& when (#mq-support = true) {
#med: ~"only screen and (#{feature}:#{val})";
#media #med {
#content();
}
}
& when not (#mq-support = true) {
& when (#feature = min-width) {
& when (#val <= #mq-fixed-value){
#content();
}
}
& when (#feature = max-width) {
& when (#val >= #mq-fixed-value){
#content();
}
}
}
}
a{
.bp(max-width, 100px, { color: red; } );
}
b{
.bp(min-width, 10px, { color: blue; } );
}

Print media queries using less.css loop

I'm using less.css as css preprocessor, and i was wonder if it is possible to print out media queries using less.css loops.
I've tried a very basic example loop:
#iterations: 30;
.loopingClass (#index) when (#index > 0) {
(~".myclass_#{index}") {
font-size: -#index px;
}
.loopingClass(#index - 1);
}
.loopingClass (0) {}
.loopingClass (#iterations);
but this will end up creating a class.
According to this example:
http://codepen.io/ericrasch/pen/HzoEx?editors=110
we can create media queries in less using this syntax:
#mobile: ~"only screen and (max-width: 529px)";
body {
#media #mobile {
background: orange;
content: "mobile";
}
}
But, as you can see, the media query value is a variable and not a class. So my question is, can i use less.css loop to print out media queries value as variable instead of classes? Or there's any workaround for this issue?
Thanks in advance

sass using variable as mixin data

I'm using grid from csswizardry and wanting to create breakpoints as variables...
If defined as standard "strings":
$breakpoints: (
'palm' '(max-width: 480px)'
)!default;
But when I change it to:
$palmmaxwidth: 480px;
$breakpoints: (
'palm' '(max-width: $palmmaxwidth)'
)!default;
it will not compile correctly within the mixin:
#mixin grid-media-query($media-query){
$breakpoint-found: false;
#each $breakpoint in $breakpoints{
$name: nth($breakpoint, 1);
$declaration: nth($breakpoint, 2);
#if $media-query == $name and $declaration{
$breakpoint-found: true;
#media only screen and #{$declaration}{
#content;
}
}
}
#if $breakpoint-found == false{
#warn "Breakpoint ‘#{$media-query}’ does not exist"
}
}
The error is Invalid CSS after "...nd (max-width: ": expected expression (e.g. 1px, bold), was "$palmmaxwidth)"
What am I missing?
The solution is quite simple after trying every possible combination:
$breakpoints: (
'palm' '(max-width: '+$palmmaxwidth+')'
)!default;

Resources