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
Scoping CSS keyframes in emulated view encapsulation #42608
base: main
Are you sure you want to change the base?
Conversation
2b1e6fa
to
45cd603
Compare
051d2ec
to
988116d
Compare
I like this idea!
In general I think it would provide a positive benefit to the emulated encapsulation mode.
Because of the change to the keyframes name, I think we would have to land this in a major release, since these names could be referenced in JS code - for example in an animation event handler.
We can wait for this timeframe, IMO, since the workaround is quite straightforward - even if identifying the problem may not be!
For other reviewers, I checked through the Angular animations code, which also makes use of |
988116d
to
8dda4a5
Compare
@petebacondarwin all done as you suggested, thanks a lot The only remaining thing are the quoted keyframes,I am waiting to hear from you on those |
e54c6a4
to
a99a2e0
Compare
…gular#42608) Ensure that keyframes rules, defined within components with emulated view encapsulation, are scoped to avoid collisions with keyframes in other components. This is achieved by renaming these keyframes to add a prefix that makes them unique across the application. In order to enable the handling of keyframes names defined as strings the previous strategy of replacing quoted css content with `%QUOTED%` (introduced in commit 7f689a2) has been removed and in its place now only specific characters inside quotes are being replaced with placeholder text (those are `;`, `:` and `,`, more can be added in the future if the need arises). Closes angular#33885 BREAKING CHANGE: Keyframes names are now prefixed with the component's "scope name". For example, the following keyframes rule in a component definition, whose "scope name" is host-my-cmp: @Keyframes foo { ... } will become: @Keyframes host-my-cmp_foo { ... } Any TypeScript/JavaScript code which relied on the names of keyframes rules will no longer match. The recommended solutions in this case are to either: - change the component's view encapsulation to the `None` or `ShadowDom` - define keyframes rules in global stylesheets (e.g styles.css) - define keyframes rules programmatically in code. PR Close angular#42608
…tion (angular#42608)" (angular#45466) This reverts commit f03e313. PR Close angular#45466
A status update: this caused one test inside google to fail, which was depending on the keyframe leaking across encapsulation boundaries. The team proposed a fix using |
The broken g3 test was fixed as per b/230486028. This can now be merged. |
This PR was merged into the repository by commit 4d6a1d6. |
…tion (angular#42608)" This reverts commit 4d6a1d6.
This caused a bit of a meltdown in g3. I got paged and had to roll it back. Unclear why the TGP didn't catch all the issues -- I will follow up on what happened, but unfortunately I think we're likely to miss the v14 RC. :/ |
So looking back at this, it seems that we broke code that was not tested as part of the TGP (i.e. Guitar tests). Additionally, it was not test-only breakage; it was real pages that are used in production. Nominally we don't support rolling back for non-TGP tests, but I got enough messages from GCP folks that in practice the rollback was inevitable. I suggested considering Unfortunately, this has probably missed 14, which closes on Wednesday. I still think this is a really valuable change, but we probably need a flag. (Maybe a new I'm sorry about this @dario-piotrowicz, we could not have foreseen the additional failures. :( |
5423f14
@dylhunn I am the one sorry for causing all these issues (I hope you didn't get in trouble because of me!!! If the flag is the only option I am totally fine with it, but I believe it still needs to be in the |
Ok, thanks for the clarification, we will need to discuss further the exact strategy. And no worries, it happens sometimes! |
Keyframes are not scoped for
Emulated
view encapsulated component, practically making them global and causing css leakageSince keyframes are not hierarchical I don't believe this issue can be solved without modifying the keyframes names, so the only thing possible I believe is to actually rename the keyframes using the component's scope selector,
The way I did it is by scanning the css twice, in the first scan I modified/scoped the keyframes names in the way mentioned above and in the second I updated animation rules using such keyframes
I understand that this is changing the actual names of the keyframes so it may not be what we actually want here, but I figured that opening a PR and starting a discussion would not hurt
PR Checklist
Please check if your PR fulfills the following requirements:
PR Type
What is the current behavior?
Issue Number: #33885
Currently keyframes are not scoped so, if I create two different keyframe animations in two different components but with the same name, those will clash and only one of them will be applied to both components
You can see it in this example I created: demo code
What happens is that I have two different components each with a keyframes called

box-animation
which colors the component's background, as you can see the application does not behave as expected:What is the new behavior?
Keyframes are scoped so that they include the component's scope selector like so:

and this allows the keyframes to remain isolated:

Does this PR introduce a breaking change?
(at least I don't think so)
Other information
As I mentioned this will cause all the keyframes names in components with the
Emulated
view encapsulation to be modified, this is definitely not too nice/elegant but I think it's the only way to scope the keyframes and I believe that it is still better to leave them global as they are now (as that produces unwanted css leakage + it is inconsistent with what happens withShadowDom
)