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
Related
Can someone tell me why this CSS calc function isn't working? When I inspect element on Chrome, it says 'Invalid property value'.
width: calc((100vw - 14px * 2) / (270px + 11px * 2));
For future googlers:
The unhelpful "invalid property value" message in DevTools might just mean that you need white space around your + - / * operators.
Incorrect (invalid property value):
width:calc(100vh-60px) <== no spaces around minus sign
Correct:
width:calc(100vh - 60px) <== white space around the minus sign
The OP's question above does not have this problem, but while googling an answer to this error message this is the first resource I found, so it should have an answer dedicated to this common error.
References:
CSS3 calc() not working in latest chrome
https://www.smashingmagazine.com/2015/12/getting-started-css-calc-techniques/
You can't divide by units like px, only numbers.
When using calc() you can't divide by pixels, you can only divide by unitless numbers. Also, the number you are dividing has to have a certain unit like px, em, vh, vw.
For example, if you need to set a width of an element you should use:
width: (100px / 2); //this equals to 50px
An important note is to make sure you put spaces between the operator signs. This calc() article provides further detailed explanation on the function.
As #cssyphys noted above, you have to have spaces around your minus sign. However, if you are using ASP.NET MVC's bundler/minifier you find that it removes the spaces so you get the noted error.
If you are using plain CSS3, the following expression can be used in CSS and won't get minified:
width: calc((100%) - 50px);
HOWEVER, if you are using LESS (and perhaps other CSS preprocessors?), the preprocessor will "optimize" your expression and rip out your inner parens, again resulting in something ASP.NET will botch up. To get around that, use LESS's "don't process" tilde expression:
width: calc(~"(100%) - 50px");
I had to go back and change a bunch of calc() statements but so worth it to get back my ASP.NET minification.
As Stephen Thomas has answered, you can't divide by units. To get around this, just divide the numbers as numbers and then assign the unit of measurement by multiplying the result by 1 unit of the units you're interested in. In your nested scenario you'd need to figure out what unit of measurement you were after in the end so that you could divide the numbers and then assign the result to a px or vw unit of measurement.
I just came across this error because one SCSS variable was set to zero:
WRONG:
$card-border-width: 0;
This eventually provoked Chrome's message Invalid property value in answer to the CSS result border-radius: 0 0 calc(0.25rem - 0) calc(0.25rem - 0).
RIGHT:
$card-border-width: 0rem;
(giving border-radius: 0 0 calc(0.25rem - 0rem) calc(0.25rem - 0rem))
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()`;
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()`;
I'm trying to use LESS css to do the following:
width: ((480/1366)*100)+'%';
The problem though is that the output becomes:
width: 35.13909224011713 '%';
How do I make it workable? ie.:
width: 35.13909224011713%;
It is possible to use string interpolation:
#myvar: ((480/1366)*100);
width: ~"#{myvar}%";
That will output
width: 35.13909224011713%;
Additionally, if you want it to be rounded, you can use round().
Even though this question is quite old, I want to add a few more examples about adding. Less will set your units to whatever is being operated on.
10px + 20px
will output 30px
(20/200) * 100%
will output 10%
So with units you dont need to concatenate the unit measurement.
I have found that adding 0 helps when you dont know what the unit value might be.
.mixin(#x, #y){
#result: (#x / #y) * 100;
}
.my_class {
.mixin(20, 100);
width: #result + 0%; // you can use any unit here
}
The above class will have a width of 20%. If we added with px, it would be 20px.
For some reason the least verbose and most obvious method is sort of missing here (it's in Richard Testani answer actually but there it's hindered with further code leading to a wrong direction). So...
The answer to original:
width: ((480/1366)*100)+'%';
is as simple as:
width: (480/1366*100%);
Speaking of percentage:
it does the trick too but personally I'd never use it for its verbosity and non-readability. At quick scanning percentage(480/1366) reads just like peekabooze(480/1366) so you have to stop and stare at it to get a clue. Contrary the explicit appearance of % in 480/1366*100% (or 480 / 1366 * 100%) makes it more easily noticeable.
I've seen this notation used a lot, and I was wondering, is there is any notable difference between these two notations?
element#id
{
property: 0;
}
and
element#id
{
property: 0px;
}
I use property: 0px; all the time, as I find it cleaner looking, but I'm not really sure if the browser interprets 0px differently than 0.
Does anyone know which one is better or correct?
Unit identifiers are optional, but there is no noted performance increase (although you are saving two characters).
CSS2 - From W3C CSS 2.1 Specification for Syntax and basic data types:
The format of a length value (denoted by <length> in this specification) is a <number> (with or without a decimal point) immediately followed by a unit identifier (e.g., px, em, etc.). After a zero length, the unit identifier is optional.
(Emphasis mine)
CSS3 - From W3C CSS Values and Units Module Level 3 (Currently in Candidate Recommendation at the time of this writing)
For zero lengths the unit identifier is optional (i.e. can be syntactically represented as the 0).
While the unit is optional when the value is 0, I tend to leave it in, as I can then tweak the values with Chrome's Developer Tools by clicking on the value and pressing the up/down arrow keys. Without a unit, that isn't really possible.
Also, CSS minifiers strip the units off of 0 values anyways, so it won't really matter in the end.
They are the same. The browser interprets both as 0, so go with whatever is more readable for you.
Zero of anything is zero. 0px = 0% = 0em = 0pt = 0
Most people leave the unit off because it is simply unnecessary clutter.
As far as I'm aware there is no difference between them, since 0px = 0em = 0ex = 0% = 0. It's purely up to you, as the developer, to decide what you like best (unless you have corporate coding standards that you need to follow, of course).
From most of the code samples I've seen, most people use the unitless version. To me, it just looks cleaner. If you're pushing a significant amount of data (say, if you're Google), those two bytes can add up to a lot of bandwidth, especially since you're quite likely to repeat them multiple times in your stylesheet.
Zero pixels is equal to zero inches and zero meters and so forth. 0 is all you need.
I personally find 0 cleaner than 0px. That's two extra characters that can add up. Why add extra bytes when you don't need to. I have see padding: 0px 0px 0px 0px which can easily be expressed as padding: 0 way too often.
You can use either - my best advice is not to worry too much but be consistent in doing it either one way or the other. I personally prefer to specify '0px' for the following reasons:
Using 0px makes things more consistent with all of the other 'px' sizes you've specified
It's also more verbose and makes it very clear that you're setting a zero length rather than a 'switch this off' flag
It's slightly easier to tweak a '0px' value to make it another value if required
zero-units Zero values don't need units. An easy way to save bytes in CSS is not include units when a value is 0. For instance, 0px and 0 are the exact same ...
http://csslint.net/index.html
If somebody gives you 0 EUR. It is that same like 0 Dollar or 0 Zloty etc. What you got is nothing = 0. That is why in the case of 0 you dont need to set a unit.
As the others say, it doesn't really matter if its 0, though I choose to add the measurements to all of my values so anyone else looking at my CSS files can gauge what measurements they're likely to deal with elsewhere.
I know that there should be no difference between 0px and 0 but I've found that sometimes there is.
I was trying to center an object like this:
position: absolute;
left: max(0px, calc((100vw - 400px)/2));
max-width: 400px;
It works but if you substitute 0px with 0 it doesn't.