Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

plugin for random() #601

Closed
3 tasks done
romainmenke opened this issue Sep 1, 2022 · 15 comments
Closed
3 tasks done

plugin for random() #601

romainmenke opened this issue Sep 1, 2022 · 15 comments
Labels
feature request New feature or request

Comments

@romainmenke
Copy link
Member

What would you want to propose?

TODO

Suggested solution

TODO

Additional context

Validations

  • Follow our Code of Conduct
  • Check that there isn't already an issue that request the same feature to avoid creating a duplicate.

Would you like to open a PR for this feature?

  • I'm willing to open a PR
@romainmenke romainmenke added the feature request New feature or request label Sep 1, 2022
@romainmenke romainmenke changed the title random() plugin for random() Sep 1, 2022
@romainmenke
Copy link
Member Author

Closing for now, waiting on the final specification

@romainmenke
Copy link
Member Author

@Antonio-Laguna
Copy link
Member

The issue I have with this is that this would be a random value at generation time vs at consumed time unless we go the JS way

@romainmenke
Copy link
Member Author

It can not even be random at generation time, that would make CSS builds indeterministic.
Each value must be pseudo random from a seed that exists within the CSS source.
Building twice must have the same outcome.

It can work as a fallback, but never as a polyfill.

@romainmenke
Copy link
Member Author

romainmenke commented Jan 25, 2023

The per-element keyword causes the random() function to generate a different value on each element the function is applied to, rather than resolving to a single value per usage in the stylesheet.

This is not something we can do 🤔

.random {
  width: random(per-element, 100px, 500px);
}

Would become :

.random {
  width: 372px;
}

But that is the same for each element.

Maybe counters?
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Counter_Styles/Using_CSS_counters

Edit : I always forget that counter values can not be used in calc

@Antonio-Laguna
Copy link
Member

Antonio-Laguna commented Jan 25, 2023

🤔 true that!

@brandonmcconnell
Copy link

brandonmcconnell commented Jun 14, 2023

@romainmenke re this:

Each value must be pseudo random from a seed that exists within the CSS source.
Building twice must have the same outcome.

My understanding of random() is that it is expected to have a different value for each pageload and that the same value only persists for the current sessions.

Is that not the case? Where in the spec is that, if you know?

This random-caching section from the spec appears to support this:
https://drafts.csswg.org/css-values-5/#random-caching

The "unique value per element or pseudo-element" must have the same lifetime as a JavaScript reference to the element (or to the originating element + sufficient additional info to uniquely identify the pseudo-element). Elements in separate documents (including across refreshes of the same page, which produces distinct documents with distinct elements) ✨ should have distinct unique values ✨. (This is not strictly required, to allow for pseudo-random generation of these values, but uniqueness should be likely enough that authors cannot depend on elements having the same values across documents.)

@romainmenke romainmenke reopened this Jun 14, 2023
@romainmenke
Copy link
Member Author

romainmenke commented Jun 14, 2023

My understanding of random() is that it is expected to have a different value for each pageload and that the same value only persists for the current sessions.

That is correct :)

I was working under the assumption to include this in PostCSS Preset Env.

If we include a non-deterministic plugin there, we would break a lot of things.
Too many people are running build systems that must have a deterministic outcome.

A standalone plugin, not included in PostCSS Preset Env would not have this constraint.


My initial idea was to have a plugin that helps authors with a semi-random fallback value.
The result would still feel random for end users in some cases and it would help CSS authors by not having to provide manual fallback values.


A second idea I had was to use the DOM itself as a source of entropy.

Not every page would have 5th child in a 6th child in a 13th child in ...
But some might.

By creating a bunch of these conditions and assigning different values to attributes you can create semi-random numbers.

Something that would appear random to an end user.

:root:has(:nth-child(...) :nth-child(...) ...) {
  --random-1: 1;
  --random-2: 2;
  --random-3: 3;
}

:root:has(:nth-child(...) :nth-child(...) ...) {
  --random-1: 2;
  --random-2: 3;
  --random-3: 1;
}

:root:has(:nth-child(...) :nth-child(...) ...) {
  --random-1: 3;
  --random-2: 1;
  --random-3: 2;
}

.foo {
  /* really quick maths, likely very broken/incorrect */
  width: clamp(100px, calc(100px + (var(--random-1) * (300px - 100px))), 300px);
  width: random(100px, 300px);
}

@romainmenke
Copy link
Member Author

The technique above could also be done without :has with some tweaks.

@romainmenke
Copy link
Member Author

romainmenke commented Jun 14, 2023

/* just writing numbers, haven't tested any of this */

:nth-child(2) {
  --random-1: 1;
}

:nth-child(2n+1) {
  --random-1: 2;
}

:nth-child(2n+2) {
  --random-1: 3;
}

:nth-child(2n+3) {
  --random-1: 4;
}

:nth-child(3) {
  --random-2: 1;
}

:nth-child(3n+1) {
  --random-2: 2;
}

:nth-child(3n+2) {
  --random-2: 3;
}

:nth-child(3n+3) {
  --random-2: 4;
}

/* ... */

.foo {
  /* really quick maths, likely very broken/incorrect */
  width: clamp(100px, calc(100px + (((var(--random-1) + var(--random-2) + var(--random-3)) / 3) * (300px - 100px))), 300px);
  width: random(100px, 300px);
}

@romainmenke
Copy link
Member Author

https://lea.verou.me/2020/07/the-cicada-principle-revisited-with-css-variables/

@romainmenke
Copy link
Member Author

@brandonmcconnell I am doing a bit of pruning in the issues here and this one hasn't seen activity in the past few weeks.

But feel free to reach out with any questions.

@brandonmcconnell
Copy link

@romainmenke I just assumed you were still working on it. No worries, thanks for the heads up 🙂

@romainmenke
Copy link
Member Author

Ha, no, didn't want to steal your thunder, only wanted to provide some options.

@brandonmcconnell
Copy link

Ah got it. No worries!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature request New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants