using random number in LESS CSS [duplicate] - css

Tried searching for this but it's difficult given the syntax. Is there any way to generate a random number in LESS? I checked the documentation and don't see anything, but wondered if anyone knew of a trick or undocumented solution.

By a LESS Mixin for Variation
By making a LESS mixin to generate the random number, you can call it each place as needed with easier control of the output. This code was built in part from the help of this SO answer, which allows you to control the output range of the random number, and whether it outputs decimals or integers.
LESS Define Mixin
/* Mixin to generate random number;
int should be 0 or 1, 1 being to make it an integer
*/
.makeRandom(#min: 0, #max: #min+1, #int: 0) {
.checkInt() {
#getNum: `Math.random() * (#{max} - #{min} + #{int})`;
#base: unit(`#{int} == 1 ? Math.floor(#{getNum}) : #{getNum}`);
}
.checkInt();
#randNum: #base + #min;
}
The above will output a variable labeled #randNum for each time the mixin is called. So then this can be done:
LESS Use Mixin
.rand1 {
.makeRandom(); /* straight random decimal between 0 - 1 */
random-number: #randNum;
}
.rand2 {
.makeRandom(#max: 2); /* random decimal 0 - 2 */
random-number: #randNum;
}
.rand3 {
.makeRandom(10, 20, 1); /* random integer 10 - 20 */
random-number: #randNum;
}
Which yields an output something along these lines (of course, the numbers will change with each compilation from LESS):
CSS Output
.rand1 {
/* straight random decimal between 0 - 1 */
random-number: 0.1597523226169918;
}
.rand2 {
/* random decimal 0 - 2 */
random-number: 0.08123856632111548;
}
.rand3 {
/* random intger 10 - 20 */
random-number: 15;
}
Of course, I realize you would probably in most cases not be directly outputting these random numbers, but rather using them in some other calculation. But this illustrates how the mixin can be used.
I also realize this does not resolve any randomness with respect to the same class usage. In other words, any element with .rand3 class above will have 15 as its number. I believe this is the issue you ran into based on your comment:
Unfortunately, I didn't think about this making all matching elements
the SAME random number, which of course it does. So I ended up using
JQuery each() with standard javascript to accomplish what I wanted.
That is just the fact of life for LESS being a preprocessor of CSS. To get randomness across similar elements via LESS you would need to generate the random numbers from this mixin by a series of classes via some sort of a loop structure and apply each class of the series to the various elements to get the randomness.

According to the documentation:
JavaScript evaluation
JavaScript expressions can be evaluated as values inside .less files. We recommend using caution with this feature as the LESS will not be compilable by ports and it makes the LESS harder to maintain. If possible, try to think of a function that can be added to achieve the same purpose and ask for it on github. We have plans to allow expanding the default functions available. However, if you still want to use JavaScript in .less, this is done by wrapping the expression with back-ticks:
So this should work:
#var: `Math.random()`;

Related

How Calc() calculate in css?

Can somebody describe Use of Calc() in css?
And what is ~ sign meaning with Calc()?
How below code calculate?
calc(~'(100% - 4 * 23.233%) / 3')
That is not a valid value in plain CSS.
It looks like that is from LESS source code, which is compiled down to the following:
calc((100% - 4 * 23.233%) / 3);
As stated by the relevant LESS documentation, ~'' is used for escaping:
Escaping allows you to use any arbitrary string as property or variable value. Anything inside ~"anything" or ~'anything' is used as is with no changes except interpolation.
This is done to prevent LESS from automatically evaluating the expression as math. Without the escaping, the value would be evaluated and compiled to:
calc(2.3559999999999994%);
For further reference, see this related question: "Less Aggressive Compilation with CSS3 calc".

css: transform + 2 css variables

I have the following css on a series of elements.
#foo-parent {
--rotation: 45deg;
}
#media (max-width: 1680px) {
.foo {
--multiplier: 8.33;
}
}
/* a number of other nearly identical media queries defining different values for --multiplier */
.foo {
transform: scale(calc(var(--multiplier) / 25)) rotate(calc(0deg - var(--rotation)))!important;
}
The rotation transform is working fine, but the scaling isn't kicking in. If I change it to
transform: scale(.222) rotate(calc(0deg - var(--rotation)))!important;
...it works.
Edit: from further testing, if I take out either half, each one works separately:
transform: scale(calc(var(--multiplier) / 25))!important;
transform: rotate(calc(0deg - var(--rotation)))!important;
It's only failing when both css variable bits are present:
transform: scale(calc(var(--multiplier) / 25)) rotate(calc(0deg - var(--rotation)))!important;
So, is there a limit that only css variable can be used, or is there something else I'm missing?
It's a bit difficult to help you with missing parts of the code here, because with this first view it should work.
But on your side, several things you can check to debug this case:
Are you sure the two variables are always defined. If they are not, all the transform value will be affected.
Is there a cycle in the attribution of the value, you can't define a variable using itself in the value, e.i. --size: calc(var(--size) + 50px);
Check if at some moment the value become invalid. It shouldn't happen easily because almost all values are valid, but the way they are used can trigger a new kind of error invalid at computed time meaning that the value of the computed variable doesn't make sense in that specific context. (https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties#Validity_and_values)
I hope this little list can help :)
PS. you can use fallback in some cases: https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties#Custom_property_fallback_values

