LESS compilation error - html

I'm trying the following statement in LESS, but its giving me an error:
(~".table-column[width='#{size}']") {
// do something
}
----------
ERROR :
----------
*ParseError: Missing closing ')'*
I'm using lessc 2.5.3, with nodejs on windows.
LESS is new to me and any pointers would be helpful.
Thanks

No need for the parens, nor the string quotes, nor the ~ (unless you are trying to use a ~ sibling selector). Observe the following...
#size: 40px;
.table-column[width='#{size}'] {
background-color: tomato;
}
// -- conversion
.table-column[width='40px'] {
background-color: tomato;
}
Codepen link - working demo
Also check out the LESS variables docs - specifically, variable interpolation, for more information.

Related

SCSS: Send Attribute and Value to Function

Note:
I'm new to web development and object oriented programming. I am brand new to SCSS and haven't yet grasped a solid understanding of the syntax. I have a basic understanding of how to use functions in SCSS.
Let me start off by defining the result I want to achieve.
_body.scss
body {
background-color: red;
}
Now I know if I wanted to obtain this result in Javascript I could:
Option 1: write a string of HTML code and replace the existing html tag.
Not going to code this, as this is a messy way of writing Javascript, but essentially using document.write() method.
Option 2: use the "setAttribute()" method
// assuming <head> and <body> are the only tags within <html>
var bodyTag = document.firstElementChild.lastElementChild;
bodyTag.setAttribute( "bgcolor", "red" );
I know there are additional ways to do this in Javascript, but for this example, I will focus on these two.
So I want to create a SCSS function that can return both the attribute and the value.
_body.scss ( Pseudocode string example )
#function makeAttribute( $attribute, $value )
{
#return $attribute + ":" + $value + ";";
}
body {
makeAttribute( background-color, red );
}
I have yet to find a built in function that addresses this ( similar to the "setAttribute()" method in Javascript ), or the string example above.
I know that functions can take: number, string, bool, color, list, map or null; but what I don't know is if an attribute fits into any of these value types ( for instance: string ).
I feel as if the article: Bringing Configuration Objects To Sass may be explaining what I am trying to do, but I'm having difficulty understanding this article ( so it may not be an explanation to a solution ).
My end goal is to create a function that would write the following css. I did not mention the browser support previously as it adds another layer of complexity that may or may not be easily explained.
body {
background-color: red;
-o-background-color: red;
-ms-background-color: red;
-moz-background-color: red;
-webkit-background-color: red;
}
i don't know if this have to be a function, i found it more logic use a mixin instead:
// Option 1
#mixin makeRule($value: red, $property: background-color) {
#{$property}: $value;
}
// Option 2:
#mixin makeRuleWithPrefixes($value: red, $property: background-color) {
#{-ms- + $property}: $value;
#{-o- + $property}: $value;
#{-moz- + $property}: $value;
#{-webkit- + $property}: $value;
#{$property}: $value;
}
/////////
body {
#include makeRule;
}
article {
#include makeRule(black);
}
p {
#include makeRule(2px solid blue, border)
}
span {
#include makeRuleWithPrefixes;
}
i changed the name, because is no right say - makeAttribute, when you are creating a cssRule ( selector + property name + property value ), well this is up to you ;)
ok the first,you need interpolation to use a variable as a property name.
The value is the first argument, so now you can use the default property, and just pass different values ( like the article :) )
or you can now set all the properties you want it, just pass the property as the second value ( like p )
body {
background-color: red;
}
article {
background-color: black;
}
p {
border: 2px solid blue;
}
span {
-ms-background-color: red;
-o-background-color: red;
-moz-background-color: red;
-webkit-background-color: red;
background-color: red;
}
I made the option two, because you ask it but i warn you, this is not a good approach. You could use a build tool ( webpack, gulp, grunt.. whatever ) than use a autoprefixer package that do this prefix automatically, this way is a pain because you have to be updating the #mixin eventually.

Jade: Best practice with classes and ids

I've searched for a while now, but I couldn't find an answer.
To create a div container with a class or id in Jade you can write:
.foo
#bar
or
div.foo
div#bar
Another thing is multiple classes:
div.foo.bar
or
div(class="foo bar")
What's best practice or is it just personal preference?
It is just a shorthand notation. Nothing wrong with it, just more readable for users who are unfamiliar with the shorter syntax to implicitly show that you are creating a div.
In some cases, using a shorthand syntax however causes the interpreter to perform better, because it works a bit different under the hood.
I'm not familiar with how Jade works, but maybe using just the dot notation saves some work behind the scenes, whilst using the more explicit instructions takes more time to parse.
Same as something similar in css:
border-style: solid;
border-width: 1px;
border-color: red;
/* shorthand */
border: 1px solid red;
Or javascript:
var foo;
if (true){
foo = "bar";
} else {
foo = "not bar";
}
// shorthand
var foo = true ? "bar" : "not bar";
var x = x + 1;
// shorthand, and might uses the processor or engine differently
var x += 1;

why does LESS prints out arithmetic operations as text?

When i'm writing the following operations
#a: 2px
#variable: #a + 5;
.margin-style{
margin-left: #variable;
}
This above code compiles to
.margin-style{
margin-left: 2px + 5;
}
instead of
margin-left:7px;
What seems to be going wrong?
Using Bootstrap and Grunt
setting strictMath:false in the Gruntfile.js under the less compiler settings solved the issue

Incremental file name using less css

I am trying to create 50 background images for a set of windows using less.
These image paths are exactly the same format, but the number just increments by 1 for each window.
Currently I have the following code:
window-1{
background-image: url('/content/images/background-1-window.png')
}
window-2{
background-image: url('/content/images/background-2-window.png')
}
..
window-50{
background-image: url('/content/images/background-50-window.png')
}
What I want to achieve is to effectively have variables replacing the numbers using less, is it possible to do this using variables and or mixins?
Something like:
window-#window-number{
Background-image: url('/content/images/background-#window-number-window.png')
}
Is it at all possible to do something like this?
Yes, it is possible, see this answer https://stackoverflow.com/a/15982103/1596547 and https://github.com/twbs/bootstrap/issues/10990 for some example code:
In your case:
.setbackgroundimage(#index) when (#index > 0)
{
window-#{index}
{
background-image: url('/content/images/background-#{index}-window.png');
}
.setbackgroundimage(#index - 1);
}
.setbackgroundimage(50);

Why won't this LESS css sizing mixin compile?

I'm trying to create a mixin that'll take two parameters and output sizing in px and rem. This is the code:
.sizing (#cssProperty; #sizeValue) {
#cssProperty: ((#sizeValue * #basefont) * 1px);
#cssProperty: (#sizeValue * 1rem);
}
Usage would be like:
h2 {
.sizing(font-size; 1)
}
Which should output (depending on what basefont size is defined):
h2 {
font-size: 12px;
font-size: 1rem;
}
But simpLESS won't compile it, and says there's an error in these two lines:
.sizing (#cssProperty; #sizeValue) {
.sizing(font-size; 1);
What am I doing wrong? Is it because of the variable property names?
Just noticed that you are trying to use variables as property names instead values which is not supported by less.
There is a hack highlighted in this answer as workaround:
How to pass a property name as an argument to a mixin in less
.mixin(#prop, #value) {
Ignore: ~"a;#{prop}:#{value}";
}
LESS does not allow to use a variable as a CSS property name.
In your code above #cssProperty: ((#sizeValue * #basefont) * 1px); is actually a definition of the new #cssProperty variable and not a CSS property: value statement, hence it produces no CSS output.
There's a workaround for what you want to achieve though, see 14868042, 18558368 etc...