SASS compilation error with nth-child selector - css

So I did a bit of research around here and was unable to find an answer, so hopefully, somebody here can help me out...
I have the following SASS code
$column: 7;
table
{
th:nth-child($column)
{
// This does NOT compile
}
th:nth-child(7)
{
// This does compile
}
}
Why is it that using the nth-child selector in combination with a variable does not compile within SASS? Is there any alternative I can go about using a dynamic value with the nth-child selector?

A variable must be interpolated when used with a selector (e.g. as an argument to a functional pseudo-class). In your case, the syntax should look something like this:
$column: 7;
table
{
th:nth-child(#{$column})
{
// ...
}
}

Related

SASS loop to generate chained :not() from variables string

I have a long list of classes I wish to use in a couple of ways.
The list looks something like this (but much longer):
$my-components: '.some-component', '.some-other-component', '.another-component';
One of the ways I need to use this list of class names in SASS (scss), which I can't figure out, is to create a long chained selector of :not()s. The final rendered output should look like this:
.parent {
> * {
&:last-of-type:not(.some-component):not(.some-other-component):not(.another-component):not(etc) {
// style rules
}
}
}
(The goal being to select the last child element of .parent that doesn't have one of the classes in the list).
Question: How can I make the above code DRY by using the $my-components variable?
Note 1: The loop's output needs to be able to be appended to that &:last-of-type, as in above example.
Note 2: I'm using the $my-components variable already in a different function, so I'd like to keep it in the same format if possible.
Note 3: I know this seems hacky and stupid, and that I should just give all of those elements a common shared class instead. But unfortunately I can not currently modify that part of the DOM.
Use a #each loop
scss:
$my-components: '.some-component', '.some-other-component', '.another-component';
.parent {
> * {
$selector: '';
#each $component in $my-components {
$selector: $selector + ":not(#{$component})"
}
&:last-of-type#{$selector} {
color: blue;
}
}
}
css:
.parent > *:last-of-type:not(.some-component):not(.some-other-component):not(.another-component) {
color: blue;
}
What's happening ?
I define a new string variable $selector.
During the #each loop, I'm concatening the string with :not(#{$component}) to add your new selector.

How to make parent selector interpolated in the middle of nested selector in sass/scss

I'd like to get the result below using sass nesting
css
.box {...}
h3.box-title {...}
I tried code like this, but it causes an error.
sass
.box {
h3.&-title {
...
}
}
I'd like to know if there is any way to do this keeping sass nesting?
I know that it's not good to write HTML element on CSS,
but I'm working on a project that I can't modify existing CSS and need to overwrite them.
Try this:
.box {
#at-root h3#{&}-title {
...
}
}
I used the sass interpolation #{} to compile expectedly the value of &, and #at-root to prevent the prefix .box (prevent resulting to .box h3.box-title because we want h3.box-title only - without the prefix .box)
Here's the captured result:
Anyway, I don't think this is a good practice to write sass/scss
.box
and
.box-title
are two different class names. Unless h3.box-title is a child of .box, honestly, there's no reason you should be nesting it.
Also & is used to look for additional class names. i.e.
.box {
&.box-title {}
}
would be
.box.box-title {}

use variables on mixin or extend in Less.js

Using variable on mixin or extend in Less.js as follow will throw error.
#bar : bar;
.#{bar} {
background: yellow;
}
// ParseError: Missing closing ')'
.foo {
.#{bar}();
}
// Not work
.jam {
&:extend(.#{bar});
}
Has Less.js a proper syntax to call mixin with variables?
You are trying to call a mixin using selector interpolation, which is not possible.
As for extend, Less documentation states it clearly:
Extend is NOT able to match selectors with variables. If selector contains variable, extend will ignore it.

Concatenate String for class name in LESS

I am converting LESS to CSS, there I want to run the LESS function below:
.myPL( #val ) {
.pL #val{
padding-left:#val;
}
}
Function Call:
.myPL( 20px );
Expected result:
.pL20px{padding-left:20px}
But actual result is Syntax Error.
Please help me to concatenate the strings in class name in LESS.
What you are looking for is called selector interpolation ... you can find it here: http://lesscss.org/#-selector-interpolation
Your mixin would need to look like this for it to work:
.myPL( #val ) {
.pL#{val} {
padding-left: #val;
}
}
What you are trying to achieve does not work in LESS:
You could do:
.myPL( #val ) {
padding-left: #val;
}
Why on earth would you manually define each possible variant of padding left with the classname itself? That's not what LESS was designed for, and doesn't really make much sense with the context you've given.
The idea of mixins is to make them reusable, but I can't understand why you'd call a classname in the middle of that mixin. Use LESS mixins properly, and do the following:
.pl(#val) {
padding-left: #val;
}

difference in id selector and namespace in less

I am trying to learn less to reduce the pain of repetitive css. One thing that confuses me is the syntax of namespace in less. To my understanding, less is compatible with css, therefore
#myelement-id{}
is an id selector. On the other hand, less supports namespace by specifying
#namespace{}
So, when I read a less file, how can I tell which "#" is for id selector and which is for namespace?
Thanks for your help.
There is no difference. A #id or .class can be used as a namespace call to access its other classes or mixins. To make it different, you need to make it a mixin. So either of these is valid:
#namespace {
.test {
prop: 1;
}
}
#namespace() {
.test {
prop: 1;
}
}
The first will produce css output as an id selector, the second will not. But either can access the nested values, so either of these work inside a selector block to access the .test class via this:
.class {
#namespace > .test;
}
But the output will be different, as the first will be:
#namespace .test {
prop: 1;
}
.class {
prop: 1;
}
And the second just:
.class {
prop: 1;
}
More over, there's no difference even between a mixin and a namespace. A namespace can also be parametric (though parametric namespaces have some unusual properties/side-effects that make them differ from non-parametric namespaces). See for example #1205, #1316, #1525.
Basically, LESS namespace is just any ruleset that contains another ruleset(s). It's more like a logical concept/convention, not a language construction.

Resources