sass how to instantiate an empty variable to be set by #if - css

I think the code speaks for itself so this is what I have:
#mixin btnNoBackgr30($divName, $iconName, $xtypeYesOrNo ){
$xtypeBtn:nil;
#if xtypeYesOrNo == 'yes'{
$xtypeBtn:x-button-#{$divName};
}
#if xtypeYesOrNo == 'no'{
$xtypeBtn:#{$divName};
}
.#{$xtypeBtn}{
properties:values;
}
all I get in css is this
.nil{
properties:values;
}
How can instantiate the variable outside the #if?
If I do it inside the #if ofc it wont be detected outside the scope like normal programming and marked ans 'undefined'
Please help. false do the same and Null give me errors

give $xtypeBtn some random default value as it will be reset anyway? If $xtypeYesOrNo can be undefined, give it a default value too?
#mixin btnNoBackgr30($divName, $iconName, $xtypeYesOrNo:default) {
$xtypeBtn:default;
#if $xtypeYesOrNo != default {
// do whatever
}
#if xtypeYesOrNo == yes {
$xtypeBtn: x-button-#{$divName};
}
#if xtypeYesOrNo == no {
$xtypeBtn: #{$divName};
}
.#{$xtypeBtn} {
properties: values;
}
}

Related

How to check in SCSS if a variable exists and ha a value?

I am new in SCSS so bear with me :)
I have a use case where a SCSS variable --my-variable can exist and can have a value depending on some settings from the backend. So, if --my-variable exists and has a value I should override some styling. If not I shouldn't override anything.
Example:
In file1 I have:
.my-div {
color: red;
}
In file2 I should have something like this:
.my-div {
#include customize(color, --my-variable);
}
#mixin customize($property, $variable) {
#if $variable and (var($variable)) {
#{$property}: var($variable);
}
}
The problem is that the if condition inside the mixin customize() is always true even if my document has no CSS variable called --my-variable. What am I doing wrong?
Thank you
Sass has a function that check if the variable exists.
variable-exists()
$colorVariable: crimson;
#if variable-exists($colorVariable) {
// Do some styling if the variable exists
}

SASS mixin outputs function in compiled CSS

My compiled CSS when viewed has a SASS function in it that was never compiled. This is presumably caused by the mixin I'm using to auto generate classes. I have no idea how to fix it.
SASS code:
$rsColors: (
main: (
base: #333030,
lighter:#827a7a,
light:#5a5555,
dark:#0c0b0b,
darker:#000000,
red: #211010,
accent:#999595,
border: #666666
),
link: (
base: #c42727,
lighter:#eb9999,
light:#de5959,
dark:#841a1a,
darker:#440e0e,
hover:#841a1a,
bg:rgba(80, 80, 80, 0.8),
bgHover: #cccccc
)
}
#mixin modifiers($map, $attribute, $prefix: '-', $hover: 'false', $separator: '-',$base: 'base', $type: 'darken', $perc: '15%') {
#each $key, $value in $map {
&#{if($key != $base, #{$prefix}#{$key}, '')} {
#if type-of($value) == 'map' {
#include modifiers($value, $attribute, $separator, $hover);
}
#else {
#{$attribute}: $value;
#if $hover == 'true' {
&:hover {
$function: get-function($type);
#{$attribute}: call($function,$value,$perc);
}
}
}
}
}
}
.rsBg {
#include modifiers($rsColors, 'background', $hover: 'true');
}
Compiled CSS (as viewed from style editor in Firefox inspector):
...
.rsBg-yellow-700 {
background: #b7791f;
}
.rsBg-yellow-700:hover {
background: darken(#b7791f, 15%);
}
...
How can I fix the compiled CSS so it's rendered correctly? I figure the mixin is to blame since it's outputting what I'm telling it to. Why it's not compiling before being output to CSS?
Expected Output:
...
.rsBg-yellow-700 {
background: #b7791f;
}
.rsBg-yellow-700:hover {
background: #915300; //assuming 15% darken
}
...
**Edit**
After some testing I have found I needed to add the ```get-function()``` method to get ```call()``` to work. However, no matter what I try I can not get the ```$perc``` variable in such a way as to not throw a "not a number" error. I can hard code percentages and it will compile without errors.. but I'd rather not have to do that.
The problem actually comes from the way you call the function and not the mixin. Instead of:
#{$attribute}: unquote(#{$type}($value, #{unquote($perc)}));
You should use the built-in function call() as below:
#{$attribute}: call($type, $value, $perc);
You also need to remove the quotation marks for the parameter $perc or you will get an error such as: $amount: "15%" is not a number for 'darken'. I tried to remove them with unquote() but it doesn't seem to work.
The answer to this issue was the use of '' in the arguments. Specifically the $lightness variable (which was changed from the #perc variable). Once I removed the quotes and just let it hang there, everything compiled and worked fine.
I removed the $type variable and changed the function to scale_color as it seemed to fit better with what I wanted. I should probably change the argument variable to a different name so not to be confused with the scale_color() argument. A task for a different day though.
PLEASE NOTE: I am accepting #Arkellys answer because it set me on the right path to this answer, and I feel really weird about accepting my own answer. I just added this answer so if another comes along it might help. Thank you #Arkellys for your help!
The final mixin
#mixin modifiers($map, $attribute, $prefix: '-', $hover: 'false', $separator: '-',$base: 'base', $lightness: -15%) {
#each $key, $color in $map {
&#{if($key != $base, #{$prefix}#{$key}, '')} {
#if type-of($color) == 'map' {
#include modifiers($color, $attribute, $separator, $hover);
}
#else {
#{$attribute}: $color;
#if $hover == 'true' {
&:hover {
#{$attribute}: scale_color($color,$lightness: $lightness);
}
}
}
}
}
}
.rsBg {
#include modifiers($rsColors, 'background', $hover: 'true', $lightness: -20%);
}

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

