-
-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
Add support for styling third-party components #1808
Comments
I find it a bit odd that we can't style imported components. Is this just something that's not been thought of yet? <Component/>
<script>
export default {
components: {
Component: './Component.html'
}
};
</script>
<style>
.component {
color: green;
}
</style> https://svelte.technology/repl?version=2.15.1&gist=353a4f670a3b9e111530bad1aa2d2d5f Maybe it's because I am used to using web components, and if you import a web component you can style using its element name Perhaps a class name or attribute could be reserved for components for a hook that allows you to style them.
Something to that effect. |
I had considered creating a Postcss plugin which converts a <Component/>
<script>
export default {
components: {
Component: './Component.html'
}
};
</script>
<style>
Component { /* would be preprocessed to .Component or something similar */
color: green;
}
</style> |
As I commented on #2888, this general feature is something we want to support, but I don't think that PR is the way we want to go about it. |
@Conduitry I suppose idea with scopes looks very good. I am not sure about binding to ref: here but the idea itself very good. |
Could you elaborate on this? How would that limit you in your desired abilities? The whole aim of passing classes down (as you would in HTML) is to not be required to implement any new syntax. |
Yep, seems it's a problem. I heard about it many times. In addition to the solution from initial comment, perhaps we can use Special selectors syntax from Svelte 2: <div>
<ThirdPartyComponent bind:this={comp}/>
</div>
<script>
let comp;
</script>
<style>
div {
color: green;
}
ref:comp .third-party-owned-div {
color: red;
}
</style> |
Interesting, just spotted this in the source code. https://github.com/sveltejs/svelte/blob/master/src/compiler/parse/index.ts#L211 |
it's also should help with sapper cases, multiple style tags will be the best implementation IMHO. |
@Conduitry What exactly is |
What's pending clarification is how we want this feature to work. Treating a prop called |
My personal input is: Make things work intuitively, out of the box. What are concrete examples where #2888 would not be the desired behavior? I'm probably not thinking in Svelte enough here. |
@nikku I personally don't see the value in passing some magic class attribute to components, when a reference to the svelte namespaced |
@antony I mean is that not the point of the |
It's not a |
right okay, magic prop. |
Closing this issue in absolute favour of sveltejs/rfcs#13 |
I think closing this in favor of sveltejs/rfcs#13 doesn't giving a sense. |
@gamelaster sorry to hear that you think it's crap. We are of course open to better ideas which aren't crap. If you have the need to make mass changes to the style of child components from their parents, then you perhaps need to reconsider your architecture, or just use a global stylesheet for these styles, as you would in any other JS app. |
Hi @antony , firstly, I'm very sorry if term I used To the topic, I don't exactly have any ideas how to improve it (since I don't know how exactly svelte handles all this under the hood), but I think there should be a better way than using global CSS file. <script>import Component from './component.svelte'</script>
<body>
<Component>
<p>some text</p>
</Component>
</body>
<style>
.component:hover p {
color: red;
}
</style> component.svelte: <div class="component">
<slot></slot>
</div> Any ideas how I can solve this? |
Yes, there probably should be a better way, but none of the comments in this issue (or any issue) provide it, which is why it has been closed. I'm afraid I can't provide support in a github issue. However if you come to the discord you will find a number of people who have solved this in a variety of different ways. |
I asked on the Discord, thanks! Although, maybe I have an idea. Every component will able to have "root" element (by default first element or selected by parameter?). This element will be able to be modified by CSS from parent. Example: <script>import Component from './component.svelte'</script>
<body>
<Component>
<p>some text</p>
</Component>
</body>
<style>
Component:hover p {
color: red;
}
</style> component.svelte <div bind:root class="component">
<slot></slot>
</div> Well, it's just idea, and as I said, I'm not sure how Svelte is processing all this under-the-hood, so even I'm not sure if realization is possible. |
@antony The problem with using systems like Discord is the solutions are not searchable or readily accessible. Keeping productive discussions regarding missing features should be done in Github. After it has been solved, then it doesn't matter what other channels are used. I just started playing with Svelte, and I find it much more enjoyable and more efficient than React and Angular. However, there seems to be some obvious missing features (which is expected with such a new language). I think those features discussions should be kept in Github with the original issue. And if there IS as solution, it should be posted here before closing the issue. Keep up the GREAT work! I'm predicting Svelte will surpass most of the other popular libraries due to being more frictionless and feeling more like natural fit for developing interfaces in Javascript. Svelte has me very excited about the future of Javascript! EDIT: BTW, what is the solution for targeting Components with CSS styles that feels natural? i.e.:
|
Hi @davidmroth Thank you for your thoughts, and I'm glad you are enjoying Svelte. To put the reasons for my closing this issue and trying to discourage discussion into context: The issue of styling child components has been discussed literally, and I mean quite literally, to death in a large number of different github issues. The discussions are endless, unproductive, and as demonstrated here, the alleged searchability of github issues does not prevent yet another ticket being opened for the same issue, the same endless discussion, and the same ill-considered 3 line "solutions" being brought up time and time again. I hope you can understand therefore why my actions may appear obtuse. We are tired by these discussions, we are fatigued by these discussions and frustrated by these discussions to the point where I may be the only maintainer who even participates in them any more. And I don't intend to keep it up. So therefore this issue is closed, not up for further discussion here, and the way to continue or propose as solution to this issue boils down two two options. Either:
Discussions leading up to either event should be precipitated by a realtime discussion on discord, where we will all benefit from its ephemeral nature. Hope this clarifies my actions for you, and please accept my apologies for being so blunt despite you being new here. I just want to provide the background for my firm decisions in this process. |
Hi @antony , thank you for writing the context of whole situation, it helped also me to understand the reasons and background of this issue. I was thinking about this, so if I will have some spare time soon, I will read everything I will find about this and will try to implement my idea to Svelte, and then turn it into RFC. Thanks for your time and work on Svelte. |
The problem
One of the things I come across repeatedly whilst working with Svelte is that scoped styles, whilst absolutely excellent, also prevent efficient style overrides of child components whose css you don't control.
For instance, if I have some code like this:
This renders html similar to the following:
Which in itself is fine, however, I am unable then to style the
third-party-owned-div
from my parent component, since all styles are prefixed - my CSS ends up like:There are some solutions, but they have their own issues
:global(.third-party-owned-div) *
This works, but attempts to style every instance of .third-party-owned-div in the application. This global style conflicts with other components (especially if they don't have unique names), unless you prefix it with a local element selector, however, you can't use :global in the middle of a selector either, so you need to wrap the entire remainder of the selector inside :global.
Effectively, you can, in a rather awkward way, address a deep child of a third-party component as follows:
However, when using a preprocessor such as scss, the above is no longer usable, since global modifiers are only allowed at the beginning or end of a selector:
include a separate global css file for styling the component:
This also works, but circumvents the scoped style system, and takes component styles away from their component, which breaks the whole component model.
Proposed solutions:
I've been thinking around a few solutions for this, and I think the cleanest one which fits the Svelte model the best is to allow a section of styles to be scoped to a different scope, which can be specified with a 'scope' attribute in the style tag, which specifies a ref, or similar. For example:
The text was updated successfully, but these errors were encountered: