Just a quick question to clear up some confusion that I have regarding units on CSS perspective.
On the CSS Transforms spec it references it with px e.g. perspective: 1000px; but I have used and in many other places others have used it without px e.g. perspective: 1000; such as on W3Schools.
Is either way more preferred? Does it matter?
Just want to clear this up, thanks.
Just because it's accepted by (some) browsers doesn't mean it's correct.
Specifying a unit of measurement is required by the CSS spec, unless the value is zero.
The spec says:
Lengths refer to distance measurements and are denoted by <length> in the property definitions. A length is a dimension. A zero length may be represented instead as the <number> ‘0’. (In other words, for zero lengths the unit identifier is optional.)
A dimension is a number immediately followed by a unit identifier.
(emphasis mine)
See the Distance Units and the Other Units for examples.
Also see the MDN discussion of length
px (or other absolute unit) is the correct way. Here is documentation (better than w3 schools) :)
https://developer.mozilla.org/en-US/docs/CSS/perspective
Related
Why is the em unit defined in terms of the font actually used to render the text, and the ex unit using the first available font?
To me, that looks like the font used to compute the height of ex can be different from the font actually used to render the text.
Quoting the specs:
The first available font, used for example in the definition of font-relative lengths such as ‘ex’ and ‘ch’ or in the definition of the ‘line-height’ property, is defined to be the first available font that would match the U+0020 (space) character given font families in the ‘font-family’ list (or a user agent's default font if none are available).
Why does the algorithm look for the space to compute the height of the letter 'x'? An explanation in layman terms would be very appreciated.
Why is the em unit defined in terms of the font actually used to render the text, and the ex unit using the first available font?
This shouldn’t be the case: both units are intended to be relative to the current font. The definition you provided mentions “font-relative lengths such as ‘ex’,” which also includes the ‘em’ unit.
That said, it seems like the authors agreed that the definition of “first available font” should be clarified: https://github.com/w3c/csswg-drafts/issues/4796
The section you quoted seem to imply that if the first font in the font-family list exists, but the U+0020 (space) character isn’t in the font, then the next font should be used. In practice, it sounds like browsers weren’t doing this anyway, and that probably wasn’t the original intent.
You can see the change that is being made to the definition here, as summarized in that issue: https://github.com/w3c/csswg-drafts/commit/7c2108c1764f328e0b60fffed47d3885a3dc7c11?diff=split
Why does the algorithm look for the space to compute the height of the letter 'x'? An explanation in layman terms would be very appreciated.
For the purpose of collecting and calculating font metrics, the U+0020 space is most likely the earliest and most common code point that could contain that information and would make sense to check. Many metrics are being calculated then, like the line height and em unit, not just the ex unit.
Beyond that, CSS ex unit section gives more detail on how that value is determined:
The x-height is so called because it is often equal to the height of the lowercase "x". However, an ex is defined even for fonts that do not contain an "x". The x-height of a font can be found in different ways. Some fonts contain reliable metrics for the x-height. If reliable font metrics are not available, UAs may determine the x-height from the height of a lowercase glyph. One possible heuristic is to look at how far the glyph for the lowercase "o" extends below the baseline, and subtract that value from the top of its bounding box. In the cases where it is impossible or impractical to determine the x-height, a value of 0.5em must be assumed.
I've searched around for an answer to this, but couldn't find any useful information. I'm trying to set the top property of an element in CSS to max(0, 120vh - 271px). I've tried several variations of this:
top: max(0, 120vh - 271px);
top: max(0, (120vh - 271px));
top: max(0, calc(120vh - 271px));
Is there something wrong with my syntax? I keep getting Chrome telling me that this is an invalid property error.
In practice, I'm actually using CSS variables for the numbers. so 120vh is actually var(--height) or something like that. When I use CSS variables, the line just doesn't do anything. It doesn't apply the style, and I don't get any warnings. What am I doing wrong here?
I'm using the newest version of Chrome (83 I believe), so this should be supported.
You need to add a unit to 0 otherwise it's confusing for the browser to handle the comparison between a uniteless value (a <number>) and a value with unit (a <length>) and the top property accept a <length> not a <number>
top: max(0px, 120vh - 271px)
To understand this, you need to follow the specification:
The min() or max() functions contain one or more comma-separated calculations, and represent the smallest (most negative) or largest (most positive) of them, respectively.
Then for calculations:
A calc() function contains a single calculation which is a sequence of values interspersed with operators, and possibly grouped by parentheses (matching the <calc-sum> grammar),
So the content of min()/max() is treated like the one of calc() then from the type checking
A math function can be many possible types, such as <length>, <number>, etc., depending on the calculations it contains, as defined below. It can be used anywhere a value of that type is allowed.
and
Note: Altho there are a few properties in which a bare <number> becomes a <length> at used-value time (specifically, line-height and tab-size), <number>s never become "length-like" in calc(). They always stay as <number>s.
You may get surprised but using top:0 is valid while top:min(0) or top:max(0) is not. To make them valid you need to add the unit.
But you can use opacity: min(0) for example since opacity accept a number as argument.
Worth to note that the same also apply to clamp() since it's equivalent to max(MIN, min(VAL, MAX))
Related: Why doesn't css-calc() work when using 0 inside the equation?
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
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
Can I change the default unit from pixel to mm?
For example I want when move an element left and top to be in mm not in pixel?
There is no 'default unit'. The CSS spec requires that a length (other than zero) that is missing a unit be treated as an error (and thus ignored).
In quirks mode (and you should almost never be using quirks mode, it makes life more difficult), most browsers will perform error recovery and assume you meant pixels (despite the spec forbidding this).
From the standard:
A <quirky-length> is syntactically identical to a <number-token>, and is interpreted as a 'px' length with the same value.
(In other words, Quirks Mode allows all 'px' lengths in the affected properties to be written without a unit, similar to unitless zero lengths.)
If you are working with screen media — avoid physical units. Most systems are not calibrated to calculate the DPI correctly (so when converting from physical units into something a monitor understands (pixels) they get it wrong).
Specifying CSS units is a requirement for non-zero values. Browsers may try to guess what you meant, but it would still be a broken stylesheet according to the standard.
I.e. there is no "default unit" in CSS2, it's just that the browser may try to help you out, although it may as well just ignore your statement that doesn't specify units as an invalid one.
No, you can not change the default unit, but it shouldn't be too much to just put the units there:
#foo {
left: 22mm;
top: 20mm;
}
You should always specify the unit nevertheless, because it is required and browsers might interpret unitless values differently.
As there's no "default unit" and you need to provide the unit when positioning an element, you can just use "mm" instead of "px".
AFAIK if no explicit unit was specified (like 'em' or '%') then "px" is concatenated to the value and there is no way to override this default behavior.
Yes, You can do this indirectly by assigning variable for unit:
--unit: 1mm;
--value: 10;
--variable: calc(var(--unit) * var(--value));
No, that's not possible since different screens might have different sizes while still having the same resolution. Ultimately leading to pixel or relative notations.