I have searched the internet and it seems very hard to find this info.
When I do
div {
width: calc(1e-10 * 1e12px);
}
It sets the width to 100px. But when I do
div {
width: calc(1e-1000 * 1e1002px);
}
It fails. Clearly, 1e1002 is out of range.
What is the valid range of numbers in CSS? Does it depend on the unit? Is it browser specific?
It is up to each browser to pick limits for CSS real numbers. The spec supports a theoretically infinite range but relies on vendors to provide 'reasonable' support.
4.1. Range Restrictions and Range Definition Notation
Properties can restrict numeric values to some range. If the value is outside the allowed range, then unless otherwise specified, the declaration is invalid and must be ignored.
[...]
CSS theoretically supports infinite precision and infinite ranges for all value types; however in reality implementations have finite capacity. UAs should support reasonably useful ranges and precisions. Range extremes that are ideally unlimited are indicated using ∞ or −∞ as appropriate.
Soruce: https://www.w3.org/TR/css-values-3/#numeric-ranges
See also:
4.3. Real Numbers: the <number> type
Number values are denoted by <number>, and represent real numbers, possibly with a fractional component.
When written literally, a number is either an integer, or zero or more decimal digits followed by a dot (.) followed by one or more decimal digits and optionally an exponent composed of "e" or "E" and an integer. It corresponds to the <number-token> production in the CSS Syntax Module [CSS3SYN]. As with integers, the first character of a number may be immediately preceded by - or + to indicate the number’s sign.
Source: https://www.w3.org/TR/css-values-3/#numbers
Related
I was scanning some stylesheets when I noticed one which used a linear-gradient with rgba() color-stops in which the rgba numbers used multiple instances of 0 instead of just a single 0:
background-image:linear-gradient(to top left, rgba(000,000,000,0.1),rgba(100,100,100,1));
I hadn't seen multiple zeroes (instead of a single zero) occupying a single slot in the rgb/a color space before, but confirmed on CodePen this is valid. I then looked up the W3C definition of number here.
To make a long story short, after some more poking and digging, I didn't realize I could prepend an indeterminate number of zeroes to a length and get the same result as with no zeroes prepended, like this:
/* The two squares generated have equivalent width and height of 100px - for giggles, I also extended the same idea to the transition-duration time */
<style>
div.aaa {
width:00000000100px;
height:100px;
background-image:linear-gradient(to top left,rgba(000,000,000,0.1),rgba(100,100,100,1));
transition:1s cubic-bezier(1,1,1,1)
}
div.bbb {
width:100px;
height:000000000000000000000000000000000100px;
background-color:green;
transition:0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001s cubic-bezier(1,1,1,1)
}
div:hover { background-color:red }
</style>
<div class="aaa"></div>
<div class="bbb"></div>
It's difficult to directly verify these numbers are equivalent representations, because using a scripting language:
/* PHP */
$x = 100;
$y = 00000000000100; // problem is PHP treats this as an octal number
echo ($x == $y) ? 'true' : 'false'; // echoes the string ---> false
/* Javascript */
var x = 100;
var y = 00000000000100; // also treats this as an octal number
var res = (x == y) ? 'true' : 'false';
alert(res); // alerts ---> false
These examples suggest to me that CSS does not treat e.g. 0000100 as an octal number, but rather as a decimal (or at least as non-octal numbers) since the magnitude of the width, height, and transition-duration for the html elements generated above appear to be identical.
Extending this CSS approach to any property and any unit, e.g., time,
Is any unit-containing CSS property value prepended with any positive number of zeroes syntactically equivalent to the same value without any prepended zeroes?
I have to admit I found this question interesting.
https://www.w3.org/TR/CSS21/syndata.html
The css 2 syntax spec says:
num [0-9]+|[0-9]*\.[0-9]+
Note that 000000000000000037.3 meets this rule and definition, a series of numbers between 0 and 9, optionally followed by a . and a further series of numbers from 0 to 9.
The css 3 spec goes on:
https://www.w3.org/TR/css3-values/#numbers
4.2. Real Numbers: the type
Number values are denoted by <number>, and represent real numbers,
possibly with a fractional component.
When written literally, a number is either an integer, or zero or more
decimal digits followed by a dot (.) followed by one or more decimal
digits and optionally an exponent composed of "e" or "E" and an
integer. It corresponds to the production in the CSS
Syntax Module [CSS3SYN]. As with integers, the first character of a
number may be immediately preceded by - or + to indicate the number’s
sign.
https://www.w3.org/TR/css-syntax-3/#convert-a-string-to-a-number
This I believe roughly explains how a css parser is supposed to take the css value and convert it to a number:
4.3.13. Convert a string to a number
This section describes how to convert a string to a number . It
returns a number.
Note: This algorithm does not do any verification to ensure that the
string contains only a number. Ensure that the string contains only a
valid CSS number before calling this algorithm.
Divide the string into seven components, in order from left to right:
A sign: a single U+002B PLUS SIGN (+) or U+002D HYPHEN-MINUS (-), or the empty string. Let s be the number -1 if the sign is U+002D
HYPHEN-MINUS (-); otherwise, let s be the number 1.
An integer part: zero or more digits. If there is at least one digit, let i be the number formed by interpreting the digits as a
base-10 integer; otherwise, let i be the number 0.
A decimal point: a single U+002E FULL STOP (.), or the empty string.
A fractional part: zero or more digits. If there is at least one digit, let f be the number formed by interpreting the digits as a
base-10 integer and d be the number of digits; otherwise, let f and d
be the number 0.
An exponent indicator: a single U+0045 LATIN CAPITAL LETTER E (E) or U+0065 LATIN SMALL LETTER E (e), or the empty string.
(-), or the empty string. Let t be the number -1 if the
sign is U+002D HYPHEN-MINUS (-); otherwise, let t be the number 1.
An exponent: zero or more digits. If there is at least one digit, let e be the number formed by interpreting the digits as a base-10
integer; otherwise, let e be the number 0.
Return the number s·(i + f·10-d)·10te.
I think the key term there is a base-10 number.
Note that for other possible situations where the starting 0 is meaningful, you have to escape it for it to function as something other than a simple number, I believe, if I read this spec right:
https://www.w3.org/TR/css-syntax-3/#escaping
Any Unicode code point can be included in an identifier or quoted
string by escaping it. CSS escape sequences start with a backslash
(\), and continue with:
Any Unicode code point that is not a hex digits or a newline. The escape sequence is replaced by that code point.
Or one to six hex digits, followed by an optional whitespace. The escape sequence is replaced by the Unicode code point whose value is
given by the hexadecimal digits. This optional whitespace allow
hexadecimal escape sequences to be followed by "real" hex digits.
An identifier with the value "&B" could be written as \26 B or \000026B.
A "real" space after the escape sequence must be doubled.
However, even here it appears the starting 0's are optional, though it's not crystal clear.
The CSS specs were while obtuse fairly clear, which isn't always the case. So yes, numbers are made from strings of digits, and can have decimals as well, and are base 10, so that means the leading zeros are simply nothing.
I speculate as well that because the specs further state that no units are required when the number value is 0, that in fact, a leading zero may mean null, nothing, internally, though obviously you'd have to look at css parsing code itself to see how that is actually handled by browsers.
So that's kind of interesting. I think that probably because css is a very simple language, it doesn't do 'clever' things like php or javascript do with leading zeros, it simply does what you'd expect, treat them as zeros, nothing.
Thanks for asking though, sometimes it's nice to go back and read the raw specs just to see how the stuff works.
I'm trying to reduce the number of decimals of a JS operation and use the result to set a transform: scale(x) inline CSS to an element.
I can't find any reference to know how many decimals are allowed by such CSS function.
I want to know how many numbers are allowed (and used by the browser in the transformation) after the comma. (0.0000000N)
The specification defines the value for scale as a <number>, which is defined as:
A number is either an <integer> or zero or more decimal digits followed by a dot (.) followed by one or more decimal digits and optionally an exponent composed of "e" or "E" and an integer. It corresponds to the <number-token> production in the CSS Syntax Module [CSS3SYN]. As with integers, the first character of a number may be immediately preceded by - or + to indicate the number’s sign.
Note the lack of how many "more" decimal digits are allowed. So any limit will be imposed by the browser, which will obviously vary by browser.
As it seems it could be useful for others and amending the accepted question by extending it I'll upgrade my comment to an answer:
In the last term, the number of decimals you'll get depends mainly on the browser implementation so, depending on your targets you'll need to do some more research. Here you have an excellent post and a good starting point:
Browser Rounding and Fractional Pixels
My question is, simply, how many (non-zero) decimal places can I include in a value I use in a CSS stylesheet before the browser rounds the number when interpreting it?
NOTE: I am aware that any decimal pixels are rounded (differently by different browsers) because the screens cannot display sub-pixel units. What I am asking is before that rounding takes place, what number of decimal places will be retained to begin performing the final browser rendering calculations/roundings.
Be it truncation or rounding, in an ideal world, neither of these things should happen. The spec simply says that a numeric value may either consist of
one or more digits, or
any number of digits, followed by a period for the decimal point, followed by one or more digits.
The spec even accounts for the fact that the leading zero before the decimal point in a value that's less than 1 is not significant and can thus be omitted, e.g. opacity: .5. But there is quite simply no theoretical upper limit.
But, due to implementation limitations, browsers will often "round" values for the purposes of rendering. This is not something you can control other than by changing the precision of your values, and even so, this behavior can vary between browsers, for obvious reasons, and is therefore something you cannot rely on.
I couldn't find a precise definition of legal syntax for CSS3 colors, either as regular expression, BNF or whatever strict formal definition there might be. Some info can be derived from the verbal description in the CSS3 Color Module (for example that comma separated lists may contain whitespace), but I don't see whether e.g. leading zeros in something like
rgb(010,005,255)
rgba(050%,1%,01%,0)
are actually legal, or omitting leading zeros of decimal fractions, like
rgba(100,100,100,.5)
I'm not talking about what is tolerated by browsers, I'm asking whether this is officially legal CSS3 syntax as I'm interested in the use of these color definitions in non-browser applications as well.
As you found already, the CSS3 Color Module specification says
The format of an RGB value in the functional notation is 'rgb(' followed by a comma-separated list of three numerical values (either three integer values or three percentage values) followed by ')'
But you then need to look in basic data types section of CSS 2.1 to find out what an integer or a percentage value is and it says...
Some value types may have integer values (denoted by ) or real number values (denoted by ). Real numbers and integers are specified in decimal notation only. An consists of one or more digits "0" to "9". A can either be an , or it can be zero or more digits followed by a dot (.) followed by one or more digits. Both integers and real numbers may be preceded by a "-" or "+" to indicate the sign. -0 is equivalent to 0 and is not a negative number.
So integers and numbers can have leading zeros.
Then later on basic data types says
The format of a percentage value (denoted by in this specification) is a immediately followed by '%'.
So percentages can have leading zeros too.
I am often programming mathematical algorithms that assume a nondimensional parameter spans the continuous space from 0..1 inclusive. These algorithms could in theory benefit from maximum resolution over the parameter space and I've considered that it would be of use to expend the full 32 or 64 bits of precision over the parameter space, with none wasted for exponents or signs.
I imagine the methods would look similar to an unsigned integer divided by its maximum representable value. Does this exist already and if so where, if not, is there a compelling reason why?
Can't you simply do all calculations in integers from 0 to MAX_INT, keeping all the same formulas/algorithms/whatever and then use "unsigned integer divided by its maximum representable value" conversion as very final step before printing result to user (or otherwise outputting it - for example in intermediate logs)?
The representation doesn't make sense without algorithms. E.g. you could represent it as fixed point (i.e. 0..MAX_INT / MAX_INT) or floated point a mantissa and exponent (e.g. to have an ability to store a values like 1e-1000) or something custom (e.g. to have an ability to represent a number 1/π precisely). After it you have define algos to manipulate the numbers in such representations. So, in other words there is no silver bullet to cover all cases. Only you know your task and could choose the best solution.
Moreover, the continuous space is impossible to represent using computes, because the space has infinite number of elements, so it cannot be algorithmized.