SASS - Referencing parent selector with #at-root in loop - sass

I have a problem that I cannot understand. When I'm trying to remove parent selector with #at-root rule nothing changes in sass selector output.
.contact {
// Define first.
$styles: one, two, three;
// Mixins.
#import 'styles/mixins';
// Import placeholders.
#import 'styles/style-one/base';
#import 'styles/style-two/base';
#import 'styles/style-three/base';
// Loop through each style.
#each $style in $styles {
#at-root .form-style-#{$style}#{&} {
#extend %style-#{$style};
}
}
}
I'm expecting output like this:
.form-style-three.contact .field { border-color:#2d2d37 }
but instead of code above, I'm getting selector like this:
.contact .form-style-three.contact .field { border-color:#2d2d37 }
Am I missing something here? Is it loop that is causing this issue?
node-sass 4.13.0 (Wrapper) [JavaScript]
libsass 3.5.4 (Sass Compiler) [C/C++]

Here is the answer: https://www.sassmeister.com/gist/b0083f2459cadbbd787331e8d8e63976
you have to add #at-root rule to imported placeholders, not to the rules in loop.

Related

sass : import only a part

I have 2 scss files, I want to use one mixin from the first into the second, but without importing the rest of the file ( I have a few url() who don't react well into this file
someDir/F1.scss
#mixin somemixin($width, $height) {
}
.someClass {
#include somemixin(17px, 10px);
background-image: url('./someUrl');
}
anotherDir/anotherAnotherDir/F2.scss
#import '../../someDir/F1';
.someOtherClass {
#include somemixin(17px, 10px);
background-image: url('./someOtherUrl');
}
How can I do it?
You can instead try #use module instead of #import and make only mixins public or decide on what you want to make public from file 1.
Check it here
https://sass-lang.com/documentation/at-rules/use

Sass extend class from module

With the new module system in sass (with #use instead of #import) how can i define a class in one file and the use it in another file with #extend ?
File colors.scss
.element {
background-color: blue;
}
main file
#use "./colors.scss" as colors;
body {
#extend .element;
}
This gives the following error:
"body" failed to #extend ".element".
The selector ".element" was not found.
Use "#extend .element !optional" if the extend should be able to fail.
Example:
https://stackblitz.com/edit/angular-tufq7f?file=src%2Fstyles.scss
How can I tell sass to get it from colors.scss?
Turns out there are a few different problems here. The first is that the stacblitz example is using an old version of sass witch does not have module support. The other is that there is no way to specify from witch sass module to extend a css class from. The correct solution is what I wrote in the question:
#extend .element;
Does the following work?
#use "./colors.scss" as colors;
body {
#extend colors.element;
}
(Modules are imported as a namespace, so you have to 'use' the 'module' by it's name)
https://sass-lang.com/documentation/at-rules/use#choosing-a-namespace

CSS Modules, Composition in nested class

I am working on a project where there is a main style.scss file for a number of components. I want to restructure the code so as every component has its own folder (index.js, styles.scss). There is a nested class that is using a class from another component and now that I have to separate all the styles, this part is broken. I can't use composition since it is a nested class. What other approaches can I take?
The code looks like this:
// Component A styless.scss
.component-a-class {
}
// Component B styless.scss
.component-b-class{
.component-a-class {
}
}
Use Sass's #import directive to import the external classes. Your code would become something like this:
// ComponentA/styless.scss
.component-a-class {
...
}
// ComponentB/styless.scss
.component-b-class{
#import "../ComponentA/styless.scss"
}
This will inject .component-a-class into the .component-b-class as a nested rule.
Edit: To import a style and also be able to modify one of its properties' values, you have to make use of Sass mixins:
// ComponentA/styless.scss
#mixin component-a-class($width: 100) {
.component-a-class {
width: $width + px;
}
}
#include component-a-class();
// ComponentB/styless.scss
#import "../ComponentA/style.scss";
.component-b-class{
#include component-a-class(500);
}
This will get you what you want, though it isn't ideal. The resulting compiled ComponentB/styless.css file will include everything written in ComponentA/styless.scss because the #import directive is an "all-or-nothing" feature (there is no selective import). The result would look like this:
// ComponentB/styless.css (compiled)
.component-a-class {
width: 100px;
}
.component-b-class .component-a-class {
width: 500px;
}

SCSS #import with & to children to class

I know you can do an import inside a class like this:
.my-class
{
#import "another-file.scss";
}
Such that a class .foo in another-file.scss will compile to .my-class .foo in the output.
What I want to do is import a file such that all the rules in the file get a certain class added to them, like this:
.my-class
{
&#import "another-file.scss";
}
Such that .foo in another-file.scss will compile to .my-class.foo in the output.
I'm building a set of components that all share a class because they are all part of the same "kit", and I want them all to share a class that denotes them as such, but I don't want to have them all in the same file under one giant nest.
Is this possible?
Thanks!
To accomplish this, you just need to preface the selectors in the file you are importing with &.
For example, if you were to import the following file, it would create rules for .my-class.header, my-class.header.cool and my-class.footer:
&.header {
color: blue;
&.cool {
font-size: 20px;
}
}
&.footer {
color: blue;
}

What is the equivalent of LESS's "import (reference) 'style'" in SASS

In addition to application.css.scss, I have multiple partials like homepage.css.scss. At the moment I have to add #import 'bootstrap' to each one of them in order to use bootstrap variables and mixins.
Let's say I want to change my default links colour to red, I'd add that to application.css.scss. But the links in homepage.css.scss will not be red because the bootstrap import will override it with blue.
In LESS, I can do #import (reference) "bootstrap", how can I do that in SASS?
The closest you will get is a silent class / placeholder. These work a little different to how LESS and reference work, you can read more on them here: http://blog.teamtreehouse.com/extending-placeholder-selectors-with-sass
LESS
lib.less
.class {
background: red;
}
main.less
#import (reference) "lib";
.anotherClass {
&:extend(.class);
}
SASS
lib.sass
%class {
background: red;
}
main.sass
#import "lib";
.anotherClass {
#extend %class;
}
CSS Output
.anotherClass {
background: red;
}

Resources