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.
Related
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);
}
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;
}
}
}
Here are two mixins
#mixin parent {
.parent & {
#content;
}
}
#mixin child($child) {
.#{$child} & {
#content;
}
}
Both mixin works fine independently.
Things which am looking for:
child can be independent
Also child mixin can be included in parent but opposite
should not be allowed.
In case someone tries to include parent into child there should
be some error message.
In css output .parent should come before .child(see example below for this point)
Point 4 example:
.test {
//some css properties
#include parent {
#include child(childboy) {
color: red;
}
}
}
as you can see this will give following output
.childboy .parent .test {
color: red;
}
As you can see .parent class is coming after .childboy.
How can we make it .parent class to come before .childboy
.parent .childboy .test {
color: red;
}
Is it possible to do with scss??
Please answer only in scss.
Thank you.
I don't think you can do it that way.
Check out this CSS-tricks post:
The & doesn't allow you to selectively traverse up your nested
selector tree to a certain place and only use a small portion of the
compiled parent selector that you want to use.
If I understand correctly, the reason why you're trying to do this with SCSS is because you want to group the .parent .childboy .test selector within .test root selector.
Here's a different way to do this with SASS:
.test {
#at-root .parent .childboy & {
color: red;
}
}
Codepen demo
Note: the trailing & appends the selectors from root downwards - here, just the .test class
From the SASS docs:
The #at-root directive causes one or more rules to be emitted at the
root of the document, rather than being nested beneath their parent
selectors.
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;
}
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;
}