This
A function that reliably gets the current scoped selector - similar to Javascript’s usage of this
.
Install
npm install seed-this --save
About
The this()
function was inspired by the $this/self
coding patterns seen in jQuery/Javascript. It’s a simple (and reliable) way to reference your current selector.
An example of the $this
variable pattern can be seen in this bit of jQuery code:
example.js
$('.menu-items').each(function() {
var $this = $(this);
if ($this.hasClass('old')) {
$this.hide();
}
else {
$this.addClass('active');
}
});
Problem
With native Sass, we have to rely on &
to reference the current selector. Although &
does reference the current selector, it also references all the selectors that come before it. It also doesn’t allow you to re-use the same selector again in recursive nesting situations (e.g. a .menu
within a .menu
).
In the following bit of Sass, we’re attemping to keep our code DRY by referencing .menu
by using &
:
example.scss
.nav {
.menu {
background: blue;
& {
margin-left: 10px;
}
}
}
The ideal (and maybe expected) CSS should look like this:
example.css
.nav .menu {
background: blue;
}
.nav .menu .menu {
margin-left: 10px;
}
But what we actually get is this:
example.css
.nav .menu {
background: blue;
}
.nav .menu {
margin-left: 10px;
}
Workarounds
A common work-aroud to this issue is to variablize &
and use the variable as your selector (similar to jQuery’s $this
or $self
):
example.scss
.nav {
.menu {
$this: &;
background: blue;
#{$this} {
margin-left: 10px;
}
}
}
However, this only works if the selector that &
is refering to is one level deep. Because .menu
is nested under .nav
, the compiled CSS results in a doubling of .nav .menu
:
example.css
.nav .menu {
background: blue; }
.nav .menu .nav .menu {
margin-left: 10px; }
Solution
Using the this()
function instead of &
will give us the results we want:
example.scss
.nav {
.menu {
$this: this(); // Replace & with this()
background: blue;
#{$this} {
margin-left: 10px;
}
}
}
example.css
.nav .menu {
background: blue; }
.nav .menu .menu {
margin-left: 10px; }
Usage
this
Reliably gets the most current selector.
this()
Returns: A selector (e.g. .menu
)
Example
example.scss
.nav {
.menu {
$this: this(); // Replace & with this()
background: blue;
#{$this} {
margin-left: 10px;
}
}
}
example.css
.nav .menu {
background: blue; }
.nav .menu .menu {
margin-left: 10px; }