emotion icon indicating copy to clipboard operation
emotion copied to clipboard

Styles added to shadow DOM not always apply in Safari

Open kalekseev opened this issue 2 years ago • 12 comments

Current behavior:

In shadow DOM safari doesn't apply some rules, it seems like rules that inserted on first render applied but when new components rendered their rules are not applied. The problem happen only in production (speedy mode), in dev when each rule inserted into separate style tag it works as expected.

Probably related https://github.com/emotion-js/emotion/issues/2502

To reproduce:

CRA repro https://github.com/kalekseev/emotion-safari-bug-repro on toggle the div must have green background but it doesn't

kalekseev avatar Oct 15 '21 23:10 kalekseev

I can't reproduce this issue here: https://codesandbox.io/s/blissful-snyder-i5o6s?file=/src/App.js

Andarist avatar Oct 17 '21 16:10 Andarist

I can't reproduce this issue here: https://codesandbox.io/s/blissful-snyder-i5o6s?file=/src/App.js

Hm, I reproduce the problem with that codesnadbox too, videos:

  • ios 15.0 https://user-images.githubusercontent.com/367259/137637303-63621b62-7665-45fa-83ca-a57d13af3d5b.mp4
  • safari 15.0 (15612.1.29.41.4, 15612) https://user-images.githubusercontent.com/367259/137637347-32672ece-992f-418c-a6d0-64dd7e963508.mp4

kalekseev avatar Oct 17 '21 17:10 kalekseev

styled-components version of that sandbox https://codesandbox.io/s/loving-lamarr-eyvpw?file=/src/index.js works as expected for me

kalekseev avatar Oct 17 '21 17:10 kalekseev

Encountered with the same issue in Safari in 15.0 but all works fine in Safari 15.4

andreyantipov avatar Oct 18 '21 07:10 andreyantipov

Encountered with the same issue in Safari in 15.0 but all works fine in Safari 15.4

@andreyantipov I think you meant Safari 14.4

I've tried Safari 15.1 beta 3 and that issues is fixed there.

kalekseev avatar Oct 18 '21 08:10 kalekseev

@kalekseev unfortunately bug is reproducible in Safari "Version 15.0 (16612.1.29.41.4, 16612)" too. Looking for a way for implementing quick & temporary workaround with MutationObserver for force repaint / reflow

andreyantipov avatar Oct 18 '21 09:10 andreyantipov

@kalekseev also tested in release 133 (Safari 15.4, WebKit 16613.1.2.2) developer preview for MacOS BigSur 11.6 (20G165) bug is not reproducible. Looks like this problem only exist in 15.0

andreyantipov avatar Oct 18 '21 09:10 andreyantipov

Hm, I reproduce the problem with that codesnadbox too, videos:

I was testing on a different version on Safari.

styled-components version of that sandbox https://codesandbox.io/s/loving-lamarr-eyvpw?file=/src/index.js works as expected for me

Note that this codesandbox is using the non-speedy mode - which is working just OK with Emotion too (according to your tests). So this is not an apple to apple comparison here. To check if this works with SC you would have to make this codesandbox to use a sheet with useCSSOMInjection: true (you would have to look it up to see how it can be done).


It seems that this issue is a Safari issue and that only a specific version (or versions) are affected by it. I'm afraid that this means that we won't bother with trying to fix it in Emotion itself - especially that we don't know how to do that (apart from turning off the speedy mode in this situation).

I think that turning off the speedy mode on your own for the affected Safari versions is a reasonable solution to this problem.

Andarist avatar Oct 18 '21 09:10 Andarist

@Andarist

Note that this codesandbox is using the non-speedy mode - which is working just OK with Emotion too (according to your tests). So this is not an apple to apple comparison here. To check if this works with SC you would have to make this codesandbox to use a sheet with useCSSOMInjection: true (you would have to look it up to see how it can be done).

There's not such thing as useCSSOMInjection, only disableCSSOMInjection https://styled-components.com/docs/api#stylesheetmanager and it's false by default, I set it explicitly to false and it works too https://codesandbox.io/s/morning-wildflower-kgoti?file=/src/index.js

It seems that this issue is a Safari issue and that only a specific version (or versions) are affected by it. I'm afraid that this means that we won't bother with trying to fix it in Emotion itself - especially that we don't know how to do that (apart from turning off the speedy mode in this situation).

That is reasonable decision, I just want to point out that styled-components manage to work in safari while emotion hits bugs, so it might worth to find out what they do differently. https://github.com/emotion-js/emotion/issues/2502 is another case when emotion hits a bug while styled-components works.

kalekseev avatar Oct 18 '21 10:10 kalekseev

useCSSOMInjection is used internally by StyleSheet: https://github.com/styled-components/styled-components/blob/97c6f70e7de83f6b216bf47245ca1a20bb2df213/packages/styled-components/src/sheet/Sheet.ts#L24 StyleSheetManager "translates" disableCSSOMInjection to that option here: https://github.com/styled-components/styled-components/blob/97c6f70e7de83f6b216bf47245ca1a20bb2df213/packages/styled-components/src/models/StyleSheetManager.tsx#L46-L48 And the default value for this you can (somewhat) check here: https://github.com/styled-components/styled-components/blob/97c6f70e7de83f6b216bf47245ca1a20bb2df213/packages/styled-components/src/constants.ts#L15-L31

Andarist avatar Oct 18 '21 11:10 Andarist

After looking through other issues (ex: https://github.com/emotion-js/emotion/issues/2502#issuecomment-940106585), it seemed clear disabling speedy was the fix-- but I wasn't sure how to turn it off. It's an option you can provide to createCache, code sample below. It's also discussed on the SSR docs page, though that isn't my use case. This solved my app's styling issues in Safari 15. Though everything looks alright, I did have one question: is it safe to disable speedy in production environments?

import React, { useEffect, useState } from 'react';
import createCache from '@emotion/cache';
import type { EmotionCache } from '@emotion/cache';
import { CacheProvider } from '@emotion/react';
import styled from '@emotion/styled';

interface AppProps {
  emotionMount: HTMLDivElement;
}

// "App" gets rendered as the child of a shadow root (not shown below).
export const App = ({ emotionMount }: AppProps) => {
  const [emotionCache] = useState<EmotionCache>(() =>
    createCache({
      key: 'my-unique-id',
      prepend: true,
      container: emotionMount,
      speedy: false,
    }),
  );

  return (
    <CacheProvider value={emotionCache}>
      {...restOfApp}
    </CacheProvider>
  );
};

petermikitsh avatar Oct 29 '21 15:10 petermikitsh

Y'all have already deduced most everything, but to just add a little history:

  • I encountered this same issue in styled components during the ios 15 beta phase https://github.com/styled-components/styled-components/issues/3544
  • Bug was filed against Webkit and fixed, but the fixed version of Webkit didn't make it's way into the Safari version included with 15.0.

So yeah, should be fixed going forward, but disabling the CSS OM optimization is necessary for ios 15.0.

TLadd avatar Jan 31 '22 17:01 TLadd