LESS extend root selector - css

I need generate css like this:
header.is-sticky .menu nav > ul > li > a span {
color: #555555;
}
My LESS code looks like tihs:
header {
.menu {
nav {
> ul > li {
> a {
span {
.is-sticky & {
color: #555555;
}
}
}
}
}
}
}
But it is generated to this wrong unwanted result:
.is-sticky header .menu nav > ul > li > a span {
color: #555555;
}
How to change LESS script to generate required result?

Here is your correct code
.menu {
nav {
> ul > li {
> a {
span {
header.is-sticky & {
color: #555555;
}
}
}
}
}
}
The output will be shown as you want
header.is-sticky .menu nav > ul > li > a span {
color: #555555;
}

Related

How to reference at a parent class selector some levels up to add a variation?

How to add a variant class .navbar-dark to .navbar from the child class .dropdown-toggle by SASS?
I try to achieve this:
.nav-wrapper .navbar.navbar-dark .nav-item > .nav-link.dropdown-toggle
.nav-wrapper{
.navbar {
$navbar: #{&};
.nav-item{
> .nav-link{
&.dropdown-toggle{
#at-root #{$navbar}.navbar-dark & {
background-color: red;
}
}
}
}
}
}
Gives:
.nav-wrapper .navbar.navbar-dark .nav-wrapper .navbar .nav-item > .nav-link.dropdown-toggle {
background-color: red;
}
And
.nav-wrapper{
.navbar {
$navbar: #{&};
.nav-item{
> .nav-link{
&.dropdown-toggle{
#at-root #{$navbar}.navbar-dark {
background-color: red;
}
}
}
}
}
}
Gives:
.nav-wrapper .navbar.navbar-dark {
background-color: red;
}

Using SASS & to target a second class of a parent

Here is my code:
.grid {
> li {
// li styles
.text & {
// new li styles if .grid also has a class of .text
}
}
}
This is wrong, it seems to only work if I target something higher than .grid, but I want to be able to target .grid.text li {} so I can change the li styles based on if the .grid has an extra class, not depending on what .grid lives inside. Is this possible?
I'm trying to avoid doing this:
.grid {
> li {
// li styles
}
&.text {
li {
// new li styles
}
}
}
You could do it using the #at-root directive while mantaining the rules nested
e.g. this snippet
.grid {
> li {
color: #fff;
#at-root {
.text#{&} {
color: #000;
}
}
}
}
on SASS >= 3.3 compiles into
.grid > li {
color: #fff;
}
.text.grid > li {
color: #000;
}

Target immediate parent in LESS from within nested classes

So I have a bunch of nested classes. I'd like to target the IMMEDIATE parent from deep within the nest. So for example, I have:
.navbar {
ul {
li {
a {
.ACTIVE & {
background: red;
}
}
}
}
}
The above results in:
.ACTIVE .navbar ul li a {
background: red;
}
But what I am trying to achieve is:
.navbar ul li.ACTIVE a {
background: red;
}
Is this possible?
Do get to that path using LESS, you'd do something like
.navbar {
& > ul {
& > li {
& > a {
&.active {
background: red;
}
}
}
}
}
This will result the following selector:
.navbar > ul > li > a.active { background: red; }
EDIT:
Sorry, totally missed the most important part.... So, to get what you're trying to achieve :
.navbar {
ul {
li {
&.ACTIVE{
a {
background: red;
}
}
}
}
}

How to use > with Sass?