Sass Variables Values Using 'px' or not

The main question is:
Should I define unit in sass variables?
I am a Sass beginner, I've already searched about best practices (and I am trying to apply them) but I could found nothing about this question.
Let me explain with examples. I am working on a website which some sections will be overridden by the customer. So, I have some sass variables that I expect my custumer override them. Some of these variables are width, for example. I've started defining all with unit included, like:
$my-app-main-container-width: 150px !default;
However, in some cases, I need to use variables to do math operations:
$density: 5;
#for $i from 1 through 10 {
.app-item-#{$i} {
padding: #{$density}px #{$density}px #{$density}px #{$i * $density + $density}px;
}
}
So I realized that in some cases I've declared the variable with px and in other cases, just the number. In my research, all samples are including the unit in variable value, but sounds weird and inconsistent when you need to calc. But, like I've said, I am a sass beginner so I will enjoy other opinions.
For now, I am omitting the unit in all my variables and defining the unit when I use the variable.

Generate random number in LESS CSS?

Tried searching for this but it's difficult given the syntax. Is there any way to generate a random number in LESS? I checked the documentation and don't see anything, but wondered if anyone knew of a trick or undocumented solution.
By a LESS Mixin for Variation
By making a LESS mixin to generate the random number, you can call it each place as needed with easier control of the output. This code was built in part from the help of this SO answer, which allows you to control the output range of the random number, and whether it outputs decimals or integers.
LESS Define Mixin
/* Mixin to generate random number;
int should be 0 or 1, 1 being to make it an integer
*/
.makeRandom(#min: 0, #max: #min+1, #int: 0) {
.checkInt() {
#getNum: `Math.random() * (#{max} - #{min} + #{int})`;
#base: unit(`#{int} == 1 ? Math.floor(#{getNum}) : #{getNum}`);
}
.checkInt();
#randNum: #base + #min;
}
The above will output a variable labeled #randNum for each time the mixin is called. So then this can be done:
LESS Use Mixin
.rand1 {
.makeRandom(); /* straight random decimal between 0 - 1 */
random-number: #randNum;
}
.rand2 {
.makeRandom(#max: 2); /* random decimal 0 - 2 */
random-number: #randNum;
}
.rand3 {
.makeRandom(10, 20, 1); /* random integer 10 - 20 */
random-number: #randNum;
}
Which yields an output something along these lines (of course, the numbers will change with each compilation from LESS):
CSS Output
.rand1 {
/* straight random decimal between 0 - 1 */
random-number: 0.1597523226169918;
}
.rand2 {
/* random decimal 0 - 2 */
random-number: 0.08123856632111548;
}
.rand3 {
/* random intger 10 - 20 */
random-number: 15;
}
Of course, I realize you would probably in most cases not be directly outputting these random numbers, but rather using them in some other calculation. But this illustrates how the mixin can be used.
I also realize this does not resolve any randomness with respect to the same class usage. In other words, any element with .rand3 class above will have 15 as its number. I believe this is the issue you ran into based on your comment:
Unfortunately, I didn't think about this making all matching elements
the SAME random number, which of course it does. So I ended up using
JQuery each() with standard javascript to accomplish what I wanted.
That is just the fact of life for LESS being a preprocessor of CSS. To get randomness across similar elements via LESS you would need to generate the random numbers from this mixin by a series of classes via some sort of a loop structure and apply each class of the series to the various elements to get the randomness.
According to the documentation:
JavaScript evaluation
JavaScript expressions can be evaluated as values inside .less files. We recommend using caution with this feature as the LESS will not be compilable by ports and it makes the LESS harder to maintain. If possible, try to think of a function that can be added to achieve the same purpose and ask for it on github. We have plans to allow expanding the default functions available. However, if you still want to use JavaScript in .less, this is done by wrapping the expression with back-ticks:
So this should work:
#var: `Math.random()`;

Are alternate nested styles possible in CSS?

I'm doing a little experiment, trying to alternate background colours for nested divs.
This is what I intend to achieve (without the inline styles):
<div style="background: #fff;">
<div style="background: #000;">
<div style="background: #fff;">
<div style="background: #000;">
and so on...
</div>
</div>
</div>
</div>
I feel like I must be missing something obvious! I tried div:nth-of-type(2n) but this appears to only apply on one level.
This is for an experiment where the divs are generated, so the solution needs to be endless (not something along the lines of div div div div = white). I know it's quite easy with JavaScript, just looking for a pure CSS solution.
As Mr Lister pointed out, nth-of-type works on one level (that of the parent of the selected div).
As far as i know and after looking through the W3C CSS3 Selectors there doesn't appear to be any css selectors for traversing through nesting (except the > selector, which only looks at the direct child of parent).
I would love te be proven wrong though as that could be very usefull.
So the only (css) solution would be the one you already stated: div > div > div {background: white; }
Can't you just generate this along with the generation of the div's?
As stated by others, this is not possible in pure CSS. However using js it is quite possible and fairly easy too.
For ease I implemented this in jQuery but you could do with pure JS.
http://jsfiddle.net/sg3s/Suf3p/
I basically made a small jQuery plugin that colors the selector you apply it on with the primary color, and uses the subselect to get a matching child to color with the secondary color and so on until no children matching the subselect are left.
jQuery(function($) {
$.fn.alternateNestedBgColor = function(subselect, colors) {
// While not a great optimization, length of the colors array always stays the same
var l = colors.length;
// Itterate over all element in possible array
// jQuery best practice to handle initializing multiple elements at once
return this.each(function() {
var $sub = $(this), i = 0;
// Executes code, at least once
do {
// Set bg color for current $sub element
$sub.css('backgroundColor', colors[i++ % l]);
// Set $sub to direct children matching given selector
$sub = $sub.children(subselect);
// Will repeat the do section if the condition returns true
} while ($sub.length > 0);
});
};
// target first div in the body
// first argument = child selector
// second argument = array list of colors
$('body>div').alternateNestedBgColor('div', ['red', 'green', 'blue', 'purple', 'grey']);
});
Update As requested an update detailing how apply and modulo were used.
It's been almost 2 year since I recently posted this. And while working, the solution I made back then was a bit verbose and confusing, as for instance, I never needed apply. I got a little bit more comfortable with scopes, so I revised the function to be much simpler.
The only situation where apply is useful is when you need to pass a value to the this variable inside the function scope. Unless working with classes there aren't a whole lot of situations you should have a need for apply or call. If you want to read up on it I would like to refer you to this answer which explains it in context of classes. The MDN link is a good resource as well (for this and other javascript constructs/concepts).
As for modulo, this is basic math and this question explains the operation quite well. In short it will give you the full integer remainder after dividing a number by another. So 33 % 8 = 1 which you could write as 33-parseInt(33/8)*8 in js though that would be grossly inefficient. The result of the operation will always be 0 (when the number perfectly divides) to the 2nd argument minus 1 (so 7 in my example).
0 % 3 = 0 // technically doesn't exist (as you can't divide 0 with anything) but 0 for practicality in all programming languages afaik(?)
1 % 3 = 1
2 % 3 = 2
3 % 3 = 0
4 % 3 = 1
5 % 3 = 2
6 % 3 = 0 etc...
It's one of those operations which is inherently simple for your CPU, in fact without it being able to do this we wouldn't have computers.
In the javascript revision I've written the selection of the color from the given array as colors[i++ % l].
In writing this would be give me the remainder of i / l and use that integer as an index for the colors array which returns a color for use.
The ++ will add 1 only after returning the value of i for use in the modulo, this behaviour would be reversed if I had written ++i, but that wouldn't work for our purpose here.
For reference here is the MDN article on do...while.
I hope that cleared some things up! :)

Resources