Comments (12)
Thanks – I did wonder about an approach like that or CSS modules (which vue-loader supports).
Personally I think there's too much friction. You can't use element selectors and attribute selectors etc, which means that any element that needs a style has to have a class
attribute, which can quickly turn your markup pretty gross. And while it can be useful to skip the cascading part (notwithstanding that it's already not that hard to do in CSS), a) sometimes you want cascading, and b) those approaches don't actually mean you no longer have to think about cascading (much less inheritance) because there's only one CSSOM and you don't know what else is on the page.
And it means you have to chuck out a lot of accumulated knowledge. A lot of developers I know would be unamused to learn they had to learn the quirks of a new leaky abstraction over something they're already reasonably productive with.
So for me, I view those sorts of approaches as a too-clever solution to an artificial problem ("our component templates are written in JavaScript now, therefore we need to put our CSS there too"). I think a lot of the biggest complaints about CSS (such as knowing which selectors you can delete, which is impossible unless you consider the CSS in the context of your markup) can be solved if you have a well-defined component structure and a dollop of static analysis.
from svelte.
Late input not so much about the feature in response to some related points raised.
I agree with @camwest, it's not just tokens like colors that are useful to share, though it's true components replace a lot of things previously shared through CSS frameworks.
Maybe I'm being too simplistic, but in my projects:
- shared CSS and "project-wide" values like spacing, widths, heights, grid systems etc are placed in a global CSS file
- component specific values are placed inside the component
I don't understand why I would define a css class inside a component if this class will be shared with other components. - @paulocoghi
It's good enough for most use cases right now, for sure! But there are a few things worth considering.
If your component's rendering relies on something present in a global scope outside, rather than something explicitly passed in/imported, it's not just an academic problem. There are practical effects; for example, to test the component "in isolation" actually means including the global. Your test global and production global can drift and you have no way to lock down the version of the global class name "interface" used in your component. So your tests can pass, but the component renders broken in production.
Having a separate global stylesheet used by components works with anything that relies on JavaScript assistance with scoping so that interior component styles don't leak to the outside (inside-out). However, Shadow DOM will also provide outside-in style encapsulation, to fix that problem where code outside your component can break your component. This means with Shadow DOM those global class names will no longer work inside the component.
My view is that JS tools/UI frameworks doing CSS scoping is filling in for a missing feature in the web platform. AFAIK there's no reason to think that approach will remain useful enough to justify the maintenance cost once a "native" solution has sufficient support. While I doubt that's now or even next year, IMO it's not too early to begin thinking about approaches that will work now and also endure under Shadow DOM.
from svelte.
This is implemented, in basic form, though it doesn't do any of the advanced stuff listed above (except for using a unique template-based hash).
Long-term it would probably make sense to use PostCSS and minify CSS by default, along with the other optimisations mentioned above. With Svelte it doesn't make sense to propagate the scoping attributes across component boundaries, so we should probably warn if any components exist outside top-level elements.
Since I'm not above stealing ideas, I had a look at https://vue-loader.vuejs.org/en/features/scoped-css.html. Turns out that scoping element selectors can entail a performance hit, for whatever reason. Should perhaps warn about that. Also, Vue has a nice mechanism for extracting CSS from a component graph and putting into a separate file for production, which is neat.
Will leave this open with an 'enhancement' label, since there's still stuff to do.
from svelte.
I haven't really run across this particular method of styling before, but to me it makes a lot of sense for things like ractive and svelte: http://mxstbr.blog/2016/11/inline-styles-vs-css-in-js
It gets around scoping altogether by packaging styles up into generated class names (probably based on a hash of the content?) and then attaching those classes to the styled elements. It kinda kicks the whole cascading part of CSS, which felt wrong at first glance, but after a bit of fond reminiscing about debugging components that where broken by accidental cascades, well, you know...
That's probably not a universal fit, but it seemed like something worth mentioning here in case you haven't come across it before either.
from svelte.
As usual, you're waaay ahead of me 😀
from svelte.
I thought about similar problem with CSS loader and came up with a proposal.
Basically I think it's optimal to let developers repeat themselves with CSS and compiler optimize resulted CSS. IMO Other than color variables there is no benefit of sharing CSS code.
from svelte.
@mohsen1 I disagree. Most design systems share a lot of properties like spacing, widths, heights, grid systems etc. You definitely need to share a lot of CSS values between components in a large application.
Take a look at http://tachyons.io/docs/ for an example of other cross cutting concerns than just colors.
from svelte.
Maybe I'm being too simplistic, but in my projects:
- shared CSS and "project-wide" values like spacing, widths, heights, grid systems etc are placed in a global CSS file
- component specific values are placed inside the component
I don't understand why I would define a css class inside a component if this class will be shared with other components.
from svelte.
Imagine scoped styles together with styles encapsulation 🎉 💥 ✨ 😄
from svelte.
@Rich-Harris fwiw you can easily do attribute and element selectors with css modules two ways:
/** Global attr selector */
:global([my-attr="something"]) {...}
/** Scoped attr selector */
.my-class [my-attr="something"] {...}
I think it'd be awesome to support css modules :).
from svelte.
This should probably be closed now, scoped CSS has been supported for ages
from svelte.
@morewry Wow! Thank you for the explanation!
from svelte.
Related Issues (20)
- Svelte 4/5: Children/slot rerenders DOM when moved HOT 4
- Svelte 5: `{null}` is rendered in an edge case
- Svelte 5: $state declared with var in *.svelte.js broken HOT 2
- Svelte 5: `$bindable()` type is unknown HOT 3
- Properties are not reactive when using `mount`and `$state` props. HOT 6
- Runes mode: cannot send data from child to parent HOT 2
- [runes] Add the ability to get a list of dependencies
- Disallow prop interpolation + other stuff without quotes? HOT 8
- don't appear the result HOT 3
- Hydration regression between 224 and 225 HOT 9
- Support Composability on Runes HOT 13
- Svelte 5: binding to universal reactivity objects HOT 3
- Custom root folder destroys hmr css update (svelte + vite + ubuntu) HOT 2
- Error on invalid tag names
- webcomponents regression after 221 HOT 1
- Svelte 5: `$state.link` various bugs HOT 5
- Shadowed variable breaks `{#await}` block HOT 3
- Svelte 5: An empty string in `@html` causes a warning during hydration. HOT 1
- Introduce `$state.from` rune HOT 8
- `<script module lang="ts">` followed by `<script lang="ts">` is a syntax error HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from svelte.