- From: Tab Atkins Jr. via GitHub <sysbot+gh@w3.org>
- Date: Fri, 17 Jun 2022 19:46:09 +0000
- To: public-css-archive@w3.org
I believe I sufficiently solved the "how to determine when random() is evaulated and *re*-evaluated" in [my proposal above](https://github.com/w3c/csswg-drafts/issues/2826#issuecomment-455347714) (see the comment preceding that for the explanation). A few nits on your syntaxes: * It appears that in your syntax the only way to make a random real is to explicitly provide a (sufficiently small) interval value, which feels odd. * Dimensions can't have a default interval: `random(1em, 5em)` canonicalizes to some px values (usually 16px and 80px) which would produce a completely different default interval than what the author probably intended; `random(1px, 3em)` or even `random(3px + 10%, 5em / 2)` don't have a common unit to derive an intent from at all. This is a similar problem to [CSS's round() function](https://drafts.csswg.org/css-values/#round-func), which requires you to explicitly give the rounding interval. So by default, if no interval is supplied, it needs to return any value within the range, no precision implied. * I *do* think it's useful to have that interval argument, tho, since it's non-trivial to recreate the correct behavior yourself. The obvious solution of `round(down, random(1em, 10em), .5em)` is non-uniform at the top - in this example it'll never produce the maximum value, and in other examples (like `round(down, random(0px, 100px), 15px)`) the last value will be produced with a different weight then the rest (in this case, `90px` will be produced only 2/3rds as much as any other value). Making it work correctly is pretty non-trivial to do in CSS, as you indicated! * Similarly, `random-item()` as an explicit function (rather than `nth(random-int(...), ...)` is probably nice for usability, since you don't have to correctly indicate the number of items in the list. We should do that. * We've also proposed `nth()` for use with conditional stuff, tho; there, it takes a *semicolon-separated* list, so you can supply entire property values, even if they're comma-separated. Is that necessary here as well? It would make it harder to pass the values as a variable, plus is kinda weird for the probably-common case of small value choices like colors or numbers. You can still always combine `nth()` and `random()` manually, if you want. -------- So, revised proposal based on the above: ``` random(<custom-ident> per-element?, <calc-sum>, <calc-sum>, [by <calc-sum>]? ); random-item(<custom-ident> per-element?, <single-value># ); ``` random() requires all its calc-sum arguments to add to the same type. It canonicalizes its arguments, and when they're fully resolved, gives a random numeric value of the appropriate type that is between the low and high values. If a precision is provided, it selects a value randomly from all values of the form `(low + N * precision)` that are less than or equal to the high value. (Insert corner-cases about low vs high ordering, and precision sign.) This is a [math function](https://drafts.csswg.org/css-values/#math-function), with all that implies. (In particular, it means we don't need to separate out random integers from reals; saying `random(foo, 1, 10, by 1)` will provide integers, and using random() in a place that expects integers will trigger rounding if necessary.) (That said, a `random-int()` might still make sense for simplicity's sake; it would let you omit the precision and get an integer by default. Unsure if ints occur often enough in CSS to be worth privileging like this.) random-item() evaluates to one of its arguments. They can be of any type. `<single-value>` is a not-yet-defined production similar to `<any-value>` that doesn't allow top-level commas. Because we can't tell what the type of the value is, random-list() triggers the same behavior as a var() - property is assumed valid at parse time, and becomes IACVT if substitution ends up giving a bad result. random() caches its results by a tuple of (custom-ident, low, high, precision, element-specific identifier if `per-element`, document-specific identifier). random-item() just caches by (custom-ident, element-specific identifier if `per-element`, document-specific identifier). This means you'll get identical results every time the same function is used, anywhere in any stylesheet, on a single page load. (If `per-element` is specified you'll get different results per element, but the same results on a particular element every time.) (I'm not including the values in the random-item() cache just because it seems harder to precisely describe them, but since they're not parsed beyond comma-splitting, maybe we can just say they're a token stream?) -- GitHub Notification of comment by tabatkins Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/2826#issuecomment-1159181409 using your GitHub account -- Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config
Received on Friday, 17 June 2022 19:46:13 UTC