svelte icon indicating copy to clipboard operation
svelte copied to clipboard

Svelte 5: add $style and CSS modules support (like Vue) to fully obfuscate/isolate class names

Open dm-de opened this issue 1 year ago • 4 comments

Describe the problem

First... Vue has this functionality - I miss in Svelte https://vuejs.org/api/sfc-css-features.html#css-modules https://github.com/vitejs/vite/discussions/7447#discussioncomment-4128874

Code like this in Svelte:

<h1 class:block={true}>Hello</h1>
<style>
    .block { display: block; }
</style>

will generate such CSS: .block.svelte-3zrlxr{display:block}

.block is my own custom class name .svelte-3zrlxr is auto-generated class name for whole component

But this is not enough! This was a "cheap" solution, that have side effects! Today... custom class names (like block) can collide with GLOBAL class names. This means, that custom used classes are simple not isolated!

Describe the proposed solution

Svelte like solution. Example code: (module was added to not break compatibility)

<h1 class={$style.block}>Text</h1>
<style module>
  .block { display: block; }
</style>

or convert (auto obfuscate)

<h1 class:block={true}>Text</h1>
<style module>
  .block { display: block; }
</style>

Both should be possible

Alternatives considered

CSS-modules work today. They obfuscate class names. Vite support CSS modules: https://vitejs.dev/guide/features#css-modules

If i write code like this, it works:

<script>
    import style from './style.module.css'
</script>
<h1 class={style.block}>Text</h1>

It generate this class name for "block": _block_1xra7_1

But now, I need to split component in separate files. I search a way to use

Importance

would make my life easier

dm-de avatar Dec 25 '23 12:12 dm-de

You can already achieve this behaviour by using svelte-preprocess-cssmodules. Not sure if this needs to be added in svelte directly

biowaffeln avatar Jan 16 '24 18:01 biowaffeln

Thank you! I don't know this.

Here is one little problem: svelte-preprocess-cssmodules requires "svelte": "^3.22.3" (updated 1 year ago)

so I get errors:

Could not resolve dependency:
npm ERR! peer svelte@"^3.20.0" from [email protected]
npm ERR! node_modules/svelte-preprocess-cssmodules
npm ERR!   svelte-preprocess-cssmodules@"^2.2.4" from the root project

I used --force to install

Not sure if this needs to be added in svelte directly

I'm not sure either... But css scoping is not perfect at the moment.

svelte-preprocess-cssmodules has bind() and allows following awesome Code:

<script>
  let color = 'red';
</script>

<p class="text">My lorem ipsum text</p>

<style module>
  .text {
    font-size: 18px;
    font-weight: bold;
    color: bind(color);
  }
</style>

dm-de avatar Jan 16 '24 19:01 dm-de

hmm that's odd. You might want to file an issue on the svelte-preprocess-cssmodules repo. I do have some trouble getting it to work in a test project myself... Anyways, I believe this issue is a duplicate of https://github.com/sveltejs/svelte/issues/6972 and should be closed.

biowaffeln avatar Jan 16 '24 20:01 biowaffeln

This would be great considering svelte-preprocess-cssmodules has not been updated in a while

h-a-s-k avatar Feb 08 '24 17:02 h-a-s-k