Why won't this LESS css sizing mixin compile? - html

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...

Related

Less syntax problems [duplicate]

This question already has answers here:
Less mixin with optional parameters
(2 answers)
Closed 5 years ago.
I can't understand some syntax usage. I have a simple mixin with default params:
#red: #ff4136;
#blue: #00aef9;
#green: #01ff70;
#yellow: #ffdc00;
.paint(#color: #yellow, #height:100px, #width:200px) {
background-color: #color;
height: #height;
width: #width;
}
.monster-happy {
.paint(#color, 100px, 10px);
}
I want to change only first and last default param and I dont want to change the middle param, something like:
.monster-happy {
.paint(#red, #height, 10px);
}
But it doesn't work. How should I make it correct and what better way to do this?
I believe that you can ignore the value you want to use the default for, and then explicitly define any parameters further down the the arguments.
.monster-happy {
.paint(#red, #width: 10px);
}
This is because your mixin will check the values that are passed in, in order that you pass them. It always expects color first, which is why we can just use #red, but due to leaving out the height, we have to explicitly state that the next value is for the #width property.

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.

Can a sass selector contain a '%' character?

I have a variable that contains a string value in the form of some percentage eg. '10%' I want to use that value to build a class name to add to my html element if the percentage is anything above '0%'. I thought this would be easy using a sass loop but I can't seem to get the class name constructed correctly.
I thought it would look something like this.
#for $i from 1 through 100{
.highlight-#{$i}% {
// styling
}
}
.highlight-0% {
// styling
}
I have tried several variations:
.highlight-#{$i + '%'} { // styling }
.highlight-#{$i}${'%'} { // styling }
I don't know if this is even possible since '%' may be reserved.
I am adding the html just in case someone can suggest a way to remove the % in there. This is what I would like to be able to do:
<tr><td class="pad-10 highlight-${publisher.numViewsPercentage}" align="center">${publisher.numViewsPercentage}</td></tr>
Not only is % a reserved character in Sass, the bigger issue is it's not an allowed character in CSS selector names. So even if you could make Sass compile the resulting class names won't be valid and won't work.
For the most part selector names need to use only letters, numbers, underscore and hyphens.
.nopercent {
color: red;
}
.percent% {
color: red;
}
<div class="nopercent">
An element withOUT a percent sign in the class.
</div>
<div class="percent%">
An element with a percent sign in the class.
</div>
% is a placeholder character in SASS since version 3.2.
You should just use it for "invisible" extendeds.

LESS compilation error

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.

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;