I am switching from LESS to SASS but have some difficulties to use it
very simple less variable + function Less :
#mini :0.1rem;
#brown:#533a38;
.border(#color:#brown){border:#mini solid #color;}
I use it :
#contact-form{
.border();
}
how can I do the same with SASS ?
thank you
$mini :0.1rem;
$brown:#533a38;
#mixin border($color:$brown){border:$mini solid $color;}
Use mixin if you don't want to return anything. Now when we use border:
#contact-form{
border: #include border;
}
Related
I couldn't find a solution for this problem: I need to set a margin in SASS with a max between 2 values, one is a calc() and the other is a regular px value. It would be something like this:
$calculation: calc(15vw + 10px);
.cssClass {
margin-right: max($calculation, 100px);
}
Any ideas on how to create a SCSS function or some way to make this work? Thank you in advance!
The Sass max() function doesn't work with values that have different units.
That said, you can use the CSS max() function by overriding the Sass version with your own:
// Override Sass function
#function max($numbers...) {
#return m#{a}x(#{$numbers});
}
$calculation: calc(15vw + 10px);
.cssClass {
margin-right: max($calculation, 100px);
}
...the SCSS above compiles to this CSS:
.cssClass {
margin-right: max(calc(15vw + 10px), 100px);
}
Credit to Jianqiu Xiao on GitHub for pointing out this solution. Having to create a custom function is an unfortunate Sass compiler quirk, though it has apparently been fixed in Dart Sass already.
How to solve the incompatible units problem?
#mixin square-size($size, $min: $size, $max: $size) {
$clamp-size: min(max($size, $min), $max);
width: $clamp-size;
height: $clamp-size;
}
The input is:
#include square-size(10vw, 40px, 70px);
Problem:
Incompatible units: 'vw' and 'px'.
node_modules\#ionic\app-scripts\dist\util\helpers.js:253.replace(/&/g, '&')
But if I use calc(1vw - 1px) it works. (no unit problem).
e.g. max(calc(1vw - 1px)) does not work. Because no number for max.
In my case I want a mixin to square the size of an element. Including clamp.
min-width, max-width, etc. does not work. It will be a rect or an ellipse. Because it does not keep the aspect ratio.
I want a element with dynamic size but with min and max size.
I understand that the dynamic unit vw (Viewport) must be present after sass compilation. Therefore it is not possible to convert the value to a fixed unit.
But is there no way?
I was able to fix the error in React SASS using the calc function.
font-size: calc(max(8vw, 30px));
If you're unable to work around it in any other way, SCSS has a function for ignoring things in quotes:
width: unquote("max(50px, 5rem)");
This will be compiled without the quotes and be valid CSS.
width: max(50px, 5rem);
It will be strange to have this in your scss, but it's a sure-fire way of allowing modern CSS to not interrupt your scss functions
The Problem
CSS didn't use to have its own runtime min() and max() functions, and before they existed SASS had a compile-time version. Since SASS doesn't run live it would be impossible for it to determine whether 10vw or 40px is larger - hence the error.
The Solution
Since SASS is case sensitive while CSS isn't, you can force the parser to use the CSS version of min or max by just calling MIN() or MAX() instead. If you need to resume SASS parsing inside of MAX() ( like to reference a SASS variable ) just surround the SASS code with #{...}.
Here's a fixed version of your code to demonstrate:
#mixin square-size($size, $min: $size, $max: $size) {
/* $clamp-size: min(max($size, $min), $max); */
$clamp-size: MIN(MAX(#{$size}, #{$min}), #{$max});
width: $clamp-size;
height: $clamp-size;
}
Good luck!
You would need to bypass the scss compiler & use a literal instead.
#mixin square-size($size, $min: $size, $max: $size) {
$clamp-size: #{'min(max(#{$size}, #{$min}), #{$max})'};
width: $clamp-size;
height: $clamp-size;
}
Try this
when doing min or max in sass, if you get incompatible units error, you can simply put the value in a quotation, and it will let it pass.
min(10vw, 20px) to"min(10vw, 20px)"
This works for other functions too.
And if you are using variables in calculations, you use #{} on the variables to make it pass
$a: 10px;
$b: 25%;
.mydiv {
width: calc(#{$a} - #{$b});
}
And the #{} converts them to string so that sass wouldn't make arithmetic using them while compiling
You could do it like this using min-width/height and max-width/height to avoid mixing units:
#mixin square-size($size, $min: $size, $max: $size) {
min-width: $min;
max-width: $max;
min-height: $min;
max-height: $max;
width: $size;
height: $size;
}
.class {
#include square-size(10vw, 40px, 70px);
}
For this, instead of SCSS #include
.foo {
#include square-size(10vw, 40px, 70px);
}
use better css function "clamp":
.foo {
width:clamp(10vw, 40px, 70px);
height:clamp(10vw, 40px, 70px);
}
I don't know why but while compiling with grunt or anything there is an error called invalid property name
#flotTip {
border: none !important;
font-size: $font-size-small !important;
line-height: 1px !important;
#extend .tooltip-inner() !important;
}
in the above code in the line-height it produces an undefined property. My task was to convert all less files into sass files. Used many solutions to convert all of them to sass as far as I can find. But this one I can't find any solution. Can anyone answer what might be the problem?
Extend is only for extending simple selectors, like class, element, or id. You cannot use !important with #extend. This is the correct way to use extend:
.foo {
color: red;
}
#flotTip {
#extend .foo;
}
You may be confused confusing extends with mixins, which also cannot use !important. This is the correct way to use mixins:
#mixin foo() {
color: red;
}
#flotTip {
#include foo();
}
The line-height: 1px !important; line looks fine. The problem is with the following line. If you're trying to include a mixin, use #include and don't prefix the mixin's name with . (dot). Also, don't put !important after it.
I would guess that you are using #extend incorrectly. See the docs here: http://sass-lang.com/documentation/file.SASS_REFERENCE.html#how_it_works
the problem that i have with this mixing is that i can't interpolation for calling different sprite mixins that compass provides.
I want to be able to have this in one place, create the sprites in different scss and them just include this shared mixing and use it.
So far seems that Sass doesn't allow me to do that. Maybe i just have a crazy and bad way of doing things ( i'm no designer really and i learn about sass a few months ago ).
Thanks for your time.
#mixin icon-button($width, $height, $icon-bg-color, $icon, $sprite-name){
.icon-base{
width: $width;
height: $height;
background-color: $icon-bg-color;
.icon{
$icon-height: #{$sprite-name}-sprite-height(#{$icon});
$icon-width: #{$sprite-name}-sprite-width(#{$icon});
#include #{$sprite-name}-sprite(#{$icon});
width: $icon-width;
height: $icon-height;
position: relative;
left: ($width - $icon-width)/2;
top: ($height - $icon-height)/2;
}
}
}
The #{something} is a ruby-way of interpolation. Compass framework uses ruby compiler to make css from scss/sass. Interpolation is just the way to insert some value (of a variable) into a string, like this: puts "I want to say #{smth}" will print "I want to say something" into irb console if you previously defined the smth = "something" variable. You also may notice the difference between ' and ". So, sometimes you would like to use standalone functions in compass like this:
headings(all) {
color: $color;
}
to compile it into css:
h1, h2, h3, h4, h5, h6 {
color: #2a2a2a;
}
Instead, it throws an error. So, to do this you need to interpolate the call of the function:
#{headings(all)} {
color: $color;
}
And it runs. But if you try to make interpolation with variables:
$color: #abc;
$color2: "#abc";
#mixin some($color) {
color: #{$color};
}
will also throw an error because in this case interpolation outputs a string "#abc".
Try to avoid using ruby syntax in compass if it is possible for cleaner style.
Note: I would appreciate if someone can explain with better compilation details because i'm not a rubyist, i'm pythonist.
Update
Check this code:
#mixin setFonting($from, $to, $size) {
$curr: $from;
$to: $to + 3;
#while $curr != $to {
h#{$curr} {
font-size: $size;
}
$curr: $curr + 1;
$size: $size + 2;
}
}
#include setFonting(1, 3, 20px);
It compiles to :
h1 {font-size: 20px;} h2 {font-size: 22px;} h3 {font-size: 24px;} h4 {font-size: 26px;} h5 {font-size: 28px;}
So as you see, #{} interpolation in compass works outside curly brackets used to define statements for selector.
If I'm using compass for CSS and use a function or mixin like:
#include background-image(linear-gradient(#a3cce0, #fff));
is there any easy way to have compass add !important to every line it generates?
You can include it inside the mixin like so:
#include border-radius(5px !important);
Compass will output the following:
-webkit-border-radius: 5px !important;
-moz-border-radius: 5px !important;
-ms-border-radius: 5px !important;
-o-border-radius: 5px !important;
border-radius: 5px !important;
UPDATE: new versions of sass support this syntax now:
#include border-radius(5px !important);
Just do this (as noted in #naoufal answer).
--- old answer ---
You can not use !important with compass mixings, but the culprit is not compass, you should blame sass for this.
#include border-radius(5px) !important; #=> SASS Syntax Error
Actually you can use a #function to handle the !important while keeping the flexibility of the mixing itself. For example:
#function is-important($important){
#return #{if($important, '!important', '')};
}
// by default we don't want the !important at the end
#mixin button-primary($important: false) {
font-size: 14px;
background: #fff is-important($important);
color: #000 is-important($important);
}
Hope it helps!
Just spent hours figuring this out but there is a quick trick you can do. At the top of your SASS file add the following:
$i: unquote("!important");
in your style do the following:
color: #CCCCCC $i;
output is:
color: #CCCCCC !important;
full sample:
$i: unquote("!important");
.some-style {
color: white $i;
}
output:
.some-style {
color: white !important;
}
This question came up in my search for a similar problem, it's spot on but I just wanted to add that Making a Sass mixin with optional arguments was another possible approach that I found useful.
Replace inset with important and pass !important in when you need it.
I had this problem last time and I overrided the compass style with a stronger selector. I just added an ID on my html element
span { #include border-radius(5px);}
span#no-radius { #include border-radius(0px); } // override