less2css won't compile dynamically created class names - less

I'm using a sublime text 2 plugin less2css to compile my less files into css files. The issue I'm having is that the plugin won't compile my mixin which is used to dynamically create header font size. I've tested the mixin with the online less compiler which winless offers, and it seems to work fine.
Is this just a bug with the plugin, or am I doing something completely wrong in my mixin?
Mixin:
#fontSize: 24px;
.calcFontSize(#index) when (#index > 0) {
(~'h#{index}') {
font-size: #fontSize - #index * 3;
}
.calcFontSize(#index - 1);
}
.calcFontSize(0) {}
.calcFontSize(6);
The issue seems to occur on this line: (~'h#{index}') {. Changing this to an h1 (or any other header element) works fine.

Your code (and WINLESS too, I believe, which is why it works there) is using older syntax for LESS CSS. Your code compiles fine at http://less2css.org/ when set to LESS 1.3.0-1.3.3, but there was a syntax change for LESS 1.4+ (no interpolation needed). So if your Sublime has upgraded the LESS to 1.4+, then that would explain why your code does not work.
If this is in fact the issue, then you just need to change the syntax of your line like so:
h#{index} {
font-size: #fontSize - #index * 3;
}
Which you can see works on http://less2css.org/ for the 1.4+ versions of LESS.

Related

Clamp addition evaluated early by Less

I am trying to use clamp for a font-size in my Less file. I set it to be font-size: clamp(3.429rem, -1.870rem + 6.493vw, 9.143rem);.
When I build my styles however, I end up with CSS looking like font-size: clamp(3.429rem, 4.623rem, 9.143rem);. Less is evaluating the addition instead of passing over the whole clamp expression into CSS. I find this odd since there is no view width at build time.
How do I get Less to simply pass the clamp expression into the CSS file without evaluating?

Why is this Less expression a syntax error depending on the math operation?

I have the following snippet of Less:
#Foo: 50px;
.someClass {
width: calc(~'(100% - #{Foo}' - 5px);
}
This works fine. However, if I change this to:
#Foo: 50px;
.someClass {
width: calc(~'(100% - #{Foo}' + 5px);
}
We now have a ParseError. We're on a bit older version of Less, but I've tried it on the official Less preview site and it still breaks.
Is this a bug or am I doing something silly?
This is a very interesting case. The below code compiles fine and produces the expected output when --strict-math setting is turned on (--strict-math=on).
#Foo: 50px;
.someClass {
width: calc(e('(100% - #{Foo}') - 5px);
}
.someClass {
width: calc(e('(100% - #{Foo}') + 5px);
}
When strict math is turned off (which is, the default), both lines result in compiler error. Error message is given below and it is indicative of the fact that Less compiler is trying to perform math operations on values inside the calc function. This aggressive compilation is a known behavior of Less compiler.
OperationError: Operation on an invalid type
As confirmed by seven-phases-max in his comment, the behavior with the e() function (both when strict math is turned on and when it is turned off) is correct and error message also is as expected.
Ideally the same behavior as above should be seen for ~"" syntax also because it is a replacement of the e(). But unfortunately it doesn't seem to be. The code fails to compile irrespective of whether the strict math setting is enabled or not and the error message shown is the following:
ParseError: Could not parse call arguments or missing ')'
The error message indicates it is Parse Error and not an Operation Error. As seven-phases-max has indicated, it seems like the parser is not expecting an arithmetic operator to follow a value that is not a number and hence is throwing a parser error. The error message could've been more friendly :)
This problem happens only when the operator is + or * and not when it is - or /. When - or / is used, they can't always be considered as math operator (because - is used in prefixes and / is used in font property for line-height etc) and so compiler processes them as an identifier but + or * is invariably a math operator and so causes the issue. When - or / is used, it just results in string concatenation.
The below is the recommended way to fix this issue as it doesn't make the compiler to think that some kind of math operation has to be performed (and leaves it to the User Agent to handle as part of CSS):
#Foo: 50px;
.someClass {
width: calc(~'(100% - #{Foo} - 5px');
}
.someClass {
width: calc(~'(100% - #{Foo} + 5px');
}
Note: There is a missing close brace ()) within the calc functions but that is irrelevant to this case.

