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
Styles encapsulation: opt-in inheritance #147
Comments
Hmm, this is interesting. But I don't think the Shadow DOM does quite what you think. Shadow DOM makes a boundary that selectors can't cross, but inheritance can. You can use I'm actually a big proponent of using inheritance judiciously rather than trying to reset every element all the time. I tend to think people are more worried by the idea of inheritance changing values within their components than the reality of doing so. Personally, I think each "outer component" can simply reset the properties it cares about and pass on the ones it doesn't. That way your "descendants" are totally responsive to the properties already set on the page, which makes them much more reusable. I gave a talk on this topic a few months back if you're interested: https://www.youtube.com/watch?v=XR6eM_5pAb0 |
whoa I had no idea that elements in the Shadow DOM inherit from the parent – I thought that SD was fully encapsulated. Anyway the point of this feature is to make inheritance predictable by whitelisting inherited properties rather than blacklisting/resetting the rest. For example
Agreed maybe opt-out leads to a less painful approach, I haven't made up my mind yet :) Thank you for sharing your knowledge and thoughts! Feel free to close the issue if you want. |
@geelen great talk. Inheritance with custom properties is indeed very powerful and would still work with my solution whose sole purpose is to remove side effects. With custom properties you would still need to be explicit eg. |
@geelen correct me if I am wrong but
this doesn't apply if we put styles only in the ShadowDOM which was my original idea https://jsfiddle.net/rvnga5mm <div class="Component">
#shadowRoot
<style>div { font-size: 3em }</style>
<div>Howdy</div>
<content></content> <!-- content in a way is like React's props.children -->
<div class="NestedComponent">
<!-- won't be affected by Component's [non-]inherited props -->
</div>
</div> Resetting everything is a way to get similar level of encapsulation. |
Adding this fyi most of the native elements that use ShadowDOM reset inherited properties - these are UA styles though. |
@giuseppeg no it still applies. It's just that the selector in your rule |
@geelen uhm are you saying that it affects the light DOM or nested components in the ShadowDOM? If the latter, agreed otherwise I am confused. Just to clarify even further, I suggest to reset all of the inherited properties and explicitly set some to .foo {
all: revert;
color: inherit;
font-family: inherit;
} |
Since nobody has asked for this feature in almost half a year it's unlikely we're going to introduce it to the library. We would also break a large amount of existing users with this change, which is not something I'd be particularly comfortable with. I'll close this issue for now, if you still strongly feel this should be part of styled-components one way or another feel free to comment again or open a new issue! |
yea I also changed my mind in the meantime.. that idea was based on one of the early versions of shadow dom which now instead doesn't block inheritance. |
This is a feature request or rather an idea – would love to know your opinion.
Like CSS Modules, CSS-in-JS solutions or even BEM and SUIT CSS,
styled components generates unique class names to avoid name clashing and global disasters caused by the CSS cascade property.
People feel pretty confident when using these tools but ignore the fact that there is another enemy around the corner that is CSS inheritance i.e.
styles applied to a component can affect the subtree and even reach the leaves. Properties like
color
,font-size
,font-family
are stillinherited
.This is good for many reasons but it is an unpredictable side-effect and imho inheritance should be opt-in (instead of opt-out) and predictable. Pete Hunt mentioned it at CSSConf [video] but we were already implementing this idea into SUIT CSS preprocessor and it is now available in v3 [link].
We could reset inherited and non-inherited properties at the root of the component to get styles encapsulation like in ShadowDOM. Descendants can still inherit from the component scope because they only get non-ineherited properties reset – styles won't affect nested components.
The only difference between SUIT and styled components is that in styled components there aren't
descendants
i.e. each component is a single element without nested stuff. Therefore in order to fit components into a specific context we'd need to have a way to tell that a component is part of a widget or something (in a way a descendant of a scoped component) and reset only non-inherited properties instead.API Ideas:
In alternative styles encapsulation could be opt-in
Any of the above solutions would just inject (or remove) the following global class names:
These two rules should be at the top of the stylesheet so that styled components can override single properties.
The text was updated successfully, but these errors were encountered: