Sass - Keep original class nesting - css

Sorry for the bad title, not sure how to name it.
While I'm compiling my scss, this:
.foo {
...
&__bar { ... }
}
it turns into code below, which is what you would expect:
.foo { ... }
.foo__bar { ... }
My problem is that I need it to be this way:
.foo { ... }
.foo .foo__bar { ... }
with .foo selector before .foo__bar.
Is there any Webpack plugin or other solution that would help to solve my problem?
I've found two ways to achive that, but I'm wondering if there's something that would save me from additional code:
.foo {
...
& &__bar { ... }
}
// or
.foo {
...
.foo__bar { ... }
}

If you intend to get this
.foo { ... }
.foo .foo__bar { ... }
You need to write your scss like this :
.foo {
......
&.foo__bar {
.......
}
}
Please try this and see if it works ?

Related

The Sass ampersand and attribute selectors

I want to create a sass file that the selectors will be attribute selectors.
When I work with class selectors, in most of the cases I will do
.parent {
&-child {
}
}
which gives me the following css: .parent-child {}.
I want to achieve the same thing with attribute selectors:
[data-parent] {
&-child {
}
}
which I want to become: [data-parent-child] {}
someone knows how to achieve this? thanks.
You can use this mixin as a workaround to get the desired result.
#mixin child-attribute($child) {
$string: inspect(&);
$original: str-slice($string, 3, -4);
#at-root #{ selector-replace(&, &, "[#{$original}#{$child}]" ) } {
#content;
}
}
The code simply does the following
$string variable is responsible for turning the parent selector to a string using the inspect function
$original variable is responsible for getting the text content of the $string variable i.e the value 'data-parent' from '([data-parent])'
selector-replace function then replaces the parent selector with the concatenation of the $original variable and child variable
When used in the following ways
[data-parent] {
#include child-attribute('-child') {
color: green;
}
}
The css output
[data-parent-child] {
color: green;
}
Depending on what you want to achieve, it can also be used like this
[grandparent] {
#include child-attribute('-parent') {
color: white;
#include child-attribute('-child') {
color: blue;
}
}
}
Which generates the following css
[grandparent-parent] {
color: white;
}
[grandparent-parent-child] {
color: blue;
}
Hope this helps you
You can create mixin that will set styles for elements with data attribytes.
Scss:
#mixin data($name) {
[data-#{$name}] {
#content;
}
}
* {
#include data('lol') {
color: red;
};
}
Css output:
* [data-lol] {
color: red;
}
DEMO
I would go down a slightly different route of having a class on your elements that contain the data attributes.
<div class="data-obj" data-parent="true"></div>
<div class="data-obj" data-parent-child="true"></div>
then in your SASS do
.data-obj {
...
&[data-parent] { ... }
&[data-parent-child] { ... }
}

SASS/SCSS does not accept &.&

Inside my component I'd like to add a modifier, which should have a higher specification so my output should look like this:
Wanted output:
.component {
// ...
}
.component.component--modifier {
// ...
}
SCSS Suggestion:
.component {
// ...
&.&--modifier {
// ...
}
}
But this does not work, I'm getting compile errors: Kind of "format errors" or "invalid CSS".
You could define a mixin:
#mixin mod($n) {
.#{$n} {
color: blue;
}
.#{$n}.#{$n}--modifier {
color: red;
}
}
#include mod(component);
Output:
.component {
color: blue;
}
.component.component--modifier {
color: red;
}
But there's probably a more raisonnable approach to your real problem, like having a modifier class.
You have a period next to the & (&.&). This would produce component..component--modifier, which is incorrect(two periods). What you really want is && but sass doesn't let you do this. What you want to do is escape the second & like this:
&#{&}--modifier
A simpler solution is to interpolate the second & by putting it into #{&}:
.component {
// ...
&#{&}--modifier {
// ...
}
}
Note: The dot between the two & is not needed, because & contains it already.
An equivalent mixin related to Densys would be:
#mixin modifier($modifier) {
&#{&}--#{$modifier} {
#content;
}
}
Usage:
.component {
#include modifier(breadcrumb) {
// ...
}
}

How can I create a Sass mixin with a class as a variable

I am trying to write something like this :
#mixin variableChild($child:".theChild") {
//some css
$child {
//css specific to the child
}
}
#parent { #include variableChild(".specificChild"); };
So it would generate this CSS :
#parent {//some css}
#parent .specificChild {
//css specific to the child
}
You were almost right, you just missed the #{} around your child selector I think. There’s more information about it in the Sass documentation.
#mixin variableChild($child:".theChild") {
#{$child} {
color: red;
}
}
#parent {
#include variableChild(".specificChild");
};
http://jsfiddle.net/UrLdB/

Multiple two-class selectors in Sass

Having multiple two-class selectors for a single declaration block, is it possible to simplify the following (i.e. not having to repeat the body tag):
body.shop, body.contact, body.about, body.faq {background-color:#fff;}
try this:
body{
&.shop, &.contact, &.about, &.faq {
background-color:#fff;
}
}
In this case we can use #each directive:
$pages: shop, contact, about, faq;
body {
#each $page in $pages {
&.#{$page} {
background-color:#FFF;
}
}
}
sassmeister.com
body {
&.shop, &.contact {
// Styles here...
}
}
If you are using sass compiled by the node, that may do.
body {
.shop, .contact, .about, .faq {
background-color:#FFFFFF;
}
}
Parent child relationship in sass
parent_tag {
.child {
// rules here
}
}

Extending a Nested Placeholder in SCSS

Is it possible to #extend a SCSS placeholder with nesting, and have that nesting reflected in the resulting class?
Given a nested placeholder:
%my-form-field {
...
&__label {
...
}
&__feedback {
...
}
}
I currently have to do the following:
.one-of-many-targets {
#extend %my-form-field;
&__label {
#extend %my-form-field__label;
}
&__feedback {
#extend %my-form-field__feedback;
}
}
But I'd like to be able to simplify this to:
.one-of-many-targets {
#extend %my-form-field;
}
... and have it resolve to:
.one-of-many-targets { ... }
.one-of-many-targets__label { ... }
.one-of-many-targets__feedback { ... }
Is there a different way to write my placeholder and #extends to make the SCSS cleaner, as in the 2nd example?
You can use a mixin instead:
#mixin my-form-field() {
width: 10px;
&__label {
width: 20px;
}
&__feedback {
width: 30px;
}
}
.one-of-many-targets {
#include my-form-field();
}
will generate:
.one-of-many-targets {
width: 10px;
}
.one-of-many-targets__label {
width: 20px;
}
.one-of-many-targets__feedback {
width: 30px;
}
You could try use selector.append()
See: https://github.com/sass/sass/issues/2808#issuecomment-574413393
Also see more info why parent selector didn't work as you expect in extend-only selectors: https://github.com/sass/sass/issues/2262#issuecomment-291645428

Resources