Is there a way to use the parent selector (&) with selector-append (sass:selector) - sass

I am trying to achieve the following in scss:
&.-icon-default, &.-icon-darker, &.-icon-dark {...}
However, using selector-append like:
#{selector-append(".-icon", "-default, -darker, -dark")} {...}
helps me achieve the following:
.-icon-default, .-icon-darker, .-icon-dark {...}
So I want to use the parent selector along with selector-append. Passing it directly to the strings in argument of selector-append gives me an error. Is there a way to solve this using selector-append or will I have to hardcode all such instances without using the selector-append function?

Include the & in the first argument. This SCSS:
div {
#{selector-append("&.-icon", "-default, -darker, -dark")} {
font-size: 2rem;
}
}
... compiles to this CSS:
div.-icon-default, div.-icon-darker, div.-icon-dark {
font-size: 2rem;
}
Is that the result you want?

Related

Pass variable name as parameter in SCSS [duplicate]

I have a very simple mixin which looks like this:
#mixin global( $variable-name ) {
font-size: #{$variable-name}-font-size;
}
I have previously defined variable $input-font-size and pass it into the mixin in the following format
#include global( input );
Problem is that the sass is not converting it and browser returns :
font-size:input-font-size
How should I write my mixin to actually return the value from $input-font-size please?
Thank you for your advice in advance!
You can't create a dynamic variables in sass.
'#{}' means it will convert whatever attribute to its plain css form, it won't be treated as a variable it will be treated as a text.
What you can do is create a map for the list of properties and call them inside the mixin.
$input-font-size: 16px;
$textarea-font-size: 14px;
$var-map: (
input: $input-font-size,
textarea: $textarea-font-size,
);
#mixin global( $variable-name ) {
font-size: map-get($var-map, $variable-name);
}
body {
#include global( input );
}
or if you dont want to create the map then you can simply pass the variable name in the mixin
#mixin sec( $variable-name ) {
font-size: $variable-name;
}
.text-area {
#include sec( $textarea-font-size );
}
Sample pen
https://codepen.io/srajagop/pen/aWedNM

What Sass Mixin returns?

In a programming language like javascript, even though I don't make any a "returned" result in the end, but it still returns a value, "undefined".
In case of Sass, I know that #mixin does not "return" anything like #function.
However, it "actually" returns nothing at all?
If it returns something actually (something like "undefined" or "void"), then what it returns?
I'm not sure I get the question but...
Mixins lets you create reusable CSS declarations (CSS content) 'called' using #include.
Unlike functions you can't assign mixins to variables as they do not produce a return value (throws an error).
#function fs($value){
#return $value;
}
#mixin fs($value){
font-size: $value;
...
}
.class { // returns value
font-size: fs(16px); // => 16px;
}
.class { // generates properties and values
#include fs(16px); // => font-size: 16px; ...
}
$var: fs(16px); // will work (function)
$var: #include fs(16px); // won't work (mixin)
Try to read this article and this one, you have some answer :
"They obtain full CSS rules where properties that are dynamic will be passed into arguments"
So when you #include a #mixin in your code, it will return CSS rules.

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

In Sass, is it possible to use a selector value as variable

Is it possible to use the value of a selector as a variable?
.warning {
color:Red;
border:1px solid #{.warning.color};
}
or
.total {
padding-top:#{.font-size};
color:Red;
}
No. SASS does not build the object model in mind when parsing the code.
You'll have to keep all the necessary stuff in variables.

How to use !important keyword in a mixin?

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

Resources