Extjs 4.2 - gradient background for menus using sencha cmd

I would like to create a gradient background color using sencha cmd
here is what I have tried :
.#{$prefix}-menu-body{
#include background-image(linear-gradient(#47607E, #35475B));
}
I have placed it under
sass\src\menu\Menu.scss
and run a package build.
I do not see any change in the background of my menus.
I would also like to know if I can use the CSS Variables to do that?
menu is a panel ui .
Ext.panel.Panel
view source
extjs-panel-ui( $ui-label, [$ui-border-color], [$ui-border-radius], [$ui-border-width], [$ui-padding], [$ui-header-color], [$ui-header-font-family], [$ui-header-font-size], [$ui-header-font-weight], [$ui-header-line-height], [$ui-header-border-color], [$ui-header-border-width], [$ui-header-border-style], [$ui-header-background-color], [$ui-header-background-gradient], [$ui-header-inner-border-color], [$ui-header-inner-border-width], [$ui-header-text-padding], [$ui-header-text-transform], [$ui-header-padding], [$ui-header-icon-width], [$ui-header-icon-height], [$ui-header-icon-spacing], [$ui-header-icon-background-position], [$ui-header-glyph-color], [$ui-header-glyph-opacity], [$ui-tool-spacing], [$ui-tool-background-image], [$ui-body-color], [$ui-body-border-color], [$ui-body-border-width], [$ui-body-border-style], [$ui-body-background-color], [$ui-body-font-size], [$ui-body-font-weight], [$ui-background-stretch-top], [$ui-background-stretch-bottom], [$ui-background-stretch-right], [$ui-background-stretch-left], [$ui-include-border-management-rules], [$ui-wrap-border-color], [$ui-wrap-border-width] )
Creates a visual theme for a Panel
put these in your menu.scss
#include extjs-panel-ui(
$ui-label: 'your-ui-label-when-used-in 'ui' property',
$ui-body-background-gradient: color-stops(#F950AD, #E4007f),
$ui-border-color:#E4007f,
$ui-body-background-color:#E4007f,
$ui-body-border-width:0px,
$ui-border-radius:5px,
$ui-body-font-size:1.6em
);
in ext-theme-neutral /sass/panel/panel.scss
add
$ui-body-background-gradient: $panel-body-background-gradient,
// $panel-body-background-gradient is in your theme, var/panel/panel.scss
//$ui-body-background-gradient is the var you are going to use.
edit panel-body scss
// body
.#{$prefix}panel-body-#{$ui-label} {
#if $ui-body-background-color != null { background: $ui-body-background-color; }
#if $ui-body-border-color != null { border-color: $ui-body-border-color; }
#if $ui-body-color != null { color: $ui-body-color; }
#if $ui-body-font-size != null { font-size: $ui-body-font-size; }
#if $ui-body-font-weight != null { font-size: $ui-body-font-weight; }
#if $ui-body-border-width != null {
border-width: $ui-body-border-width;
#if $ui-body-border-style != null { border-style: $ui-body-border-style; }
}
//$ui-body-background-gradient: $panel-body-background-gradient,
////$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ add it !!!
#if $ui-body-background-gradient !=null {
#include background-gradient(
$ui-body-background-color,
$ui-body-background-gradient,
top
);
}
}

Get variable name from variable value in SASS/SCSS

I'd like to access variable within an #each loop using defined value like in the following example:
$car:true;
$people:false;
$job:false;
#mixin options($someval){
#each $prefix in car,people,job{
#if $#{$prefix} == true{
//some CSS...
}
}
}
Variable would be a sort of "semaphores" that define whether print or not Css rules.
My big doubt is how can I check over dynamically defined variables name ?
I've tried with $#{$prefix} but it doesn't work.
EDIT ---------------------------
I'd like to obtain this CSS
car-something: 34px;
Where the word "car" is taken from $prefix and in the first round of #each loop $#{$prefix} becomes $car
The problem is on $#{$prefix} ... it doesn't work :P i get an error
This is an old question but since it has no valid answer, here it is
You need to pass a map to #each
$car:true;
$people:false;
$job:false;
#mixin options($someval){
#each $key, $val in (car: $car, people: $people, job: $job) {
#if $val == true{
#{$key}-something: $someval
}
}
}
test {
#include options(34px)
}
Instead of trying to interpolate a variable name, pass a list to the mixin.
$car: true;
$people: false;
$job: false;
$thing-list: $car, $people, $job;
#mixin thingamajig($thing-list) {
#each $thing in $thing-list {
#if $thing {
// Some CSS
}
}
}

Resources