Sass Placeholders from Mixins - css

I want to create Sass placeholders on the fly using arbitrary values passed from a style block:
#mixin example-mixin($arg) {
%placeholder-#{$arg} {
property: $arg;
}
#extend %placeholder-#{$arg};
}
Calling the mixin:
.classname {
#include example-mixin('value');
}
This almost works, but for some reason in the CSS output the .classname is given twice as though it's a descendant selector:
.classname .classname {
property: value;
}
I'm not seeing the logic behind the duplicate class names - can anyone see what I'm doing wrong and/or suggest a workaround?

Let's look at what happens if you use real classes instead of extend classes
.a {
.b {
color: blue;
}
#extend .b;
}
Output:
.a .b, .a .a {
color: blue;
}
The only reason I could imagine you wanting to do this is so you can use the extend class for purposes of extending instead of .classname like so:
.c {
#extend .b;
}
You'll see that the output probably isn't what you want at all:
.a .b, .a .a, .a .c {
color: blue;
}
The .a .a doesn't make a whole lot of sense to me either, but it's harmless. What you're actually wanting to do is something like this:
%placeholder-name, .classname {
property: name;
}
.foo {
#extend %placeholder-name;
}
And the output will be like this:
.foo, .classname {
property: name;
}

Related

What does this mixin mean?

In a scss file, I saw the below code snippet:
#mixin myMixin() {
:global(.rtl) & {
#content;
}
}
I understand the keywords #mixinas well as #content and tried to understand :global() from this link:
What does :global (colon global) do?.
But I am not sure what "&" does here or what this whole mixin does.
The ampersand (&) is a combinator used in nesting and in this case it is being used to qualify a selector.
For a general example:
// This Sass...
.foo {
.bar & {
color: red;
}
}
// ...would compile to this CSS
.bar .foo { color:red; }
In your example, the mixin declaration replaces .foo, and would look like:
// If you called your mixin at .bar
.bar {
#include myMixin {
color: red;
}
}
// It should compile to something like this
:global(.rtl) .bar { color: red; }
More details about ampersands and qualifying selectors in this CSS Tricks article.

SASS - How can I assign two classes the same style except one property?

I have a SASS stylesheet and I want to assign the same styles for two classes (.class and .otherclass) except for one property (before:) which should have another value for .otherclass.
This is the code I currently have:
.class, .otherclass {
p { font-family:arial;
&before:
#extend .class-one {}
}
~ .extraclass {}
}
Thanks
To be quite honest I'm not sure why u don't want to write two different selectors, or just overide some property in second one. E.g
.class1, .class2, .class3 {
&:before{
content: 'class';
}
}
.class2:before {
content: 'class2';
}
Maybe using :not selector would be helpfull:https://www.w3schools.com/cssref/sel_not.asp
.class1, .class2, .class3 {
&:before {
content: 'class'
}
&:not(.class1):before{
content: 'class23'
}
}
Please try to look like:
.test{
$color:#f00;
}
.demo{
&:extend(.test);
}

Increase specificity weight with double selector via Sass

As mentioned here on Stack Overflow in another question and MDN tells about the specificity of selectors, I want to slightly increase the weight of my selector via Sass to override some existing styles. Here's an example of the (compiled) CSS.
.parent .parent__child.parent__child { color: red; }
It is more specific than just using .parent .parent__child as a selector.
I have a way to do this via Sass, but I think there should be a better way to do this:
.parent {
&__child.parent__child { color: red; }
}
Ideally, this would be the best possible setup (the ampersands have to be directly attached to each other since it's not a child selector):
.parent {
&__child&__child { color: red; }
}
This throws an error and adds a dot between the 'child' selectors. The Sass documentation doesn't say anything about this particular case. Any ideas on how to achieve this?
edit
I know about the interpolation brackets method, but what if the selector is more profound than three or four layers deep? I only want its parent selector to be duplicated, not the whole selector tree.
There's a special trick in SASS for doubling specificity using interpolation brackets (more on that here and here) since two &'s next to each other is invalid SASS syntax.
.parent {
&__child {
&#{&} {
color: red;
}
}
}
// compiles to
// .parent__child.parent__child { color: red; }
// You can also do this with deeper nested elements by
// prefacing the interpolation with the ancestor selectors:
.parent {
&__child {
.some .ancestor .elements &#{&} {
color: red;
}
}
}
// compiles to
// .some .ancestor .elements .parent__child.parent__child { color: red; }
For those of you who stumble upon this and use LESS, double &&'s are allowed:
.parent {
&__child {
&& {
color: red;
}
}
}

Less cascading & refactoring

I am trying to refactor some css looking like this:
path.myClass {
//some CSS
}
.someOtherClass.myClass {
//some other CSS
}
I am struggling to find the right syntax for the first part. I am trying to have something looking like this:
.myClass {
path.& {
// some CSS
}
.someOtherClass {
// some other CSS
}
}
How can I refactor this correctly?
You can do it like below. Since the top level selector already has . there is no need to add it again before the parent selector (&) in the inner selector. The second one is fairly straightforward as you can append the parent selector either at the start or at the end. The order of classes doesn't matter.
(Note: There should be no space before the parent selector as it would change the meaning.)
.myClass {
path&{
color: red;
}
.someOtherClass& { /* can do &.someOtherClass also, order doesn't matter */
color: blue;
}
}
Below is the compiled CSS output:
path.myClass {
color: red;
}
.someOtherClass.myClass {
color: blue;
}

Is it possible to create a required class as nested class in less?

Is it possible to write a nested version of
.foo.bar
in less? Like
.foo {
.bar { } // ='nested'; creates '.foo .bar' tho
}
Yes, you can reference the parent selector by using the & operator.
.foo {
&.bar {
color: #f00;
}
}
Which compiles to:
.foo.bar {
color: #f00;
}

Resources