How can I use > symbol with Sass? I want to override this with
nav>li>a:hover, .nav>li>a:focus {
text-decoration: none;
background-color: #eee;
}
this:
nav {
li {
a:hover, a:focus { }
}
}
However, it doesn't work as > has a more strict pathing. I need to use > with my Sass. How can I do it?
Ps. Don't want to rely on !important
This may work for you:
SASS:
nav {
> li {
> a:hover, > a:focus { }
}
}
I believe this is what you're after:
SASS
nav {
> li {
> a {
&:hover, &:focus {text-decoration: none;background-color: #eee;}
}
}
}

Generating selector lists in LESS

Live demo here: http://codepen.io/KenPowers/pen/Ddfqh
Consider the following LESS code:
// Hide all list items by default and make internal labels have pointer cursors
li {
display: none;
label {
cursor: pointer;
}
}
// This function generates selectors and corresponding css
.gen (#tag) {
#sel: ~"##{tag}:checked";
#{sel} {
& ~ ul > li[data-index~=#{tag}] {
display: list-item;
}
& ~ ul > li > label[for=#{tag}] {
color: red;
}
}
}
// Generate required selectors and css
.gen("foo");
.gen("bar");
.gen("baz");
It generates the following CSS:
li {
display: none;
}
li label {
cursor: pointer;
}
#foo:checked ~ ul > li[data-index~="foo"] {
display: list-item;
}
#foo:checked ~ ul > li > label[for="foo"] {
color: red;
}
#bar:checked ~ ul > li[data-index~="bar"] {
display: list-item;
}
#bar:checked ~ ul > li > label[for="bar"] {
color: red;
}
#baz:checked ~ ul > li[data-index~="baz"] {
display: list-item;
}
#baz:checked ~ ul > li > label[for="baz"] {
color: red;
}
However, a more compressed output may look like the following:
li {
display: none;
}
li label {
cursor: pointer;
}
#foo:checked ~ ul > li[data-index~="foo"],
#bar:checked ~ ul > li[data-index~="bar"],
#baz:checked ~ ul > li[data-index~="baz"] {
display: list-item;
}
#foo:checked ~ ul > li > label[for="foo"],
#bar:checked ~ ul > li > label[for="bar"],
#baz:checked ~ ul > li > label[for="baz"] {
color: red;
}
Is there a way I can modify the original LESS to generate the second CSS listing?
In Less 1.4.0+ you can :extend a placeholder class:
.dp-list-item {
display: list-item;
}
.label-color {
color: red;
}
// This function generates selectors and corresponding css
.gen (#tag) {
#sel: ~"##{tag}:checked ~ ul > li";
#{sel} {
&[data-index~=#{tag}]:extend(.dp-list-item){}
& > label[for=#{tag}]:extend(.label-color){}
}
}
// Generate required selectors and css
.gen("foo");
.gen("bar");
.gen("baz");
Forked pen
Generated CSS:
.dp-list-item,
#foo:checked ~ ul > li[data-index~="foo"],
#bar:checked ~ ul > li[data-index~="bar"],
#baz:checked ~ ul > li[data-index~="baz"] {
display: list-item;
}
.label-color,
#foo:checked ~ ul > li > label[for="foo"],
#bar:checked ~ ul > li > label[for="bar"],
#baz:checked ~ ul > li > label[for="baz"] {
color: red;
}
As you can see, the only drawback is that both classes which I've used as placeholders will be in the generated CSS. I believe this can't be worked around until Less implements something akin to Sass' placeholder selectors.
ps. I've omitted the global li rules which are not part of the mixin for brevity.
As per OP request, here is a Sass (with .scss syntax) equivalent:
//placeholder selectors
%dp-list-item {
display: list-item;
}
%label-color {
color: red;
}
// This function generates selectors and corresponding css
#mixin gen($tag) {
##{$tag}:checked ~ ul > li {
&[data-index~=#{$tag}] {
#extend %dp-list-item;
}
& > label[for=#{$tag}] {
#extend %label-color;
}
}
}
// Generate required selectors and css
#each $item in (foo bar baz) {
#include gen($item);
}
Demo
Generated CSS:
#foo:checked ~ ul > li[data-index~=foo], #bar:checked ~ ul > li[data-index~=bar], #baz:checked ~ ul > li[data-index~=baz] {
display: list-item;
}
#foo:checked ~ ul > li > label[for=foo], #bar:checked ~ ul > li > label[for=bar], #baz:checked ~ ul > li > label[for=baz] {
color: red;
}
You can see that Sass' syntax is rather verbose when compared to Less. Sass also has some nice features such as control directives and excellent interpolation which I've applied in the example above.

Resources