use variables on mixin or extend in Less.js - css

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.

Related

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 {}

Using mixin inside the same selector in LESS?

I'm trying to achieve something like this in LESS:
.a {
// some properties
}
.b {
.a {
.a();
}
}
It doesn't work, because it takes the .a() from the closest scope, which is .b .a in this case. I need this quirky rule just to overwrite another context for .a to use the default .a styles.
Can I call a mixin of the same selector in LESS? Or maybe there are some workarounds?
Use a separate mixin class and refer to it in both non-inside-b and inside-b cases.
To prevent outputting the mixin class, use the functional mixin-definition syntax:
.a() {}
Also, mixins can be defined inside a dummy id as a namespace, and that mixins shouldn’t be output too.

How to override mixins in LESS CSS 1.4+

I've been using what I thought was a very elegant pattern for defining the styles of reusable components/widgets, using LESS. It works beautifully in LESS 1.3-, but after upgrading recently, my whole library is broken. Does anyone know a way to accomplish something like this in 1.4+?
Here's a very simple example of a component:
#componentName {
.loadMixins(){
.text() {}
.header() {}
}
.apply(){
> h3 {
// markup-specific styles
padding: 3px;
margin-bottom: 0;
// custom styles
.header();
}
> div.body, > div.popup p {
color: red;
// custom styles
.text()
}
}
}
And here's how it would be used:
.coolWidget {
#componentName.loadMixins();
// override mixins here
.text(){
color: green;
}
#componentName.apply();
}
This keeps all the markup-dependent styles abstracted from the user. I could completely change my markup and the user's styles would still work. According to the less.js changelog, 1.4.0 Beta 1 has a line "variables in mixins no longer 'leak' into their calling scope"
Is there any way around this?
Strictly speaking nested variables and mixins are still expanded into calling scope unless this scope already has those names defined.
Your example above results in a error:
SyntaxError: .header is undefined...
and it's expected as no .header() is actually defined within the .coolWidget (or anywhere else).
This can be fixed by providing "default" definitions for .text and .header somewhere inside #componentName.
For example if you modify .loadMixins() to:
.loadMixins() {
.text();
.header();
// default properties in case a caller does not provide its own:
.text() {}
.header() {}
}
then the example compiles OK and all text/header properties are overridden as expected.
I can imagine how your library may become broken because of new scope rules but this particular example you gave above does not illustrate the problem.

LESS: mixin with non-class ruleset

In LESS, I am trying to define the button.c2 ruleset, to be applied to <button class="c2">...</button> elements. This ruleset is mainly based on the button.c1 ruleset. However, the following code produces a ParseError:
button.c2 {
button.c1;// Trying to import a ruleset
... // additional rules, such as font-size: 120%;
}
It seems to me that the ParseError is caused by the fact that the imported ruleset does not refer to a class or ID ("button.c1" does not start with a "." or a "#"). From the LESS documentation:
Any CSS class or id ruleset can be mixed-in that way.
Why is there such a limitation? Is there any way around it?
The limitation might just be ease of parsing, since . or # don't show up as the first character of a normal style rule the parser automatically knows that those should be mixed in.
You could get around it by defining .c1 as a mixin and using it for both buttons:
.c1() {
// c1 rules
}
button.c1 {
.c1;
}
button.c2 {
.c1;
// additional rules
}
However, coming up in LESS 1.4.0 are :extend selectors, which will allow you to do what you want. The syntax would be:
button.c2:extend(button.c1) {
// additional rules
}

SASS compilation error with nth-child selector

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})
{
// ...
}
}

Resources