Skip to content
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

Injection order of tss and regular styles are in the wrong order for a short while #52

Closed
paales opened this issue Jan 7, 2022 · 3 comments

Comments

@paales
Copy link

paales commented Jan 7, 2022

Hi there!

I'm running into an issue where the order of css and tss styles are sorted in the wrong way in the head for a short period of time..

Video of the problem: https://d.pr/v/SXxXJq

You can see it happening from the 15 second mark in the video, you see the tss- below the css- styles for a short while

It seems to be due to a reordering in the header which is happening teporarily:

Screen.Capture.on.2022-01-07.at.10-47-49.mp4

Server loaded styles:
Schermafbeelding 2022-01-07 om 10 49 34

CSS styles get applied below the tss styles:
Schermafbeelding 2022-01-07 om 10 49 45

CSS styles are now moved to the top:
Schermafbeelding 2022-01-07 om 10 49 50

I'm using the following code:

// eslint-disable-next-line @next/next/no-document-import-in-page
import type Document from 'next/document'
import { withEmotionCache } from 'tss-react/nextJs'
import { emotionCache } from './tssReact'

export function documentWithEmotion(Doc: typeof Document) {
  return withEmotionCache({ Document: Doc, getCaches: () => [emotionCache()] })
}
import createCache from '@emotion/cache'
import type { EmotionCache } from '@emotion/cache'
import { CacheProvider } from '@emotion/react'
import { getTssDefaultEmotionCache, TssCacheProvider } from 'tss-react'

let cache: EmotionCache | undefined

/** Creates a single instance of the `@emotion/cache` that is shared between server and client */
export function emotionCache() {
  if (!cache) cache = createCache({ key: 'mui', prepend: true })
  return cache
}

/** Provider that is supposed to be used in your `pages/_app.tsx` */
export function EmotionProvider({ children }: { children: React.ReactNode }) {
  return (
    <CacheProvider value={emotionCache()}>
      <TssCacheProvider value={getTssDefaultEmotionCache()}>{children}</TssCacheProvider>
    </CacheProvider>
  )
}

I've tried without the TssCacheProvider first, but that doesn't seem to be making a difference.

Ideas: After googling a bit we might be able to use this option to make this more stable?
emotion-js/emotion#2037 (comment)

(In general it bothers me a bit that it even recreates styles in the DOM, because that means that the browser must reevaluate the styles, but maybe that goes away if the locations are exactly the same..)

(I promise I'm almost done bothering you with all these issues 😗)

@garronej
Copy link
Owner

garronej commented Jan 7, 2022

Hi,

<TssCacheProvider value={getTssDefaultEmotionCache()}>

This is a no-op.

let cache: EmotionCache | undefined
/** Creates a single instance of the @emotion/cache that is shared between server and client */
export function emotionCache() {
if (!cache) cache = createCache({ key: 'mui', prepend: true })
return cache
}

This is not a correct setup for SSR. A new instance of emotion cache must be created for every render on the server.
Please refer to the documentation.

Beside, do you use cx or something else to merge classe names?

Please create a sandbox if you want me to provide further assistance. With stackblitz you can even create SSR playgrounds.

@paales
Copy link
Author

paales commented Jan 7, 2022

@garronej I've totally misread the example and didn't create a new emotion cache for each server render.. I've now corrected it and it seems to work as expected!

Beside, do you use cx or something else to merge classe names?

I'm still using clsx() to merge multiple classes, didn't understand what the advantage was.

I've read the source code of cx and it seems it overrides any media queries here? So that it more works like inline styles? Or does it do some additional things?

@garronej
Copy link
Owner

garronej commented Jan 7, 2022

@paales

does it do some additional things?

Yes it absolutely do additional things! It ensures styles are overwritten in the correct order!

const useStyles = makeStyles()({
    "blue": {
         "backgroundColor": "blue"
    },
    "red": {
        "backgroundColor": "red"
    }
});

function MyComponent(){

    const { classes, cx } = useStyles();

    return (
        <div className={cx(classes.red, classes.blue)}>Hello World</div>
    );

}

In this example the <div> will have a blue background. But if I use cx(classes.blue, classes.red) the <div> will have a red background.

For what it does relative to media queries see this issue.

Best

@garronej garronej closed this as completed Jan 7, 2022
gitbook-com bot pushed a commit that referenced this issue Mar 2, 2022
gitbook-com bot pushed a commit that referenced this issue Oct 19, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants