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

JS in CSS #51

Closed
wants to merge 4 commits into from
Closed

JS in CSS #51

wants to merge 4 commits into from

Conversation

bluwy
Copy link
Member

@bluwy bluwy commented May 24, 2021

@antony
Copy link
Member

antony commented May 25, 2021

I'd be tempted to say that the backtick character doesn't appear in CSS so this might be a better syntax than js.

Overall I think this is a nice idea, but I feel like it might be hellish given all the css preprocessors people are using.

@bluwy
Copy link
Member Author

bluwy commented May 26, 2021

@antony Interesting, through some digging I found that backticks were also once used by Less for inline javascript, so there was an existing convention! (Though deprecated by Less)

I've updated by my repo to test out multiple preprocessors and the backtick syntax. Result:

  1. js() works for all preprocessors. The vscode extensions I tried for syntax highlighting doesn't nag much too.
  2. Backtick syntax failed for all preprocessors and even Svelte's css parser. The vscode extensions nag a bit too.

Looks like backticks doesn't get enough love from the preprocessor ecosystem.

Update: js() works in less too, but it needs to be escaped if they're quotes within the parentheses, e.g. width: ~"js(num + 'px')";.

@pngwn
Copy link
Member

pngwn commented May 26, 2021

What does this give us that css variables don't?

I don't think the 'difficult to learn' criticism of css variables is valid. It is a standard and is no less esoteric then this proposal. Aligning to existing web standards where possible has always been a design goal.

This would add a huge amount of complexity to the css handling and would be a significant feature.

@bluwy
Copy link
Member Author

bluwy commented May 26, 2021

@pngwn Perhaps the biggest benefit this gives that CSS variables don't is that CSS variables can be scoped by Svelte, similar to how classes work. Besides that, it's purely subjective whether the syntactic sugar is actually worth it.

I'm currently comparing this to style properties as it plays at the same "syntactic sugar" feature level, that both can be done with pure CSS variables manually.

Regarding web standards, I chose js() as it's the least web-breaking feature and plays as the same area in calc() and var(), so most preprocessors would've took into account of this function syntax. There's also a CSS Houdini draft that further expands on custom CSS functions, so there could be a future where this would be a standard syntax.

But if the goal is to stick proper laid-out web standards, then I'm fine if we wait longer for the CSS ecosystem to progress, but at the same time it'll be interesting for Svelte to take the first leap.

@pngwn
Copy link
Member

pngwn commented May 26, 2021

The issue there is that we don't want endless sugar, we already have the css properties thing we don't want to keep adding different kinds of sugar to do the same thing.

We have a pretty clear preference to use the simplest, most standardised approach where possible.

@bluwy
Copy link
Member Author

bluwy commented May 26, 2021

I agree that having too much sugar isn't great, but however I don't think the style properties feature is doing the same thing as this, as highlighted in the technical background section.

Furthermore, in a bigger picture of JS in CSS, I'd like to see CSS variables as the implementation detail only. So would the consensus be that JS in CSS would not be implemented/considered in the future?

Nonetheless, I'm hoping to have a final answer for this as it's a topic that comes around from time to time.

@TehShrike
Copy link
Member

I've gotten by in a lot of cases by just putting the dynamic CSS on the elements e.g. <div style="width: {num}px">Hello</div>

@catielanier
Copy link

I've gotten by in a lot of cases by just putting the dynamic CSS on the elements e.g. <div style="width: {num}px">Hello</div>

While that's fine, it's not necessarily the most dry if you're going to be repeating the same style in multiple places, especially you have more than one rule that might need some dynamic rules in the same element. Would be nice to frame this off a class and do the dynamic stuff in CSS with that class and apply it all with one class definition.

@bluwy
Copy link
Member Author

bluwy commented Jul 17, 2021

Just realized Vue had this feature for a while now in this RFC and have recently be merged into Vue 3.2. It's using v-bind() instead of js(), with great positive feedback there.

@Theo-Steiner
Copy link

Theo-Steiner commented Aug 10, 2021

This came up in the discord today because someone shared a link of vue's implementation of this and people (at least I) got very excited about the idea of having this in svelte as well.
I was wondering rather than introducing a new syntax of js() to svelte's css, why not allow for this syntactically by using the already existing var() with curly braces like in the html-like part of svelte?

<script>
let color = 'hotpink'
</script>
<h1>Pretty in pink</h1>
<style>
h1 {
  background-color: var({color});
}
</style>

if this desugars to something like this

<script>
let color = 'hotpink'
</script>
<h1 style="--svelte-hash-h1: {color};">Pretty in pink</h1>
<style>
h1 {
  background-color: var(--svelte-hash-h1);
}
</style>

the var({ javascript }) syntax would be very intuitive

@bluwy
Copy link
Member Author

bluwy commented Aug 10, 2021

@Theo-Steiner The issue with that syntax, or any other curly braces syntax, is that they don't work well with IDE extensions. I've tested them in VSCode with this repo for postcss, sass, and even normal css, they all currently report parsing errors, which the Svelte vscode extension can't handle (?) as the syntax highlighting are all done by external vscode extensions.

Using js() would be the least destructive way, similar to v-bind().

@Mlocik97
Copy link

Mlocik97 commented Aug 31, 2021

with #42 I don't think, we will need this RFC at all, and I think, this will add more complexity and unexpected behaviours and other disadvantages than advantages. CSS can be dynamic only in values, that are already covered by CSS variables, so I don't see any reason to have this. But I actually like idea of #51 (comment)

@bluwy
Copy link
Member Author

bluwy commented Sep 2, 2021

@Mlocik97 I guess so, looks like #42 had some discussion related to this feature too. Though I don't think it completely overlaps with this usecase-wise (e.g. #51 (comment)) and feature-wise (e.g. hashed css vars). But I'd agree if that RFC got merged, it would be really weird to have this merged as well since we would have too many ways of doing similar things.

But I actually like idea of #51 (comment)

As explained in the comment above, unless we embrace breaking every tooling out there, it won't be a viable option. {} is already reserved in css and I don't think we should bend it.

@Mlocik97
Copy link

Mlocik97 commented Sep 2, 2021

 {} is already reserved in css and I don't think we should bend it.

I don't think this is problem at all. And it's not really reserved.

@bluwy
Copy link
Member Author

bluwy commented Sep 2, 2021

I've tried that before and it is a problem. If you insist, you can try implementing that variant based on https://github.com/bluwy/svelte-js-in-css then.

@bluwy
Copy link
Member Author

bluwy commented Sep 27, 2021

Closing this as half of the votes are not in favour of this feature.

@bluwy bluwy closed this Sep 27, 2021
@windyclory
Copy link

@bluwy
Good job, I liked it. I like this syntax more:

width: {width}px

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

Successfully merging this pull request may close these issues.

8 participants