How to use !important keyword in a mixin? - sass

I can't get Sass to output the !important keyword with a mixin, I've tried:
#include font-size($font-size-sml) !important;
And:
#include font-size($font-size-sml !important);
It always throws an error.
EDIT
I ended up with this which works fine:
#mixin font-size($font-size, $sledge-hammer: "") {
font-size: $font-size #{$sledge-hammer};
font-size: ($font-size / $base-font-size)+rem #{$sledge-hammer};
line-height: ceil($font-size / $base-line-height) * ($base-line-height / $font-size);
}

You can't add !important to whole mixin in SASS (It is possible in LESS I think) like you're trying to do in first example.
Second example works for me (you can pass !important with a parameter), I mean, if you use $font-size-sml directly as a property value it works, so maybe check your syntax.
But if it's really not working for you, you can do something with flag, set a important_flag as a mixin parameter and then use if-else statement in mixin. Something like this:
#mixin large-text($prop, $is_imp: false) {
#if $is_imp == false {
font-size: $prop;
} #else {
font-size: $prop !important;
}
}
Maybe it's not a glamorous way to do it, but it works ;-)

You can use the if(condition, when-true, when-false) function.
So the code will be simplest and compact:
#mixin large-text($size, $isImportant: false) {
font-size: $size if($isImportant, !important, null);
}

Related

Inline scss variable as the name part in the evaluation of another scss variable

Suppose I have the following scss variables:
$until-xs: "(max-width: 377px)";
$until-sm: "(max-width: 640px)";
...
$until-xl: "(max-width: 4000px)";
And based on them the following helper css classes are constructed:
.until-sm {
display: none;
#media #{$until-xs} {
display: block !important;
}
}
.until-md {
display: none !important;
#media #{$until-sm} {
display: block !important;
}
}
/* plus a lot of classes like this */
I am trying to create a mixin that would help me define those classes more easily by passing the $until-x variable as an input to the mixin, like so:
#mixin until($x) {
display: none;
#media #{'$until-'#{$x}} {
display: block !important;
}
}
Such that the classes above will be defined simply as:
.until-xs { #include until($until-xs); }
The problem is the media variable inlining part does not evaluate the way I wanted, like:
#{'$until-'#{$x}} (when x is 'xs') =>
#{'$until-xs'} =>
#{$until-xs} =>
(max-width: 377px)
Any way I can achieve this? Since this can be applied in multiple places in my project I am more interested in the possibility of inlining vars like this than the solution to the particular problem from the example.
Instead of defining lots of variables like $until-xs, $until-sm and so on, you can define a map that contains information of your medias like the code below:
#use "sass:map";
$until-var: ("xs": "(max-width: 377px)", "sm": "(max-width: 620px)", "md": "(max-width: 807px)");
#mixin until($x) {
display: none;
#media #{map.get($until-var, $x)} {
display: block !important;
}
}
/* using that in your classes */
.until-xs { #include until("xs"); }
.until-sm { #include until("sm"); }
I'm not sure what you mean by inlining vars! But if you want a single mixin that works for different medias, I think that works.

Ampersand and mixins in SCSS

Searched but can't find an answer..
I have an element which gets generated (by an external platform) with the following classes: p-button and button.
Now the SCSS is like this:
.p-button {
&.button {
margin: 10px;
}
}
But I want to refactor using mixin includes (this is a big project so there is no other way of making this code better except using mixins). The mixin takes the given selector and applies a . to it. I can't change the mixin, as it is used by many other teams, so I can't pass the ampersand together with the selector. I tried this:
.p-button {
& {
#include button-appearance("button") {
margin: 10px;
}
}
}
But that doesn't work (puts a space between it). You can't do this:
.p-button {
&#include button-appearance("button") {
margin: 10px;
}
}
Anyone have a clue?
EDIT: Here is the mixin
#mixin button-appearance(
$appearance-class,
$show,
$background-color,
$background-image,
$background-position) {
$sel: $button-selector;
#if $appearance-class {
$sel: $sel + '.' + $appearance-class;
}
#{$sel} {
#include normalized-background-image($background-image);
#include show($show);
background-color: $background-color;
background-position: $background-position;
}
#content;
}
EDIT 2: Here is the $button-selector (I can not edit this in the platform, but maybe overwrite it in my own project?)
$button-class: 'p-button';
$button-selector: '.#{$button-class}';
Everyone, finally found the solution. I just removed the &.button from the .p-button mixin include and now it works:
#include button-appearance ("button") { *styles* }
#include button-appearance () { *styles* }
Edited the answer after the original question was edited adding the used and un modifiable mixin
The original mixin does not append the ‘#content’ passed to the mixin to the generated selector. So if you cannot modify the original mixin, the only way is to add your properties outside the mixin. According to the mixin the selector will match a predefined ‘$button-selector’ variable, so it won’t use your class.
So, if you want to use the same class defined in ‘$button-class’, try the following:
#{$button-selector}.button {
margin: 10px;
}
Will output:
.p-button.button {
margin: 10px;
}

SASS/SCSS change variable value before extend

I have Bootstrap 3.3.7 and custom scss files.
I want to override $grid-float-breakpoint only once before #extend evaluates. Right now I have 3 classes which extend base bootstrap class (they use default value, so i don't want to mess with them).
In doc when using mixins and include it's possible. Is it possible using .class and #extend?
I'm looking for something like
$foo : 1px;
.normal-class {
font-size: $foo;
}
.extended-normal-class {
#extend .normal-class;
font-color: yellow;
}
-- This is what I'm trying to do: ---------------------
.override-class {
$foo: 3px;
#extend .normal-class;
// font-size in this class after compile should have 3px;
}
To achiev what you need, you must use #mixin instead of #extend, heres follow an example:
#mixin size($size: 1px){
font-size: $size;
}
.extended-normal-class{
#include size();
}
.override-class{
#include size(3px);
}

compiling sass with grunt produce invalid property name

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

Giving default arguments to mixins when there is more than one variable

I am trying to make a #mixin where I want to give a default value to the first variable but not to the second variable.
#mixin myCoolFont($color:purple, $size) {
color: $color;
font-size: $size;
}
Now when I call that mixin I do something like this:
p {
#include myCoolFont(white, 63px)
}
When compiling it outputs an error that says $size must come before any other arguments.
Please, tell me, what am I doing wrong?
You just do as error says, it will work, simple change order of arguments so that last argument(s) are those with default values. In your case:
#mixin myCoolFont($size, $color:purple) {
color: $color;
font-size: $size;
}
p {
#include myCoolFont(63px, white)
}

Resources