Less CSS - How to return value in viewport with (vw)

The Less percentage function returns value in (%) - wow!
element {
width: percentage(700 / 1400);
}
will compile to:
element {
width: 50%;
}
What would be the best way or syntax to get the value in (vw) so the style will compile to:
(bare in mind that the division function needs to be used. (700 / 1400))
element {
width: 50vw;
}
The best way to achieve the expected output would be to multiply the value by 100vw. This would be the most meaningful and easily understandable method.
a{
width: 700/1400 * 100vw;
}
The below method of using unit() function works too but I wouldn't really recommend it.
One of the primary reasons why I wouldn't recommend it is because I am not sure if that is supposed to work as it does. The unit() function is supposed to take a number as its first parameter and add the units to it but a percentage value is not exactly a number and this may not work in future versions depending on how the Less core team view it.
I read the docs and it seems like the first parameter can be a number with or without a dimension but I still wouldn't recommend it because the earlier method is far more easier to understand than the usage of functions.
b{
width: unit(percentage(700/1400), vw);
}

Bootstrap 3 XS - Why threshold is high and how to change?

I've used bootstrap for awhile now, and for the life of me I cannot remember the xs coming into play at 767px. I'm using Boostrap v3, LESS, and cannot find where to change the threshold for the hidden-xs class. I did a project-wide search, and only the variables are popping up in the Find Results.
file: responsive-utilities.less
line: 134
.hidden-xs {
#media (max-width: #screen-xs-max) {
.responsive-invisibility();
}
}
When I inspect element in chrome the variable, #screen-xs-max is being set at 767px
#media (max-width: 767px)
.hidden-xs {
display: none !important;
}
I have disable cache on in chrome as well. I attempted to change the #screen-xs-max variable by removing the variable all together and putting a hard number, but that didn't change it either.
I've also looked at this website, Customize and download Bootstrap, and that confused me even more b/c I use col-XXX-## and hidden-XX, not the #screen-xs, which is in the Media queries breakpoints section. And not only that, but the xs is set to 480px.
Appreciate it.
Addition:
I am compiling LESS using less.js as well.
Maybe my main question would be - how do I increase the sm threshold, and reduce the xs threshold - as in have the xs at a lower pixel setting, like 520px?
If you are compiling the LESS yourself, and want to modify the breakpoint between xs and sm sizes, try changing the #screen-sm variable in the variables.less file.
e.g. for v3.3.0:
https://github.com/twbs/bootstrap/blob/v3.3.0/less/variables.less#L285
Line 285

Less dynamic class-names generated at runtime, or classes generated from array loop

Currently, one of my developers have developed this less file:
.countryFlag( #countryName :"DK"){
content: url("/images/flags/#{countryName}.gif") no-repeat center;
}
a.flag-DK {
.countryFlag ();
}
a.flag-DE {
.countryFlag (DE);
}
a.flag-EE {
.countryFlag (EE);
}
...
with some 20 countries. I was wondering if this can be done smarter with less, either using loops or dynamic names created at runtime. Consider the following pseudo-code that describes what I want:
a.flag-#{country} {
content: url("/images/flags/#{country}.gif") no-repeat center;
}
that simply matches any definitions. I am aware that this could create lots of conflicts, but perhaps it could be further narrowed down via regex? Makes sense, but haven't been able to find this.
An alternative could be to create the "static" css classes using a loop of some sort. Consider this pseudo-alternative:
#countries: 'dk', 'de', 'uk', 'us', ...;
for(country : countries) {
a.flag-#{country} {
content: url("/images/flags/#{country}.gif") no-repeat center;
}
}
and thus create the classes for a pre-determined list of countries.
Is either of these alternatives available in some sort of way? Or can you perhaps advice on a third option that I might have overlooked? I feel kinda stupid when I see 20-something almost identical classes defined, having only a small string in difference, and think that a CSS pre-processor MUST be able to do this smarter.
Thanks!
Less.js "for" snippet has a few lines of documentation, too. I found this page very useful a few days ago when I was facing a problem like yours.
You can simply declare a list of values to be used as strings in your foreach loop. (eg #list: banana, apple, pear, potato, carrot, peach;)
Make you sure you're using a recent version of Less!