SASS Mixin Rewrite & (ampersand) - sass

I'm trying to write a mixin that will modify the parent selector on output. The idea is that in cases where a mixin is called, the parent selector will need to have a string replacement done on it. I have most of this working, but I can't figure out how to swallow the &.
.test {
#include alt_parent() {
content: 'test';
}
}
The mixin is something like this:
#mixin alt_parent() {
#{str-replace(unquote("#{selector_append(&)}"), "s", "x")} {
#content;
}
}
I have the string replacement working, so that isn't the problem. What I get is this (and I understand why):
.test .text {
content: 'test';
}
What I want is this:
.text {
content: 'test';
}

You have to use the #at-root directive to defeat the automatic inclusion of the selectors represented by &.
http://alwaystwisted.com/articles/2014-03-08-using-sass-33s-at-root-for-piece-of-mind
#mixin alt_parent($parent) {
#at-root {
#{str-replace(unquote("#{selector_append(&)}"), "s", "x")} {
#content;
}
}
}

Related

SASS prefix custom element

I try to prefix a custom element that looks like this <myprefix-toggle></myprefix-toggle>. It does not work. However if I add # as if it would be an id it does compile. Why and how can I get around it?
Works
$prefix: "myprefix-";
#{$prefix}toggle {
background: red;
}
Does not work
$prefix: "myprefix-";
{$prefix}toggle {
background: red;
}
The error I get is probably not that related to the real issue...
Error: expected ':' after $prefix in assignment statement
If it's of importance I use gulp-sass to compile the sass to css.
The hashtag and the curly brackets is the Sass syntax for interpolation #{ ... }
$prefix: "myprefix-";
// CSS output
#{$prefix}toggle { ... } // myprefix-toggle { ... }
.#{$prefix}toggle { ... } // .myprefix-toggle { ... }
##{$prefix}toggle { ... } // #myprefix-toggle { ... }

Is it possible to pass in variables such that it adds to the actual scss variables?

I have a scss code like below
.hello-station {
&-hello123 {
.site-logo__image {
#extend .logos--hello-123;
margin: 27px 0;
}
}
}
Now you can see that the word "hello" is repeated throughout... So is the number.
I will like to create a mixin or function such that the word and the number can be passed along as variables. Is that possible?
Pretty simple actually, Sass/SCSS offers a concatenation syntax:
$word: 'hello';
$number: 123;
.#{$word}-station {
&-#{$word}#{$number} {
.site-logo__image {
#extend .logos--#{$word}-#{$number};
margin: 27px 0;
}
}
}

Conditionally output a part of SCSS rule selector

I would like to specify an additional default shortcut class to a set of classes, similarly to that
#each $pos, $some-css-rules in ("left": ..., "right": ..., ...) {
#if $pos == "left" {
.block,
}
.block-#($pos) {
...
}
}
that would be outputted as
.block,
.block-left {
...
}
.block-right {
...
}
However, it will stumble over .block, syntax error.
.block-left cannot be replaced here with .block.left because $pos will collide with existing classes (.left, etc).
I would prefer to avoid .block { #extend .block-left } if possible, there is a considerable amount of similar rules that will gain a lot of WET code this way.
Is there a way to conditionally output a part of rule selector? How can both SCSS and CSS be kept DRY in a pattern like that?
I'm not sure if I understand the question but I achieve the output CSS based on your code. I put the #if directive inside the selector to compare with $pos variable. Here is my code:
SASS
#each $pos, $some-css-rules in ("left": red, "right": blue) {
.block-#{$pos} {
#if $pos == "left" {
#at-root .block, &{
color:$some-css-rules;
}
}
#else{
color:$some-css-rules;
}
}
}
Output
.block, .block-left {
color: red;
}
.block-right {
color: blue;
}

How do I reference the parent selector at the end? [duplicate]

This question already has an answer here:
Append the parent selector to the end with Sass
(1 answer)
Closed 7 years ago.
How can I turn this:
.btn-primary {
.open .dropdown-toggle.btn-primary { ... }
}
into
.btn-primary {
.open .dropdown-toggle& { ... }
}
I keep getting invalid selector after .dropdown-toggle
If you read the complete error, it should say this:
"&" may only be used at the beginning of a compound selector.
However, .dropdown-toggle.btn-primary is the same as .btn-primary.dropdown-toggle. So place the parent selector at the beginning:
.btn-primary {
.open &.dropdown-toggle { color: blue; }
}
As of Sass 3.4, you can do that like this:
.btn-primary {
.open .dropdown-toggle#{&} { color: blue; }
}
No offense, but I'm not sure you understand what is & used for.. Just in case I'm right here is the explanation:
Sometimes it’s useful to use a nested rule’s parent selector in other ways than the default.
For instance, you might want to have special styles for when that selector is hovered over or
for when the body element has a certain class. In these cases, you can explicitly specify where the parent selector should be inserted using the & character.
Example:
p{
background: red;
&:hover{
background: blue;
}
&:active {
background: blue;
}
}
Which will be converted to this:
p {
background:red;
}
p:hover {
background:red;
}
p:active {
background:red;
}

Prepending parent selectors in SCSS

I want to nest selectors by prepending the parent selector in SCSS.
The basic selector is:
.selector-class .selector-class__element {}
Here is the HTML:
<div class="selector-class">
<div class="selector-class__element"></div>
</div>
(A) Here is the desired result in SCSS:
.selector-class {
.selector-class__element {
}
}
(B) This is the idea behind how I want to do it: (Does not work)
.selector-class {
&__element {
}
}
Is there a more effecient way of doing it than using the method in (A) ?
You just need to add an extra ampersand at the beginning:
.selector-class {
& &__element {
background: red;
}
}
You need to try this one. This is just an example for both class and element. You may try any one of them.
.selector-class {
&.class, &div { background: blue; }
}
EDIT
Below is the interpolation method of concatenating string.
.selector-class {
&#{'__element'} { background: blue; }
}
CSS
.selector-class .selector-class__element { background: blue; }
more about interpolation
interpolation

Resources