diff --git a/css-values/Overview.bs b/css-values/Overview.bs index 5883f6c0e128..2e96b691565f 100644 --- a/css-values/Overview.bs +++ b/css-values/Overview.bs @@ -1583,14 +1583,20 @@ Functional Notations -->

-Mathematical Expressions: ''calc()''

+Mathematical Expressions: ''calc()'', ''min()'', and ''max()'' - The calc() function allows mathematical expressions + The math functions, + calc(), min(), and max(), + allow mathematical expressions with addition (''+''), subtraction (''-''), multiplication (''*''), and division (''/'') to be used as component values. - The ''calc()'' expression represents the result of the mathematical calculation it contains, - using standard operator precedence rules. - It can be used wherever + A ''calc()'' function represents the result of the mathematical calculation it contains, + using standard operator precedence rules; + a ''min()'' or ''max()'' function represents + the smallest (most negative) or largest (most positive), respectively, + comma-separated calculation it contains. + + A [=math function=] can be used wherever <>, <>, <>, @@ -1599,8 +1605,10 @@ Mathematical Expressions: ''calc()'' <>, or <> values are allowed. - Components of a ''calc()'' expression can be literal values or - ''attr()'' or ''calc()'' expressions. + Components of a [=math function=] can be literal values, + other [=math functions=], + or other expressions, such as ''attr()'', + that evaluate to a valid argument type (like <>).
@@ -1664,10 +1672,12 @@ Mathematical Expressions: ''calc()''
 

Syntax

- The syntax of a ''calc()'' function is: + The syntax of a [=math function=] is:
 	<> = calc( <> )
