-
Notifications
You must be signed in to change notification settings - Fork 141
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
[css-custom-functions] user-defined custom CSS functions #1007
Comments
As a programmer, I slightly prefer the at-rule syntax, which looks similar to different programming languages. It should also be kept in mind to be able to define a worklet for extended functionality. I also like the idea of realizing mixins with that syntax, though I wonder whether functions and mixins should be mixed (pun intended 😄). I mean, whether it should be allowed to let a function return property values or several property declarations. I'd rather expect to have two different syntaxes for that, e.g. an Sebastian |
I think it would be great if there was a way for authors to wire up custom functions JavaScript knows about to CSS using a custom Suppose you have a function like this somewhere in JS: function pickRandom(array = []) {
return array[Math.floor(Math.random() * array.length]
} You would need some way to register this with CSS to be used with a certain name: CSS.registerCustomFunction({
name: '--pick-random',
syntax: '<any>#', // space separated tokens
definition: pickRandom,
events: ['load']
}) And then be able to use it anywhere in a CSS value as :root {
background-color: --pick-random(red green blue);
} Being able to expose existing JavaScript functions to CSS (including all of the colour conversion and animation libs out there) would bring a lot of value because so many of the most useful functions might exist already and be immediately usable from new places. Another exciting possibility is allowing people to integrate some of the styling integrations currently only possible CSS-in-JS to be used from regular CSS stylesheets as well. I think this would be true whether or not there was a way to declaratively define them from CSS syntax (which I also think is fun). As a side note, I am not proposing anything about defining them from CSS but an at-rule seems to make sense for something like that. Just for fun, here's a codepen I made recently exploring defining JS functions in CSS syntax to be used from CSS as custom functions: https://codepen.io/tomhodgins/pen/oNbBYZw I'd love to see anything like this, even browsers parsing and hanging onto a {
--works-inside-in-a-custom-property: --custom();
} Inside the value of a custom property basically everything that's valid CSS parsed and kept, so any a {
width: var(--works-in-any-property-value-that-includes-var-too) --custom();
} It also seems like browsers parse and hang onto custom functions inside property values that include I'm all for anything like any of the above! 😎 |
As I mentioned in the previous issue, #857 is related - unfortunately that linked to 857 in CSS instead of Houdini, sorry if it caused issues - this link should work though. |
Oh that thread looks beautiful! Thanks @bkardell |
Could regular custom property declaration/semantics be extended to take parameters? Something like
|
My proposal: CSS.registerFunction({
name: 'fnName',
call: jsFunction,
arguments: ["<color>", "<url>"]
})
function jsFunction(color, url) {
} body {
background: call("fnName", #000, url("https://imageurl"));
} |
I think for better performance, you'd need something more like the paint worklet, which can operate earlier in the render cycle. Also, passing to / from JavaScript requires you to define types in terms of the CSS OM. Otherwise, you can't do something like animate values, because the type returned from JavaScript doesn't conform to a CSS type. Which is why I'm proposing Value Transform worklets. @oknoorap I think you got quite close, except:
|
Noticed this overlaps with Issue w3c/csswg-drafts#9350. |
@matthew-dean I agree |
I think it would be useful to approach this from both ends. Ideally CSS could provide a declarative syntax for the simpler use-cases, and we could also work on a Houdini syntax for more imperative extensions as needed. |
I think we can simply use --name() like with variables so we don't need call. |
alternatively, since the @function fn-name {
use: "awesomeFunction";
/** alternative
call: "awesomeFunction";
invoke: "awesomeFunction";
syntax: "awesomeFunction";
source: "awesomeFunction"; */
arguments: [<number> | <percentage>]?
}
body {
width: fn-name(10);
} |
Note that the |
I wish there was a way to make re-usable CSS "functions".
Currently, we can't make re-usable logic without unfortunately coupling to HTML markup. See:
As you can tell from those pages, in order to make re-usable expressions ("functions"), we must couple the re-usability to the HTML markup, which is not ideal.
It would be great to be able to create re-usable logic/functions in a way that does not require a CSS author to ever touch any HTML code.
How might an proposal syntax look like, to work around the current limitation?
Perhaps:
^ In that example, the user does not have to worry about "evaluating CSS variables at the level where they are needed" (which requires the CSS author to touch the HTML markup as shown by @Afif13's nicely-written answer in the second SO question).
There's probably a bunch of other ways we could do it.
Here's another idea for sake of spinning up some ideas:
Or, maybe we can create a new special type of block (it may be cleaner):
Maybe functions can also return a rule expression, which could be "mixed" onto a rule (not sure about syntax though):
results in equivalent of
or something.
With
@function
, maybe the return just has to match the context where the function is being used. For example in the previous two examples we saw it used to return a property value, and to return a rule that is mixed in the rule where it is used.Maybe we could also use it at the top level to create top-level rules (not sure about the particular syntax, probably someone with CSS implementation expertise can weigh in):
The text was updated successfully, but these errors were encountered: