Re: [csswg-drafts] [css-values] random() function (#2826)

@tabatkins Thanks again for thinking through this with me. I like the API overall and how the use of custom idents allows us not to _have to_ rely on CSS custom properties for storing random values.

One point I would like to discuss just a bit more is cases where the custom ident is excluded. As it stands nowโ€”AFAICTโ€”a lack of an ident works almost like an ident of its own, just a `null` one, where multiple instances of the same `random()` value without an ident would produce the same value. This works, though I see some desirable situations that this approach might make difficult/impossible, at least without the use of a CSS preprocessor to generate random idents on demand.

One example that does a good job demonstrating this is a confetti burst ๐ŸŽ‰๐Ÿ‘‡๐Ÿผ
```css
.confetti > .confetto {
  animation: 3s ease-out reverse random-offset;
}
@keyframes random {
  from {
    transform: translate(0px, 0px);
  }
  to {
    transform: translate(random(-50px, 50px), random(-50px, 50px));
  }
}
```

<details><summary><b><i>(Click to expand)</i></b> โ€ฆor similarly, using the <code>@property</code> rule, which doesn't appear to make things "easier", though I think it might be necessary for this sort of thing. I could be wrong here. ๐Ÿ‘‡๐Ÿผ</summary>

```css
@property --offset-x {
  syntax: "<length>";
  initial-value: 0px;
  inherits: false;
}
@property --offset-y {
  syntax: "<length>";
  initial-value: 0px;
  inherits: false;
}
.confetti > .confetto {
  translate(var(--offset-x), var(--offset-y));
  animation: 3s ease-out reverse random-offset;
}
@keyframes random {
  from {
    --offset-x: 0px;
    --offset-y: 0px;
  }
  to {
    --offset-x: random(-50px, 50px);
    --offset-y: random(-50px, 50px);
  }
}
```
</details>

In either of these cases, generating a _new_ random value when the ident is omitted allows each of these confetti to burst in a unique random direction and offset. Without this, if they all generate the same random value, the confetti would _not only_ all get the same random value and offset, but the x and y offset would also be identical, meaning that all the confetti would appear as a singular confetto (overtop each other) traveling in some randomized square direction, so even with the random values, this would always produce a 45ยบ direction from an axis.

For the x and y values to be different, that require at least one ident for `x` and one for `y`, which solves the "square" issue, but each confetto would still appear as one, layered over each other. With idents, each would require a unique ident for both x and y, like this:

```html
<div class="confetti">
  <div class="confetto" style="--ident-x: x1; --ident-y: y1"></div>
  <div class="confetto" style="--ident-x: x2; --ident-y: y2"></div>
  <div class="confetto" style="--ident-x: x3; --ident-y: y3"></div>
  <div class="confetto" style="--ident-x: x4; --ident-y: y4"></div>
  <div class="confetto" style="--ident-x: x5; --ident-y: y5"></div>
</div>
```
```css
.confetti > .confetto {
  animation: 3s ease-out reverse random-offset;
  --offset-x: random(var(--ident-x), -50px, 50px);
  --offset-y: random(var(--ident-y), -50px, 50px);
}
@keyframes random {
  from {
    transform: translate(0px, 0px);
  }
  to {
    transform: translate(var(--offset-x), var(--offset-y));
  }
}
```

<details><summary><b><i>(Click to expand)</i></b> <code>@property</code> version of this example ๐Ÿ‘‡๐Ÿผ</summary>

```html
<div class="confetti">
  <div class="confetto" style="--ident-x: x1; --ident-y: y1"></div>
  <div class="confetto" style="--ident-x: x2; --ident-y: y2"></div>
  <div class="confetto" style="--ident-x: x3; --ident-y: y3"></div>
  <div class="confetto" style="--ident-x: x4; --ident-y: y4"></div>
  <div class="confetto" style="--ident-x: x5; --ident-y: y5"></div>
</div>
```
```css
@property --offset-x {
  syntax: "<length>";
  initial-value: 0px;
  inherits: false;
}
@property --offset-y {
  syntax: "<length>";
  initial-value: 0px;
  inherits: false;
}
.confetti > .confetto {
  translate(var(--offset-x), var(--offset-y));
  animation: 3s ease-out reverse random-offset;
  --offset-x-to: random(var(--ident-x), -50px, 50px);
  --offset-y-to: random(var(--ident-y), -50px, 50px);
}
@keyframes random {
  from {
    transform: translate(0px, 0px);
  }
  to {
    transform: translate(var(--offset-x-to), var(--offset-y-to));
  }
}
```
</details>

Is there still room to discuss the possibility of having the default for when an ident is omitted to generate a new random value and only use the same value when an ident is used? I could also see this being useful for 2nd party packages using a `random()` function also used on the site and getting the same value, thereby producing some seemingly non-random results.

Thanks again! Really appreciate you talking through this with me ๐Ÿ™Œ๐Ÿผ

-- 
GitHub Notification of comment by brandonmcconnell
Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/2826#issuecomment-1186549299 using your GitHub account


-- 
Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config

Received on Sunday, 17 July 2022 15:38:23 UTC