+	<>  = min( <># )
+	<>  = max( <># )
 	<calc-sum> = <> [ [ '+' | '-' ] <> ]*
 	<calc-product> = <> [ '*' <> | '/' <> ]*
 	<calc-value> = <> | <> | <> | ( <> )
@@ -1676,20 +1686,20 @@ Syntax
 	<calc-number-value> = <> | ( <> )
 	
- In addition, white space + In addition, [=whitespace=] is required on both sides of the ''+'' and ''-'' operators. (The ''*'' and ''/'' operaters can be used without white space around them.) - UAs must support ''calc()'' expressions of at least 20 terms, + UAs must support [=math function=] expressions of at least 20 terms, where each NUMBER, DIMENSION, or PERCENTAGE is a term. - If a ''calc()'' expression contains more than the supported number of terms, + If a [=math function=] contains more than the supported number of terms, it must be treated as if it were invalid.

Type Checking

- A math expression has a resolved type, which is one of + A [=math function=] has a resolved type, which is one of <>, <>, <>, @@ -1697,17 +1707,32 @@ Type Checking <>, <>, or <>. - The resolved type must be valid for where the expression is placed; + The resolved type must be valid for where the [=math function=] is placed; otherwise, the expression is invalid. - The resolved type of the expression is determined by the types of the values it contains. - <>s are of type <> or <>. - A <>’s type is given by its unit - (''cm'' is <>, ''deg'' is <>, etc.). - An ''attr()'' expression's type is given by its <> argument. + + The resolved type of a [=math function=] is determined by the values and calculations it contains: + + * <>s are of type <> or <>. + * A <>’s type is given by its unit + (''cm'' is <>, ''deg'' is <>, etc.). + * Functions’ types are defined by their specification + (nested ''calc()'' has its type determined by its own contents, + ''attr()''’s type is determined by its <> argument, + etc). + * Larger calculations’ types are determined by the types of their arguments + and the rules for their operation, + as defined below. + + A ''calc()'' expression's resolved type is the resolved type of the calculation it contains. + The resolved type of a ''min()'' or ''max()'' expression + is the resolved type of any of the calculations it contains. + If a ''min()'' or ''max()'' expression's arguments have different resolved types, + the expression is invalid. Note: Because <>s are always interpreted as <>s or <>s, - "unitless 0" <>s aren't supported in ''calc()''. + "unitless 0" <>s aren't supported in [=math functions=]. That is, ''width: calc(0 + 5px);'' is invalid, + because it's trying to add a <> to a <>, even though both ''width: 0;'' and ''width: 5px;'' are valid. @@ -1778,38 +1803,42 @@ Type Checking (as purely-numeric expressions can be evaluated without any additional information at parse time). - Note: Algebraic simplifications do not affect the validity of the ''calc()'' expression or its resolved type. + Note: Algebraic simplifications do not affect the validity of a [=math function=] or its resolved type. For example, ''calc(5px - 5px + 10s)'' and ''calc(0 * 5px + 10s)'' are both invalid due to the attempt to add a length and a time.

Computed Value

- The computed value of a ''calc()'' expression is the expression + The computed value of a ''calc()'' function is the expression with all components computed. + The computed value of a ''min()'' or ''max()'' function + is the comma-separated list of expressions, + with each expression having all its component computed. Where percentages are not resolved at computed-value time, - they are not resolved in ''calc()'' expressions, + they are not resolved in [=math functions=], e.g. ''calc(100% - 100% + 1em)'' resolves to ''calc(1em + 0%)'', not to ''1em''. If there are special rules for computing percentages in a value (e.g. the height property), - they apply whenever a ''calc()'' expression contains percentages. + they apply whenever a [=math function=] contains percentages.
Note: The serialization rules do not preserve the structure of the computation, so implementations can simplify the expressions further than what is required here when storing the values internally; - in particular, all ''calc()'' expressions can be reduced + in particular, all [=math function=] expressions can be reduced to a sum of a <>, a <>, and some <>s, eliminating all multiplication or division, and combining terms with identical units. At this time, all units can be absolutized to a single unit per type at computed-value time, - so at that point the ''calc()'' expression can be reduced - to just a <>, a <>, and a single absolute <> of the appropriate type. + so at that point the [=math function=] can be reduced + to just a <>, a <>, and a single absolute <> of the appropriate type, + per expression.
@@ -1848,7 +1877,7 @@ Computed Value

Range Checking

- Parse-time range-checking of values is not performed within ''calc()'', + Parse-time range-checking of values is not performed within [=math functions=], and therefore out-of-range values do not cause the declaration to become invalid. However, the used value resulting from an expression must be clamped to the range allowed in the target context. @@ -1876,33 +1905,76 @@ Serialization Issue: This section is still under discussion. - To serialize a ''calc()'' value: +
+ To serialize a ''calc()'' value + + 1. [=Simplify the expression=] inside of it. - 1. Simplify the expression by: + 2. If this simplification process results in only a single value + (one <>, one <>, or one <>), + and the value being serialized is a computed value or later, + serialize it just as that one value, + without the ''calc()'' wrapper. + If this value is outside the allowed range for the context, + it must be clamped to the nearest allowed value. + + 3. Otherwise, + [=serialize the summation=], + prefix the result with "calc(" + and suffix it with ")", + then return it. +
- * Replacing nested ''calc()'' values with parentheses containing their contents - * Resolving all multiplications and divisions - * Combining identical units +
+ To serialize a ''min()'' or ''max()'' value: + + 1. For each comma-separated expression inside of it, + [=simplify the expression=]. + + 2. Let |s| initially be "min(" or "max(", as appropriate. + + 3. [=serialize the summation|Serialize each summation=], + then join them into a single string, + with ", " between each term. + Append the result to |s|. + + 4. Append ")" to |s|, + then return it. +
+ +
+ To simplify an expression: + + 1. Replace any ''calc()'' values with parentheses containing their contents. + 2. Resolve all multiplications and divisions. + 3. Combine identical units. + 4. Recurse into ''min()'' or ''max()'' values. + 5. Return the result. Note: The value-computation process can transform disparate units into identical ones. For example, ''em'' and ''px'' are obviously different at specified-value time, but at computed-value time they're both absolutized to ''px''. - The result must be a summation of unique units. + The result must be a summation of unique units and/or [=math functions=]. (Terms with a value of zero must be preserved in this summation.) +
- 2. If this simplification process results in only a single value - (one <>, one <>, or one <>), - and the value being serialized is a computed value or later, - serialize it just as that one value, - without the ''calc()'' wrapper. - If this value is outside the allowed range for the context, - it must be clamped to the nearest allowed value. - - 3. Otherwise, serialize as a ''calc()'' containing the summation, - with the units ordered ASCII case-insensitive alphabetically, - the number (if present) coming before all units, - and the percentage (if present) coming after all units. +
+ To serialize a summation: + + 1. Sort the terms in the following order: + + 1. The number, if present + 2. The dimensions, ordered by their units ASCII case-insensitive alphabetically + 3. The percentage, if present + 4. The ''min()'' and ''max()'' functions, + in the order they appeared in the original expression. + + 2. Serialize all the terms, + then join them into a single string, + with " + " between each term. + Return the result. +
For example, ''calc(20px + 30px)'' would serialize as ''calc(50px)'' as a specified value,