Reputation: 44393
I'm using Sass (.scss) for my current project.
Following example:
HTML
<div class="container desc">
<div class="hello">
Hello World
</div>
</div>
SCSS
.container {
background:red;
color:white;
.hello {
padding-left:50px;
}
}
This works great.
Can I handle multiple classes while using nested styles.
In the sample above I'm talking about this:
CSS
.container.desc {
background:blue;
}
In this case all div.container
would normally be red
but div.container.desc
would be blue.
How can I nest this inside container
with Sass?
Upvotes: 485
Views: 530054
Reputation: 51241
You can use the parent selector reference &
, it will be replaced by the parent selector after compilation:
For your example:
.container {
background:red;
&.desc{
background:blue;
}
}
/* compiles to: */
.container {
background: red;
}
.container.desc {
background: blue;
}
The &
will completely resolve, so if your parent selector is nested itself, the nesting will be resolved before replacing the &
.
This notation is most often used to write pseudo-elements and -classes:
.element{
&:hover{ ... }
&:nth-child(1){ ... }
}
However, you can place the &
at virtually any position you like*, so the following is possible too:
.container {
background:red;
#id &{
background:blue;
}
}
/* compiles to: */
.container {
background: red;
}
#id .container {
background: blue;
}
However be aware, that this somehow breaks your nesting structure and thus may increase the effort of finding a specific rule in your stylesheet.
*: No other characters than whitespaces are allowed in front of the &
. So you cannot do a direct concatenation of selector
+&
- #id&
would throw an error.
Upvotes: 806
Reputation: 41
Christoph's answer is perfect. Sometimes however you may want to go more classes up than one. In this case you could try the @at-root
and #{}
css features which would enable two root classes to sit next to each other using &
.
This wouldn't work (due to the nothing before &
rule):
container {
background:red;
color:white;
.desc& {
background: blue;
}
.hello {
padding-left:50px;
}
}
But this would (using @at-root plus #{&}
):
container {
background:red;
color:white;
@at-root .desc#{&} {
background: blue;
}
.hello {
padding-left:50px;
}
}
Upvotes: 4
Reputation: 2128
this worked for me
<div class="container">
<div class="desc">
desc
</div>
<div class="asc">
asc
</div>
</div>
.container{
&.desc {
background: blue;
}
&.asc {
background: red;
}
}
Upvotes: 0
Reputation: 47
In addition to Cristoph's answer, if you want to be more specific in your declaration you can refer to all children of a container class component. This can be done with:
.container {
// ...
#{&}.hello {
padding-left: 50px;
}
}
This compiles to:
.container .container.hello {
padding-left: 50px;
}
I hope this be helpful to you!
Upvotes: 3
Reputation: 746
Use &
SCSS
.container {
background:red;
color:white;
&.hello {
padding-left:50px;
}
}
https://sass-lang.com/documentation/style-rules/parent-selector
Upvotes: 6
Reputation: 371
If that is the case, I think you need to use a better way of creating a class name or a class name convention. For example, like you said you want the .container
class to have different color according to a specific usage or appearance. You can do this:
SCSS
.container {
background: red;
&--desc {
background: blue;
}
// or you can do a more specific name
&--blue {
background: blue;
}
&--red {
background: red;
}
}
CSS
.container {
background: red;
}
.container--desc {
background: blue;
}
.container--blue {
background: blue;
}
.container--red {
background: red;
}
The code above is based on BEM Methodology in class naming conventions. You can check this link: BEM — Block Element Modifier Methodology
Upvotes: 32